mirror of
https://git.rwth-aachen.de/acs/public/villas/web-backend-go/
synced 2025-03-30 00:00:12 +01:00
150 lines
5.5 KiB
Go
150 lines
5.5 KiB
Go
/** Database package, roles.
|
|
*
|
|
* @author Sonja Happ <sonja.happ@eonerc.rwth-aachen.de>
|
|
* @copyright 2014-2019, Institute for Automation of Complex Power Systems, EONERC
|
|
* @license GNU General Public License (version 3)
|
|
*
|
|
* VILLASweb-backend-go
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*********************************************************************************/
|
|
package database
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// The types ModelName and CRUD exist in order to have const variables
|
|
// that will be used by every model's package. That way we avoid
|
|
// hardcoding the same names all over and spelling mistakes that will
|
|
// lead IsActionAllowed to fail. We do not typedef the different roles
|
|
// because they will be read as strings from the context.
|
|
|
|
type ModelName string
|
|
|
|
const ModelUser = ModelName("user")
|
|
const ModelUsers = ModelName("users")
|
|
const ModelScenario = ModelName("scenario")
|
|
const ModelInfrastructureComponent = ModelName("ic")
|
|
const ModelInfrastructureComponentAction = ModelName("icaction")
|
|
const ModelDashboard = ModelName("dashboard")
|
|
const ModelWidget = ModelName("widget")
|
|
const ModelComponentConfiguration = ModelName("component-configuration")
|
|
const ModelSignal = ModelName("signal")
|
|
const ModelFile = ModelName("file")
|
|
const ModelResult = ModelName("result")
|
|
|
|
type CRUD string
|
|
|
|
const Create = CRUD("create")
|
|
const Read = CRUD("read")
|
|
const Update = CRUD("update")
|
|
const Delete = CRUD("delete")
|
|
|
|
// Type Permission maps a CRUD operation to true or false
|
|
type Permission map[CRUD]bool
|
|
|
|
// Type ModelActions maps a model name to a map of Permission for every model
|
|
type ModelActions map[ModelName]Permission
|
|
|
|
// Type RoleActions maps a role to a map of ModelActions for every role
|
|
type RoleActions map[string]ModelActions
|
|
|
|
// Predefined CRUD operations permissions to be used in Roles
|
|
var crud = Permission{Create: true, Read: true, Update: true, Delete: true}
|
|
var _ru_ = Permission{Create: false, Read: true, Update: true, Delete: false}
|
|
var __u_ = Permission{Create: false, Read: false, Update: true, Delete: false}
|
|
var _r__ = Permission{Create: false, Read: true, Update: false, Delete: false}
|
|
var none = Permission{Create: false, Read: false, Update: false, Delete: false}
|
|
|
|
// Roles is used as a look up variable to determine if a certain user is
|
|
// allowed to do a certain action on a given model based on his role
|
|
var Roles = RoleActions{
|
|
"Admin": {
|
|
ModelUser: crud,
|
|
ModelUsers: crud,
|
|
ModelScenario: crud,
|
|
ModelComponentConfiguration: crud,
|
|
ModelInfrastructureComponent: crud,
|
|
ModelInfrastructureComponentAction: crud,
|
|
ModelWidget: crud,
|
|
ModelDashboard: crud,
|
|
ModelSignal: crud,
|
|
ModelFile: crud,
|
|
ModelResult: crud,
|
|
},
|
|
"User": {
|
|
ModelUser: _ru_,
|
|
ModelUsers: none,
|
|
ModelScenario: crud,
|
|
ModelComponentConfiguration: crud,
|
|
ModelInfrastructureComponent: _r__,
|
|
ModelInfrastructureComponentAction: _ru_,
|
|
ModelWidget: crud,
|
|
ModelDashboard: crud,
|
|
ModelSignal: crud,
|
|
ModelFile: crud,
|
|
ModelResult: crud,
|
|
},
|
|
"Guest": {
|
|
ModelScenario: _r__,
|
|
ModelComponentConfiguration: _r__,
|
|
ModelDashboard: _r__,
|
|
ModelWidget: _r__,
|
|
ModelInfrastructureComponent: _r__,
|
|
ModelInfrastructureComponentAction: _r__,
|
|
ModelUser: _ru_,
|
|
ModelUsers: none,
|
|
ModelSignal: _r__,
|
|
ModelFile: _r__,
|
|
ModelResult: none,
|
|
},
|
|
"Download": {
|
|
ModelScenario: none,
|
|
ModelComponentConfiguration: none,
|
|
ModelDashboard: none,
|
|
ModelWidget: none,
|
|
ModelInfrastructureComponent: none,
|
|
ModelInfrastructureComponentAction: none,
|
|
ModelUser: none,
|
|
ModelUsers: none,
|
|
ModelSignal: none,
|
|
ModelFile: _r__,
|
|
ModelResult: none,
|
|
},
|
|
}
|
|
|
|
func ValidateRole(c *gin.Context, model ModelName, action CRUD) error {
|
|
// Extracts and validates the role which is saved in the context for
|
|
// executing a specific CRUD operation on a specific model. In case
|
|
// of invalid role return an error.
|
|
|
|
// Get user's role from context
|
|
role, exists := c.Get(UserRoleCtx)
|
|
if !exists {
|
|
return fmt.Errorf("Request does not contain user's role")
|
|
}
|
|
|
|
// Check if the role can execute the action on the model
|
|
if !Roles[role.(string)][model][action] {
|
|
return fmt.Errorf("Action not allowed for role %v", role)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// elements added to context about a user
|
|
const UserIDCtx = "user_id"
|
|
const UserRoleCtx = "user_role"
|