diff --git a/controller/northbound/server/auth.go b/controller/northbound/server/auth.go index 6d4610aaca98668b2e8653702ef9e22e4199c1ac..764ddb3ca9277b174c310ff5bcd73dedaa671749 100644 --- a/controller/northbound/server/auth.go +++ b/controller/northbound/server/auth.go @@ -54,6 +54,17 @@ func (s Auth) Login(ctx context.Context, request *apb.LoginRequest) (*apb.LoginR } //TODO: add session handling here, update user with token + userToUpdate, err := userc.Get(store.Query{Name: user.UserName}) + if err != nil { + return nil, err + } + + userToUpdate.SetToken(token) + + err = userc.Update(userToUpdate) + if err != nil { + return nil, err + } return &apb.LoginResponse{ Timestamp: time.Now().UnixNano(), @@ -217,16 +228,14 @@ func (s Auth) DeleteUsers(ctx context.Context, request *apb.DeleteUsersRequest) } func (s Auth) isValidUser(user rbac.User) (bool, error) { - storedUsers, err := userc.GetAll() + storedUser, err := userc.Get(store.Query{Name: user.Name()}) if err != nil { return false, err } - for _, u := range storedUsers { - if u.Name() == user.Name() { - if u.GetPassword() == user.GetPassword() { - return true, nil - } + if storedUser.Name() == user.Name() { + if storedUser.GetPassword() == user.GetPassword() { + return true, nil } } diff --git a/controller/rbac/databaseRoleStore.go b/controller/rbac/databaseRoleStore.go index 9634c9b3fd39fe2bdd91fb59a848a4bb130ba3bd..c4e7a27478335e6563e55572d03796d730217e12 100644 --- a/controller/rbac/databaseRoleStore.go +++ b/controller/rbac/databaseRoleStore.go @@ -68,10 +68,10 @@ func (s *DatabaseRoleStore) Get(query store.Query) (rbac.Role, error) { collection := db.Collection(s.roleStoreName) if query.ID != uuid.Nil { - log.Debugf("Role-Search-ID: %+v\n", query.ID.String()) + log.Debugf("Role-Search-ID: %+v", query.ID.String()) result = collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: query.ID.String()}}) } else { - log.Debugf("Role-Search-Name: %+v\n", query.Name) + log.Debugf("Role-Search-Name: %+v", query.Name) result = collection.FindOne(ctx, bson.D{primitive.E{Key: "rolename", Value: query.Name}}) } @@ -145,7 +145,7 @@ func (s *DatabaseRoleStore) Update(roleToUpdate rbac.Role) error { err := client.Database(database.DatabaseName). Collection(s.roleStoreName). FindOneAndUpdate( - ctx, bson.M{"id": roleToUpdate.ID}, update, &opt). + ctx, bson.M{"_id": roleToUpdate.ID}, update, &opt). Decode(&updatedRole) if err != nil { log.Printf("Could not update Role: %v", err) diff --git a/controller/rbac/databaseUserStore.go b/controller/rbac/databaseUserStore.go index 47c958979517044ccc2336199e778945459e4294..e58b7f1015298f1545b69c2d30daf19423c742b5 100644 --- a/controller/rbac/databaseUserStore.go +++ b/controller/rbac/databaseUserStore.go @@ -58,7 +58,7 @@ func (s *DatabaseUserStore) Delete(userToDelete rbac.User) error { // User does not exist an error is returned. func (s *DatabaseUserStore) Get(query store.Query) (rbac.User, error) { var result *mongo.SingleResult - var user User + var loadedUser LoadedUser client, ctx, cancel := database.GetMongoConnection() defer cancel() @@ -68,10 +68,10 @@ func (s *DatabaseUserStore) Get(query store.Query) (rbac.User, error) { collection := db.Collection(s.userStoreName) if query.ID != uuid.Nil { - log.Debugf("User-Search-ID: %+v\n", query.ID.String()) + log.Debugf("User-Search-ID: %+v", query.ID.String()) result = collection.FindOne(ctx, bson.D{primitive.E{Key: "_id", Value: query.ID.String()}}) } else { - log.Debugf("User-Search-Name: %+v\n", query.Name) + log.Debugf("User-Search-Name: %+v", query.Name) result = collection.FindOne(ctx, bson.D{primitive.E{Key: "username", Value: query.Name}}) } @@ -79,19 +79,19 @@ func (s *DatabaseUserStore) Get(query store.Query) (rbac.User, error) { return nil, errors.ErrCouldNotFind{StoreName: s.userStoreName} } - err := result.Decode(&user) + err := result.Decode(&loadedUser) if err != nil { log.Printf("Failed marshalling %v", err) return nil, errors.ErrCouldNotMarshall{StoreName: s.userStoreName} } - return &user, nil + return s.createUserFromStore(loadedUser), nil } // GetAll returns all Users func (s *DatabaseUserStore) GetAll() ([]rbac.User, error) { - var users []User + var loadedUsers []LoadedUser var usersToReturn []rbac.User client, ctx, cancel := database.GetMongoConnection() @@ -106,18 +106,16 @@ func (s *DatabaseUserStore) GetAll() ([]rbac.User, error) { } defer cursor.Close(ctx) - err = cursor.All(ctx, &users) + err = cursor.All(ctx, &loadedUsers) if err != nil { log.Printf("Failed marshalling %v", err) return nil, errors.ErrCouldNotMarshall{StoreName: s.userStoreName} } - //TODO: remove loop, should not be needed - // currently used for problem with wrong return type - for _, u := range users { - usersToReturn = append(usersToReturn, &User{UserID: u.UserID, UserName: u.UserName, - Roles: u.Roles, Password: u.Password, Token: u.Token}) + for _, loadedUser := range loadedUsers { + user := s.createUserFromStore(loadedUser) + usersToReturn = append(usersToReturn, user) } return usersToReturn, nil @@ -125,15 +123,13 @@ func (s *DatabaseUserStore) GetAll() ([]rbac.User, error) { // Update updates the User. func (s *DatabaseUserStore) Update(userToUpdate rbac.User) error { - var updatedUser rbac.User + var updatedLoadedUser LoadedUser client, ctx, cancel := database.GetMongoConnection() defer cancel() defer client.Disconnect(ctx) - update := bson.M{ - "$set": userToUpdate, - } + update := bson.D{primitive.E{Key: "$set", Value: userToUpdate}} upsert := false after := options.After @@ -145,8 +141,8 @@ func (s *DatabaseUserStore) Update(userToUpdate rbac.User) error { err := client.Database(database.DatabaseName). Collection(s.userStoreName). FindOneAndUpdate( - ctx, bson.M{"_id": userToUpdate.ID}, update, &opt). - Decode(&updatedUser) + ctx, bson.M{"_id": userToUpdate.ID().String()}, update, &opt). + Decode(&updatedLoadedUser) if err != nil { log.Printf("Could not update User: %v", err) @@ -155,3 +151,7 @@ func (s *DatabaseUserStore) Update(userToUpdate rbac.User) error { return nil } + +func (s *DatabaseUserStore) createUserFromStore(loadedUser LoadedUser) rbac.User { + return NewUser(loadedUser.ID(), loadedUser.UserName, loadedUser.Roles, loadedUser.Password, loadedUser.Token) +} diff --git a/controller/rbac/user.go b/controller/rbac/user.go index 79ac458b8edd9a352eb8bcfaa2bad1deeea85d69..ce3e71f12680382b33d5a6283258a0d56d27d259 100644 --- a/controller/rbac/user.go +++ b/controller/rbac/user.go @@ -1,6 +1,8 @@ package rbac import ( + "encoding/json" + "code.fbi.h-da.de/danet/gosdn/controller/interfaces/rbac" "github.com/google/uuid" "go.mongodb.org/mongo-driver/bson" @@ -8,8 +10,8 @@ import ( // User represents the data of a user for access control and is stored in a storage. type User struct { - UserID uuid.UUID `json:"id,omitempty"` - UserName string `json:"name,omitempty"` + UserID uuid.UUID `json:"_id,omitempty"` + UserName string `json:"username,omitempty"` Roles map[string]string `json:"roles,omitempty"` Password string `json:"password,omitempty"` Token string `json:"token,omitempty"` @@ -70,11 +72,28 @@ func (u *User) SetToken(token string) { u.Token = token } +// MarshalJSON implements the MarshalJSON interface to store a user as JSON +func (u *User) MarshalJSON() ([]byte, error) { + return json.Marshal(&struct { + UserID uuid.UUID `json:"_id,omitempty"` + UserName string `json:"username,omitempty"` + Roles map[string]string `json:"roles,omitempty"` + Password string `json:"password,omitempty"` + Token string `json:"token,omitempty"` + }{ + UserID: u.ID(), + UserName: u.Name(), + Roles: u.Roles, + Password: u.Password, + Token: u.Token, + }) +} + // MarshallBSON implments the MarshalBSON interface to store a user as BSON func (u *User) MarshalBSON() ([]byte, error) { return bson.Marshal(&struct { UserID string `bson:"_id,omitempty"` - UserName string `bson:"name,omitempty"` + UserName string `bson:"username,omitempty"` Roles map[string]string `bson:"roles,omitempty"` Password string `bson:"password,omitempty"` Token string `bson:"token,omitempty"` diff --git a/controller/rbac/userStore.go b/controller/rbac/userStore.go index 15681113940ff2c53a44d4cb52014dd70474671c..7c128c327f27997e646906579b148be9d74b95cf 100644 --- a/controller/rbac/userStore.go +++ b/controller/rbac/userStore.go @@ -17,13 +17,14 @@ type UserStore struct { //LoadedUser represents a User that was loaded type LoadedUser struct { - UserID string `json:"id,omitempty" bson:"_id,omitempty"` - UserName string `json:"name,omitempty"` + UserID string `json:"_id,omitempty" bson:"_id,omitempty"` + UserName string `json:"username,omitempty"` Roles map[string]string `json:"roles,omitempty"` Password string `json:"password,omitempty"` Token string `json:"token,omitempty"` } +// ID returns the ID of the loaded user func (lu LoadedUser) ID() uuid.UUID { return uuid.MustParse(lu.UserID) }