Skip to content
Snippets Groups Projects
Commit 103916c3 authored by Neil-Jocelyn Schark's avatar Neil-Jocelyn Schark Committed by Neil-Jocelyn Schark
Browse files

add multiple tokens without changing featureset

parent cd7e0421
No related branches found
No related tags found
1 merge request!977Resolve "Improve token usage for users"
......@@ -76,14 +76,15 @@ func createTestUsers() error {
testUserPWD := createHashedAndSaltedPassword("user", salt)
testRandPWD := createHashedAndSaltedPassword("aurelius", salt)
wrongTokens := []string{"wrong token"}
users := []rbacImpl.User{
{UserID: uuid.MustParse(adminID), UserName: "testAdmin", Roles: adminRoleMap, Password: testAdminPWD},
{UserID: uuid.MustParse(userID), UserName: "testUser", Roles: userRoleMap, Password: testUserPWD},
{UserID: uuid.New(), UserName: "testRandom", Roles: randomRoleMap, Password: testRandPWD, Token: "wrong token"},
{UserID: uuid.New(), UserName: "testRandom", Roles: randomRoleMap, Password: testRandPWD, Tokens: wrongTokens},
}
for _, u := range users {
err := userService.Add(rbacImpl.NewUser(u.ID(), u.Name(), u.Roles, u.Password, "", salt, conflict.Metadata{ResourceVersion: 0}))
err := userService.Add(rbacImpl.NewUser(u.ID(), u.Name(), u.Roles, u.Password, wrongTokens, salt, conflict.Metadata{ResourceVersion: 0}))
if err != nil {
return err
}
......@@ -146,7 +147,7 @@ func createTestUserToken(userName string, validTokenRequired bool) (string, erro
if err != nil {
return token, err
}
user.SetToken(token)
user.AddToken(token)
err = userService.Update(user)
if err != nil {
......
......@@ -430,7 +430,7 @@ func ensureDefaultUserExists() error {
hashedPassword := base64.RawStdEncoding.EncodeToString(argon2.IDKey([]byte(usedPassword), []byte(salt), 1, 64*1024, 4, 32))
err = c.userService.Add(rbacImpl.NewUser(uuid.New(), defaultUserName, map[string]string{config.BasePndUUID.String(): "admin"}, string(hashedPassword), "", salt, conflict.Metadata{ResourceVersion: 0}))
err = c.userService.Add(rbacImpl.NewUser(uuid.New(), defaultUserName, map[string]string{config.BasePndUUID.String(): "admin"}, string(hashedPassword), []string{}, salt, conflict.Metadata{ResourceVersion: 0}))
if err != nil {
return err
}
......
......@@ -12,8 +12,10 @@ type User interface {
Name() string
GetRoles() map[string]string
GetPassword() string
GetToken() string
SetToken(string)
GetTokens() []string
SetTokens([]string)
AddToken(string)
RemoveToken(string) error
GetSalt() string
GetMetadata() conflict.Metadata
}
......@@ -24,7 +26,7 @@ type LoadedUser struct {
UserName string `json:"username"`
Roles map[string]string `json:"roles,omitempty"`
Password string `json:"password"`
Token string `json:"token,omitempty"`
Tokens []string `json:"tokens,omitempty"`
Salt string `json:"salt" bson:"salt"`
Metadata conflict.Metadata `json:"metadata" bson:"metadata"`
}
......@@ -92,7 +92,7 @@ func (s AuthServer) Login(ctx context.Context, request *apb.LoginRequest) (*apb.
return nil, err
}
userToUpdate.SetToken(token)
userToUpdate.AddToken(token)
err = s.userService.Update(userToUpdate)
if err != nil {
......@@ -155,7 +155,7 @@ func (s AuthServer) isCorrectPassword(storedPassword, salt, loginPassword string
}
// handleLogout checks if the provided user name matches with the one associated with token and
// replaces the stored token of the user with an empty string.
// removed the token from all tokens of the user
func (s AuthServer) handleLogout(ctx context.Context, userName string) error {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
......@@ -179,7 +179,17 @@ func (s AuthServer) handleLogout(ctx context.Context, userName string) error {
return err
}
if token != storedUser.GetToken() {
storedTokens := storedUser.GetTokens()
foundToken := false
for _, storedToken := range storedTokens {
if storedToken == token {
storedUser.RemoveToken(token)
foundToken = true
break
}
}
if !foundToken {
return status.Errorf(codes.Aborted, "missing match of token provied for user")
}
......@@ -187,7 +197,7 @@ func (s AuthServer) handleLogout(ctx context.Context, userName string) error {
UserName: storedUser.Name(),
Roles: storedUser.GetRoles(),
Password: storedUser.GetPassword(),
Token: " ",
Tokens: storedUser.GetTokens(),
Salt: storedUser.GetSalt(),
Metadata: storedUser.GetMetadata(),
})
......
......@@ -97,7 +97,17 @@ func (auth *AuthInterceptor) authorize(ctx context.Context, method string) error
return err
}
if user.GetToken() != token {
storedTokens := user.GetTokens()
foundToken := false
for _, storedToken := range storedTokens {
if storedToken == token {
foundToken = true
break
}
}
if !foundToken {
return status.Errorf(codes.PermissionDenied, "invalid token")
}
......
......@@ -98,14 +98,15 @@ func createTestUsers(userService rbacInterfaces.UserService) error {
testUserPWD := createHashedAndSaltedPassword("user", salt)
testRandPWD := createHashedAndSaltedPassword("aurelius", salt)
wrongTokens := []string{"Wrong token"}
users := []rbac.User{
{UserID: uuid.MustParse(adminID), UserName: "testAdmin", Roles: adminRoleMap, Password: testAdminPWD},
{UserID: uuid.MustParse(userID), UserName: "testUser", Roles: userRoleMap, Password: testUserPWD},
{UserID: uuid.New(), UserName: "testRandom", Roles: randomRoleMap, Password: testRandPWD, Token: "wrong token"},
{UserID: uuid.New(), UserName: "testRandom", Roles: randomRoleMap, Password: testRandPWD, Tokens: wrongTokens},
}
wrongTokens = []string{}
for _, u := range users {
err := userService.Add(rbac.NewUser(u.ID(), u.Name(), u.Roles, u.Password, "", salt, conflict.Metadata{ResourceVersion: 0}))
err := userService.Add(rbac.NewUser(u.ID(), u.Name(), u.Roles, u.Password, wrongTokens, salt, conflict.Metadata{ResourceVersion: 0}))
if err != nil {
return err
}
......@@ -176,6 +177,7 @@ func patchLogger(t *testing.T) {
// be attached to the provided user. Else the user won't have the token and can not be authorized.
func createTestUserToken(userName string, validTokenRequired bool, userService rbacInterfaces.UserService, jwt *rbac.JWTManager) (string, error) {
token, err := jwt.GenerateToken(rbac.User{UserName: userName})
tokens := []string{token}
if err != nil {
return token, err
}
......@@ -185,7 +187,7 @@ func createTestUserToken(userName string, validTokenRequired bool, userService r
if err != nil {
return token, err
}
user.SetToken(token)
user.SetTokens(tokens)
err = userService.Update(user)
if err != nil {
......
......@@ -97,7 +97,7 @@ func (u UserServer) CreateUsers(ctx context.Context, request *apb.CreateUsersReq
userID = uuid.New()
}
user := rbac.NewUser(userID, user.Name, roles, string(hashedPassword), user.Token, salt, conflict.Metadata{ResourceVersion: 0})
user := rbac.NewUser(userID, user.Name, roles, string(hashedPassword), []string{}, salt, conflict.Metadata{ResourceVersion: 0})
err = u.userService.Add(user)
if err != nil {
log.Error(err)
......@@ -204,7 +204,7 @@ func (u UserServer) UpdateUsers(ctx context.Context, request *apb.UpdateUsersReq
hashedPassword := base64.RawStdEncoding.EncodeToString(argon2.IDKey([]byte(user.Password), []byte(storedUser.GetSalt()), 1, 64*1024, 4, 32))
userToUpdate := rbac.NewUser(uid, user.Name, user.Roles, string(hashedPassword), user.Token, storedUser.GetSalt(), conflict.Metadata{
userToUpdate := rbac.NewUser(uid, user.Name, user.Roles, string(hashedPassword), []string{}, storedUser.GetSalt(), conflict.Metadata{
ResourceVersion: int(user.Metadata.ResourceVersion)})
usr, _ := userToUpdate.(*rbac.User)
......
......@@ -138,7 +138,7 @@ func (s *UserService) createUserFromStore(loadedUser rbac.LoadedUser) rbac.User
loadedUser.UserName,
loadedUser.Roles,
loadedUser.Password,
loadedUser.Token,
loadedUser.Tokens,
loadedUser.Salt,
loadedUser.Metadata,
)
......
......@@ -2,6 +2,7 @@ package rbac
import (
"encoding/json"
"errors"
"code.fbi.h-da.de/danet/gosdn/controller/conflict"
"code.fbi.h-da.de/danet/gosdn/controller/interfaces/rbac"
......@@ -16,7 +17,7 @@ type User struct {
UserName string `json:"username"`
Roles map[string]string `json:"roles,omitempty"`
Password string `json:"password"`
Token string `json:"token,omitempty"`
Tokens []string `json:"token,omitempty"`
Salt string `json:"salt"`
}
......@@ -25,7 +26,7 @@ func NewUser(id uuid.UUID,
name string,
roles map[string]string,
pw string,
token string,
tokens []string,
salt string,
metadata conflict.Metadata,
) rbac.User {
......@@ -34,7 +35,7 @@ func NewUser(id uuid.UUID,
UserName: name,
Roles: roles,
Password: pw,
Token: token,
Tokens: tokens,
Salt: salt,
Metadata: metadata,
}
......@@ -66,8 +67,8 @@ func (u *User) GetRoles() map[string]string {
}
// GetToken returns the token of the user.
func (u *User) GetToken() string {
return u.Token
func (u *User) GetTokens() []string {
return u.Tokens
}
// SetName sets the name of the user.
......@@ -76,8 +77,25 @@ func (u *User) SetName(name string) {
}
// SetToken sets the token of the user.
func (u *User) SetToken(token string) {
u.Token = token
func (u *User) SetTokens(tokens []string) {
u.Tokens = tokens
}
// AddToken adds a token to the user.
func (u *User) AddToken(token string) {
u.Tokens = append(u.Tokens, token)
}
// RemoveToken removes a token from the user.
func (u *User) RemoveToken(inputToken string) error {
for i, token := range u.Tokens {
if token == inputToken {
u.Tokens = append(u.Tokens[:i], u.Tokens[i+1:]...)
return nil
}
}
err := errors.New("token not found")
return err
}
// GetSalt returns the salt of the user.
......@@ -92,7 +110,7 @@ func (u *User) MarshalJSON() ([]byte, error) {
UserName string `json:"username"`
Roles map[string]string `json:"roles,omitempty"`
Password string `json:"password"`
Token string `json:"token,omitempty"`
Tokens []string `json:"tokens,omitempty"`
Salt string `json:"salt"`
Metadata conflict.Metadata `json:"metadata"`
}{
......@@ -100,7 +118,7 @@ func (u *User) MarshalJSON() ([]byte, error) {
UserName: u.Name(),
Roles: u.Roles,
Password: u.Password,
Token: u.Token,
Tokens: u.Tokens,
Salt: u.Salt,
Metadata: u.Metadata,
})
......@@ -113,7 +131,7 @@ func (u *User) MarshalBSON() ([]byte, error) {
UserName string `bson:"username"`
Roles map[string]string `bson:"roles,omitempty"`
Password string `bson:"password"`
Token string `bson:"token,omitempty"`
Tokens []string `bson:"tokens,omitempty"`
Salt string `bson:"salt"`
Metadata conflict.Metadata `bson:"metadata"`
}{
......@@ -121,7 +139,7 @@ func (u *User) MarshalBSON() ([]byte, error) {
UserName: u.Name(),
Roles: u.Roles,
Password: u.Password,
Token: u.Token,
Tokens: u.Tokens,
Salt: u.Salt,
Metadata: u.Metadata,
})
......
......@@ -20,7 +20,8 @@ func TestFileSystemUserStore_Add(t *testing.T) {
}
var idtest uuid.UUID
var role map[string]string
testingUser := NewUser(idtest, "testUser", role, "xyz", "svsvsfbdwbwbev", "svswvasfbw", conflict.Metadata{})
tokens := []string{"svsvsfbdwbwbev"}
testingUser := NewUser(idtest, "testUser", role, "xyz", tokens, "svswvasfbw", conflict.Metadata{})
tests := []struct {
name string
args args
......@@ -51,7 +52,8 @@ func TestFileSystemUserStore_Delete(t *testing.T) {
}
var idtest uuid.UUID
var role map[string]string
testingUser := NewUser(idtest, "", role, "xyz", "svsvsfbdwbwbev", "svswvasfbw", conflict.Metadata{})
tokens := []string{"svsvsfbdwbwbev"}
testingUser := NewUser(idtest, "", role, "xyz", tokens, "svswvasfbw", conflict.Metadata{})
tests := []struct {
name string
args args
......@@ -84,7 +86,8 @@ func TestFileSystemUserStore_Get(t *testing.T) {
}
var idtest uuid.UUID
var role map[string]string
testingUser := NewUser(idtest, "", role, "xyz", "svsvsfbdwbwbev", "svswvasfbw", conflict.Metadata{})
tokens := []string{"svsvsfbdwbwbev"}
testingUser := NewUser(idtest, "", role, "xyz", tokens, "svswvasfbw", conflict.Metadata{})
tests := []struct {
name string
args args
......@@ -96,7 +99,7 @@ func TestFileSystemUserStore_Get(t *testing.T) {
args{
store.Query{ID: idtest, Name: "test"},
},
rbac.LoadedUser{ID: idtest.String(), UserName: "", Roles: role, Password: "xyz", Token: "svsvsfbdwbwbev", Salt: "svswvasfbw"},
rbac.LoadedUser{ID: idtest.String(), UserName: "", Roles: role, Password: "xyz", Tokens: tokens, Salt: "svswvasfbw"},
false,
},
}
......@@ -123,9 +126,10 @@ func TestFileSystemUserStore_GetAll(t *testing.T) {
var idtest uuid.UUID
var role map[string]string
testingUser1 := NewUser(idtest, "", role, "xyz", "svsvsfbdwbwbevasf", "svswvasfbwasv", conflict.Metadata{})
testingUser2 := NewUser(idtest, "", role, "abc", "svsvsfbdwbwbevsav", "svswvasfbwadf", conflict.Metadata{})
testingUser3 := NewUser(idtest, "", role, "lmn", "svsvsfbdwbwbevscv", "svswvasfbwasd", conflict.Metadata{})
tokens := []string{"svsvsfbdwbwbev"}
testingUser1 := NewUser(idtest, "", role, "xyz", tokens, "svswvasfbwasv", conflict.Metadata{})
testingUser2 := NewUser(idtest, "", role, "abc", tokens, "svswvasfbwadf", conflict.Metadata{})
testingUser3 := NewUser(idtest, "", role, "lmn", tokens, "svswvasfbwasd", conflict.Metadata{})
tests := []struct {
name string
want []rbac.LoadedUser
......@@ -133,7 +137,7 @@ func TestFileSystemUserStore_GetAll(t *testing.T) {
}{
{
"testUser",
[]rbac.LoadedUser{{ID: idtest.String(), UserName: "", Roles: role, Password: "xyz", Token: "svsvsfbdwbwbevasf", Salt: "svswvasfbwasv"}, {ID: idtest.String(), UserName: "", Roles: role, Password: "abc", Token: "svsvsfbdwbwbevsav", Salt: "svswvasfbwadf"}, {ID: idtest.String(), UserName: "", Roles: role, Password: "lmn", Token: "svsvsfbdwbwbevscv", Salt: "svswvasfbwasd"}},
[]rbac.LoadedUser{{ID: idtest.String(), UserName: "", Roles: role, Password: "xyz", Tokens: tokens, Salt: "svswvasfbwasv"}, {ID: idtest.String(), UserName: "", Roles: role, Password: "abc", Tokens: tokens, Salt: "svswvasfbwadf"}, {ID: idtest.String(), UserName: "", Roles: role, Password: "lmn", Tokens: tokens, Salt: "svswvasfbwasd"}},
false,
},
}
......@@ -175,7 +179,8 @@ func TestFileSystemUserStore_Update(t *testing.T) {
}
var idtest uuid.UUID
var role map[string]string
testingUser := NewUser(idtest, "", role, "xyz", "svsvsfbdwbwbev", "svswvasfbw", conflict.Metadata{})
tokens := []string{"svsvsfbdwbwbev"}
testingUser := NewUser(idtest, "", role, "xyz", tokens, "svswvasfbw", conflict.Metadata{})
tests := []struct {
name string
args args
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment