Newer
Older
Fabian Seidl
committed
package rbac
import (
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/rbac"
"code.fbi.h-da.de/danet/gosdn/controller/nucleus/database"
"code.fbi.h-da.de/danet/gosdn/controller/nucleus/errors"
"code.fbi.h-da.de/danet/gosdn/controller/store"
"github.com/google/uuid"
log "github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// DatabaseRoleStore is used to store roles in database
type DatabaseRoleStore struct {
roleStoreName string
}
Fabian Seidl
committed
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
func (s *DatabaseRoleStore) Add(roleToAdd rbac.Role) error {
client, ctx, cancel := database.GetMongoConnection()
defer cancel()
defer client.Disconnect(ctx)
_, err := client.Database(database.DatabaseName).
Collection(s.roleStoreName).
InsertOne(ctx, roleToAdd)
if err != nil {
if mongo.IsDuplicateKeyError(err) {
return nil
}
return errors.ErrCouldNotCreate{StoreName: s.roleStoreName}
}
return nil
}
// Delete deletes a Role.
func (s *DatabaseRoleStore) Delete(roleToDelete rbac.Role) error {
client, ctx, cancel := database.GetMongoConnection()
defer cancel()
defer client.Disconnect(ctx)
_, err := client.Database(database.DatabaseName).
Collection(s.roleStoreName).
DeleteOne(ctx, bson.D{primitive.E{Key: "_id", Value: roleToDelete.ID().String()}})
if err != nil {
return errors.ErrCouldNotFind{StoreName: s.roleStoreName}
}
return nil
}
// Get takes a Roles's UUID or name and returns the Role. If the requested
// Role does not exist an error is returned.
func (s *DatabaseRoleStore) Get(query store.Query) (rbac.Role, error) {
var result *mongo.SingleResult
Fabian Seidl
committed
client, ctx, cancel := database.GetMongoConnection()
defer cancel()
defer client.Disconnect(ctx)
db := client.Database(database.DatabaseName)
collection := db.Collection(s.roleStoreName)
if query.ID != uuid.Nil {
log.Debugf("Role-Search-ID: %+v", query.ID.String())
Fabian Seidl
committed
result = collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: query.ID.String()}})
} else {
log.Debugf("Role-Search-Name: %+v", query.Name)
Fabian Seidl
committed
result = collection.FindOne(ctx, bson.D{primitive.E{Key: "rolename", Value: query.Name}})
}
if result == nil {
return nil, nil
}
Fabian Seidl
committed
if err != nil {
log.Printf("Failed marshalling %v", err)
return nil, errors.ErrCouldNotMarshall{StoreName: s.roleStoreName}
}
return s.createRoleFromStore(loadedRole), nil
Fabian Seidl
committed
}
// GetAll returns all Roles.
func (s *DatabaseRoleStore) GetAll() ([]rbac.Role, error) {
Fabian Seidl
committed
var rolesToReturn []rbac.Role
client, ctx, cancel := database.GetMongoConnection()
defer cancel()
defer client.Disconnect(ctx)
db := client.Database(database.DatabaseName)
collection := db.Collection(s.roleStoreName)
cursor, err := collection.Find(ctx, bson.D{})
if err != nil {
return nil, err
}
defer cursor.Close(ctx)
Fabian Seidl
committed
if err != nil {
log.Printf("Failed marshalling %v", err)
return nil, errors.ErrCouldNotMarshall{StoreName: s.roleStoreName}
}
//TODO: remove loop, should not be needed
// currently used for problem with wrong return type
for _, loadedRole := range loadedRoles {
role := s.createRoleFromStore(loadedRole)
rolesToReturn = append(rolesToReturn, role)
Fabian Seidl
committed
}
return rolesToReturn, nil
}
// Update updates the role
func (s *DatabaseRoleStore) Update(roleToUpdate rbac.Role) error {
Fabian Seidl
committed
client, ctx, cancel := database.GetMongoConnection()
defer cancel()
defer client.Disconnect(ctx)
update := bson.D{primitive.E{Key: "$set", Value: roleToUpdate}}
Fabian Seidl
committed
upsert := false
after := options.After
opt := options.FindOneAndUpdateOptions{
Upsert: &upsert,
ReturnDocument: &after,
}
err := client.Database(database.DatabaseName).
Collection(s.roleStoreName).
FindOneAndUpdate(
ctx, bson.M{"_id": roleToUpdate.ID().String()}, update, &opt).
Decode(&updatedLoadedRole)
Fabian Seidl
committed
if err != nil {
log.Printf("Could not update Role: %v", err)
return errors.ErrCouldNotUpdate{StoreName: s.roleStoreName}
}
return nil
}
func (s *DatabaseRoleStore) createRoleFromStore(loadedRole LoadedRole) rbac.Role {
return NewRole(loadedRole.ID(), loadedRole.RoleName, loadedRole.Description, loadedRole.Permissions)
}