move validation into account manager + func for get requests

This commit is contained in:
Pascal Fischer 2023-03-30 13:58:44 +02:00
parent ecc4f8a10d
commit 5c1acdbf2f
6 changed files with 322 additions and 106 deletions

View File

@ -67,8 +67,10 @@ type AccountManager interface {
GetNetworkMap(peerID string) (*NetworkMap, error) GetNetworkMap(peerID string) (*NetworkMap, error)
GetPeerNetwork(peerID string) (*Network, error) GetPeerNetwork(peerID string) (*Network, error)
AddPeer(setupKey, userID string, peer *Peer) (*Peer, *NetworkMap, error) AddPeer(setupKey, userID string, peer *Peer) (*Peer, *NetworkMap, error)
AddPATToUser(accountID string, userID string, pat *PersonalAccessToken) error CreatePAT(accountID string, executingUserID string, targetUserId string, tokenName string, expiresIn int) (*PersonalAccessTokenGenerated, error)
DeletePAT(accountID string, userID string, tokenID string) error DeletePAT(accountID string, executingUserID string, targetUserId string, tokenID string) error
GetPAT(accountID string, executingUserID string, targetUserId string, tokenID string) (*PersonalAccessToken, error)
GetAllPATs(accountID string, executingUserID string, targetUserId string) ([]*PersonalAccessToken, error)
UpdatePeerSSHKey(peerID string, sshKey string) error UpdatePeerSSHKey(peerID string, sshKey string) error
GetUsersFromAccount(accountID, userID string) ([]*UserInfo, error) GetUsersFromAccount(accountID, userID string) ([]*UserInfo, error)
GetGroup(accountId, groupID string) (*Group, error) GetGroup(accountId, groupID string) (*Group, error)

View File

@ -46,17 +46,19 @@ func (h *PATHandler) GetAllTokens(w http.ResponseWriter, r *http.Request) {
util.WriteError(status.Errorf(status.InvalidArgument, "invalid user ID"), w) util.WriteError(status.Errorf(status.InvalidArgument, "invalid user ID"), w)
return return
} }
if userID != user.Id {
util.WriteErrorResponse("User not authorized to get tokens", http.StatusUnauthorized, w) pats, err := h.accountManager.GetAllPATs(account.Id, user.Id, userID)
if err != nil {
util.WriteError(err, w)
return return
} }
var pats []*api.PersonalAccessToken var patResponse []*api.PersonalAccessToken
for _, pat := range account.Users[userID].PATs { for _, pat := range pats {
pats = append(pats, toPATResponse(pat)) patResponse = append(patResponse, toPATResponse(pat))
} }
util.WriteJSONObject(w, pats) util.WriteJSONObject(w, patResponse)
} }
// GetToken is HTTP GET handler that returns a personal access token for the given user // GetToken is HTTP GET handler that returns a personal access token for the given user
@ -69,15 +71,11 @@ func (h *PATHandler) GetToken(w http.ResponseWriter, r *http.Request) {
} }
vars := mux.Vars(r) vars := mux.Vars(r)
userID := vars["userId"] targetUserID := vars["userId"]
if len(userID) == 0 { if len(targetUserID) == 0 {
util.WriteError(status.Errorf(status.InvalidArgument, "invalid user ID"), w) util.WriteError(status.Errorf(status.InvalidArgument, "invalid user ID"), w)
return return
} }
if userID != user.Id {
util.WriteErrorResponse("User not authorized to get token", http.StatusUnauthorized, w)
return
}
tokenID := vars["tokenId"] tokenID := vars["tokenId"]
if len(tokenID) == 0 { if len(tokenID) == 0 {
@ -85,15 +83,9 @@ func (h *PATHandler) GetToken(w http.ResponseWriter, r *http.Request) {
return return
} }
user = account.Users[userID] pat, err := h.accountManager.GetPAT(account.Id, user.Id, targetUserID, tokenID)
if user == nil { if err != nil {
util.WriteError(status.Errorf(status.NotFound, "user not found"), w) util.WriteError(err, w)
return
}
pat := user.PATs[tokenID]
if pat == nil {
util.WriteError(status.Errorf(status.NotFound, "PAT not found"), w)
return return
} }
@ -110,15 +102,11 @@ func (h *PATHandler) CreateToken(w http.ResponseWriter, r *http.Request) {
} }
vars := mux.Vars(r) vars := mux.Vars(r)
userID := vars["userId"] targetUserID := vars["userId"]
if len(userID) == 0 { if len(targetUserID) == 0 {
util.WriteError(status.Errorf(status.InvalidArgument, "invalid user ID"), w) util.WriteError(status.Errorf(status.InvalidArgument, "invalid user ID"), w)
return return
} }
if userID != user.Id {
util.WriteErrorResponse("User not authorized to create token", http.StatusUnauthorized, w)
return
}
var req api.PostApiUsersUserIdTokensJSONRequestBody var req api.PostApiUsersUserIdTokensJSONRequestBody
err = json.NewDecoder(r.Body).Decode(&req) err = json.NewDecoder(r.Body).Decode(&req)
@ -127,23 +115,7 @@ func (h *PATHandler) CreateToken(w http.ResponseWriter, r *http.Request) {
return return
} }
if req.Name == "" { pat, err := h.accountManager.CreatePAT(account.Id, user.Id, targetUserID, req.Name, req.ExpiresIn)
util.WriteErrorResponse("name can't be empty", http.StatusBadRequest, w)
return
}
if req.ExpiresIn < 1 || req.ExpiresIn > 365 {
util.WriteErrorResponse("expiration has to be between 1 and 365", http.StatusBadRequest, w)
return
}
pat, err := server.CreateNewPAT(req.Name, req.ExpiresIn, user.Id)
if err != nil {
util.WriteError(err, w)
return
}
err = h.accountManager.AddPATToUser(account.Id, userID, &pat.PersonalAccessToken)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return
@ -162,15 +134,11 @@ func (h *PATHandler) DeleteToken(w http.ResponseWriter, r *http.Request) {
} }
vars := mux.Vars(r) vars := mux.Vars(r)
userID := vars["userId"] targetUserID := vars["userId"]
if len(userID) == 0 { if len(targetUserID) == 0 {
util.WriteError(status.Errorf(status.InvalidArgument, "invalid user ID"), w) util.WriteError(status.Errorf(status.InvalidArgument, "invalid user ID"), w)
return return
} }
if userID != user.Id {
util.WriteErrorResponse("User not authorized to delete token", http.StatusUnauthorized, w)
return
}
tokenID := vars["tokenId"] tokenID := vars["tokenId"]
if len(tokenID) == 0 { if len(tokenID) == 0 {
@ -178,7 +146,7 @@ func (h *PATHandler) DeleteToken(w http.ResponseWriter, r *http.Request) {
return return
} }
err = h.accountManager.DeletePAT(account.Id, userID, tokenID) err = h.accountManager.DeletePAT(account.Id, user.Id, targetUserID, tokenID)
if err != nil { if err != nil {
util.WriteError(err, w) util.WriteError(err, w)
return return

View File

@ -63,31 +63,55 @@ var testAccount = &server.Account{
func initPATTestData() *PATHandler { func initPATTestData() *PATHandler {
return &PATHandler{ return &PATHandler{
accountManager: &mock_server.MockAccountManager{ accountManager: &mock_server.MockAccountManager{
AddPATToUserFunc: func(accountID string, userID string, pat *server.PersonalAccessToken) error { CreatePATFunc: func(accountID string, executingUserID string, targetUserID string, tokenName string, expiresIn int) (*server.PersonalAccessTokenGenerated, error) {
if accountID != existingAccountID { if accountID != existingAccountID {
return status.Errorf(status.NotFound, "account with ID %s not found", accountID) return nil, status.Errorf(status.NotFound, "account with ID %s not found", accountID)
} }
if userID != existingUserID { if targetUserID != existingUserID {
return status.Errorf(status.NotFound, "user with ID %s not found", userID) return nil, status.Errorf(status.NotFound, "user with ID %s not found", targetUserID)
} }
return nil return &server.PersonalAccessTokenGenerated{
PlainToken: "nbp_z1pvsg2wP3EzmEou4S679KyTNhov632eyrXe",
PersonalAccessToken: server.PersonalAccessToken{},
}, nil
}, },
GetAccountFromTokenFunc: func(_ jwtclaims.AuthorizationClaims) (*server.Account, *server.User, error) { GetAccountFromTokenFunc: func(_ jwtclaims.AuthorizationClaims) (*server.Account, *server.User, error) {
return testAccount, testAccount.Users[existingUserID], nil return testAccount, testAccount.Users[existingUserID], nil
}, },
DeletePATFunc: func(accountID string, userID string, tokenID string) error { DeletePATFunc: func(accountID string, executingUserID string, targetUserID string, tokenID string) error {
if accountID != existingAccountID { if accountID != existingAccountID {
return status.Errorf(status.NotFound, "account with ID %s not found", accountID) return status.Errorf(status.NotFound, "account with ID %s not found", accountID)
} }
if userID != existingUserID { if targetUserID != existingUserID {
return status.Errorf(status.NotFound, "user with ID %s not found", userID) return status.Errorf(status.NotFound, "user with ID %s not found", targetUserID)
} }
if tokenID != existingTokenID { if tokenID != existingTokenID {
return status.Errorf(status.NotFound, "token with ID %s not found", tokenID) return status.Errorf(status.NotFound, "token with ID %s not found", tokenID)
} }
return nil return nil
}, },
GetPATFunc: func(accountID string, executingUserID string, targetUserID string, tokenID string) (*server.PersonalAccessToken, error) {
if accountID != existingAccountID {
return nil, status.Errorf(status.NotFound, "account with ID %s not found", accountID)
}
if targetUserID != existingUserID {
return nil, status.Errorf(status.NotFound, "user with ID %s not found", targetUserID)
}
if tokenID != existingTokenID {
return nil, status.Errorf(status.NotFound, "token with ID %s not found", tokenID)
}
return testAccount.Users[existingUserID].PATs[existingTokenID], nil
},
GetAllPATsFunc: func(accountID string, executingUserID string, targetUserID string) ([]*server.PersonalAccessToken, error) {
if accountID != existingAccountID {
return nil, status.Errorf(status.NotFound, "account with ID %s not found", accountID)
}
if targetUserID != existingUserID {
return nil, status.Errorf(status.NotFound, "user with ID %s not found", targetUserID)
}
return []*server.PersonalAccessToken{testAccount.Users[existingUserID].PATs[existingTokenID], testAccount.Users[existingUserID].PATs["token2"]}, nil
},
}, },
claimsExtractor: jwtclaims.NewClaimsExtractor( claimsExtractor: jwtclaims.NewClaimsExtractor(
jwtclaims.WithFromRequestContext(func(r *http.Request) jwtclaims.AuthorizationClaims { jwtclaims.WithFromRequestContext(func(r *http.Request) jwtclaims.AuthorizationClaims {

View File

@ -60,8 +60,10 @@ type MockAccountManager struct {
SaveSetupKeyFunc func(accountID string, key *server.SetupKey, userID string) (*server.SetupKey, error) SaveSetupKeyFunc func(accountID string, key *server.SetupKey, userID string) (*server.SetupKey, error)
ListSetupKeysFunc func(accountID, userID string) ([]*server.SetupKey, error) ListSetupKeysFunc func(accountID, userID string) ([]*server.SetupKey, error)
SaveUserFunc func(accountID, userID string, user *server.User) (*server.UserInfo, error) SaveUserFunc func(accountID, userID string, user *server.User) (*server.UserInfo, error)
AddPATToUserFunc func(accountID string, userID string, pat *server.PersonalAccessToken) error CreatePATFunc func(accountID string, executingUserID string, targetUserId string, tokenName string, expiresIn int) (*server.PersonalAccessTokenGenerated, error)
DeletePATFunc func(accountID string, userID string, tokenID string) error DeletePATFunc func(accountID string, executingUserID string, targetUserId string, tokenID string) error
GetPATFunc func(accountID string, executingUserID string, targetUserId string, tokenID string) (*server.PersonalAccessToken, error)
GetAllPATsFunc func(accountID string, executingUserID string, targetUserId string) ([]*server.PersonalAccessToken, error)
GetNameServerGroupFunc func(accountID, nsGroupID string) (*nbdns.NameServerGroup, error) GetNameServerGroupFunc func(accountID, nsGroupID string) (*nbdns.NameServerGroup, error)
CreateNameServerGroupFunc func(accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool, userID string) (*nbdns.NameServerGroup, error) CreateNameServerGroupFunc func(accountID string, name, description string, nameServerList []nbdns.NameServer, groups []string, primary bool, domains []string, enabled bool, userID string) (*nbdns.NameServerGroup, error)
SaveNameServerGroupFunc func(accountID, userID string, nsGroupToSave *nbdns.NameServerGroup) error SaveNameServerGroupFunc func(accountID, userID string, nsGroupToSave *nbdns.NameServerGroup) error
@ -186,22 +188,38 @@ func (am *MockAccountManager) GetAccountFromPAT(pat string) (*server.Account, *s
return nil, nil, nil, status.Errorf(codes.Unimplemented, "method GetAccountFromPAT is not implemented") return nil, nil, nil, status.Errorf(codes.Unimplemented, "method GetAccountFromPAT is not implemented")
} }
// AddPATToUser mock implementation of AddPATToUser from server.AccountManager interface // CreatePAT mock implementation of GetPAT from server.AccountManager interface
func (am *MockAccountManager) AddPATToUser(accountID string, userID string, pat *server.PersonalAccessToken) error { func (am *MockAccountManager) CreatePAT(accountID string, executingUserID string, targetUserID string, name string, expiresIn int) (*server.PersonalAccessTokenGenerated, error) {
if am.AddPATToUserFunc != nil { if am.CreatePATFunc != nil {
return am.AddPATToUserFunc(accountID, userID, pat) return am.CreatePATFunc(accountID, executingUserID, targetUserID, name, expiresIn)
} }
return status.Errorf(codes.Unimplemented, "method AddPATToUser is not implemented") return nil, status.Errorf(codes.Unimplemented, "method CreatePAT is not implemented")
} }
// DeletePAT mock implementation of DeletePAT from server.AccountManager interface // DeletePAT mock implementation of DeletePAT from server.AccountManager interface
func (am *MockAccountManager) DeletePAT(accountID string, userID string, tokenID string) error { func (am *MockAccountManager) DeletePAT(accountID string, executingUserID string, targetUserID string, tokenID string) error {
if am.DeletePATFunc != nil { if am.DeletePATFunc != nil {
return am.DeletePATFunc(accountID, userID, tokenID) return am.DeletePATFunc(accountID, executingUserID, targetUserID, tokenID)
} }
return status.Errorf(codes.Unimplemented, "method DeletePAT is not implemented") return status.Errorf(codes.Unimplemented, "method DeletePAT is not implemented")
} }
// GetPAT mock implementation of GetPAT from server.AccountManager interface
func (am *MockAccountManager) GetPAT(accountID string, executingUserID string, targetUserID string, tokenID string) (*server.PersonalAccessToken, error) {
if am.GetPATFunc != nil {
return am.GetPATFunc(accountID, executingUserID, targetUserID, tokenID)
}
return nil, status.Errorf(codes.Unimplemented, "method GetPAT is not implemented")
}
// GetAllPATs mock implementation of GetAllPATs from server.AccountManager interface
func (am *MockAccountManager) GetAllPATs(accountID string, executingUserID string, targetUserID string) ([]*server.PersonalAccessToken, error) {
if am.GetAllPATsFunc != nil {
return am.GetAllPATsFunc(accountID, executingUserID, targetUserID)
}
return nil, status.Errorf(codes.Unimplemented, "method GetAllPATs is not implemented")
}
// GetNetworkMap mock implementation of GetNetworkMap from server.AccountManager interface // GetNetworkMap mock implementation of GetNetworkMap from server.AccountManager interface
func (am *MockAccountManager) GetNetworkMap(peerKey string) (*server.NetworkMap, error) { func (am *MockAccountManager) GetNetworkMap(peerKey string) (*server.NetworkMap, error) {
if am.GetNetworkMapFunc != nil { if am.GetNetworkMapFunc != nil {

View File

@ -193,37 +193,63 @@ func (am *DefaultAccountManager) CreateUser(accountID, userID string, invite *Us
} }
// AddPATToUser takes the userID and the accountID the user belongs to and assigns a provided PersonalAccessToken to that user // CreatePAT creates a new PAT for the given user
func (am *DefaultAccountManager) AddPATToUser(accountID string, userID string, pat *PersonalAccessToken) error { func (am *DefaultAccountManager) CreatePAT(accountID string, executingUserID string, targetUserId string, tokenName string, expiresIn int) (*PersonalAccessTokenGenerated, error) {
unlock := am.Store.AcquireAccountLock(accountID) unlock := am.Store.AcquireAccountLock(accountID)
defer unlock() defer unlock()
if tokenName == "" {
return nil, status.Errorf(status.InvalidArgument, "token name can't be empty")
}
if expiresIn < 1 || expiresIn > 365 {
return nil, status.Errorf(status.InvalidArgument, "expiration has to be between 1 and 365")
}
if executingUserID != targetUserId {
return nil, status.Errorf(status.PermissionDenied, "no permission to create PAT for this user")
}
account, err := am.Store.GetAccount(accountID) account, err := am.Store.GetAccount(accountID)
if err != nil { if err != nil {
return err return nil, err
} }
user := account.Users[userID] targetUser := account.Users[targetUserId]
if user == nil { if targetUser == nil {
return status.Errorf(status.NotFound, "user not found") return nil, status.Errorf(status.NotFound, "targetUser not found")
} }
user.PATs[pat.ID] = pat pat, err := CreateNewPAT(tokenName, expiresIn, targetUser.Id)
if err != nil {
return nil, status.Errorf(status.Internal, "failed to create PAT: %v", err)
}
return am.Store.SaveAccount(account) targetUser.PATs[pat.ID] = &pat.PersonalAccessToken
err = am.Store.SaveAccount(account)
if err != nil {
return nil, status.Errorf(status.Internal, "failed to save account: %v", err)
}
return pat, nil
} }
// DeletePAT deletes a specific PAT from a user // DeletePAT deletes a specific PAT from a user
func (am *DefaultAccountManager) DeletePAT(accountID string, userID string, tokenID string) error { func (am *DefaultAccountManager) DeletePAT(accountID string, executingUserID string, targetUserID string, tokenID string) error {
unlock := am.Store.AcquireAccountLock(accountID) unlock := am.Store.AcquireAccountLock(accountID)
defer unlock() defer unlock()
account, err := am.Store.GetAccount(accountID) if executingUserID != targetUserID {
if err != nil { return status.Errorf(status.PermissionDenied, "no permission to delete PAT for this user")
return err
} }
user := account.Users[userID] account, err := am.Store.GetAccount(accountID)
if err != nil {
return status.Errorf(status.NotFound, "account not found: %s", err)
}
user := account.Users[targetUserID]
if user == nil { if user == nil {
return status.Errorf(status.NotFound, "user not found") return status.Errorf(status.NotFound, "user not found")
} }
@ -235,15 +261,73 @@ func (am *DefaultAccountManager) DeletePAT(accountID string, userID string, toke
err = am.Store.DeleteTokenID2UserIDIndex(pat.ID) err = am.Store.DeleteTokenID2UserIDIndex(pat.ID)
if err != nil { if err != nil {
return err return status.Errorf(status.Internal, "Failed to delete token id index: %s", err)
} }
err = am.Store.DeleteHashedPAT2TokenIDIndex(pat.HashedToken) err = am.Store.DeleteHashedPAT2TokenIDIndex(pat.HashedToken)
if err != nil { if err != nil {
return err return status.Errorf(status.Internal, "Failed to delete hashed token index: %s", err)
} }
delete(user.PATs, tokenID) delete(user.PATs, tokenID)
return am.Store.SaveAccount(account) err = am.Store.SaveAccount(account)
if err != nil {
return status.Errorf(status.Internal, "Failed to save account: %s", err)
}
return nil
}
// GetPAT returns a specific PAT from a user
func (am *DefaultAccountManager) GetPAT(accountID string, executingUserID string, targetUserID string, tokenID string) (*PersonalAccessToken, error) {
unlock := am.Store.AcquireAccountLock(accountID)
defer unlock()
if executingUserID != targetUserID {
return nil, status.Errorf(status.PermissionDenied, "no permission to get PAT for this user")
}
account, err := am.Store.GetAccount(accountID)
if err != nil {
return nil, status.Errorf(status.NotFound, "account not found: %s", err)
}
user := account.Users[targetUserID]
if user == nil {
return nil, status.Errorf(status.NotFound, "user not found")
}
pat := user.PATs[tokenID]
if pat == nil {
return nil, status.Errorf(status.NotFound, "PAT not found")
}
return pat, nil
}
// GetAllPATs returns all PATs for a user
func (am *DefaultAccountManager) GetAllPATs(accountID string, executingUserID string, targetUserID string) ([]*PersonalAccessToken, error) {
unlock := am.Store.AcquireAccountLock(accountID)
defer unlock()
if executingUserID != targetUserID {
return nil, status.Errorf(status.PermissionDenied, "no permission to get PAT for this user")
}
account, err := am.Store.GetAccount(accountID)
if err != nil {
return nil, status.Errorf(status.NotFound, "account not found: %s", err)
}
user := account.Users[targetUserID]
if user == nil {
return nil, status.Errorf(status.NotFound, "user not found")
}
var pats []*PersonalAccessToken
for _, pat := range user.PATs {
pats = append(pats, pat)
}
return pats, nil
} }
// SaveUser saves updates a given user. If the user doesn't exit it will throw status.NotFound error. // SaveUser saves updates a given user. If the user doesn't exit it will throw status.NotFound error.

View File

@ -7,13 +7,20 @@ import (
) )
const ( const (
mockAccountID = "accountID" mockAccountID = "accountID"
mockUserID = "userID" mockUserID = "userID"
mockTokenID = "tokenID" mockTargetUserId = "targetUserID"
mockToken = "SoMeHaShEdToKeN" mockTokenID1 = "tokenID1"
mockToken1 = "SoMeHaShEdToKeN1"
mockTokenID2 = "tokenID2"
mockToken2 = "SoMeHaShEdToKeN2"
mockTokenName = "tokenName"
mockEmptyTokenName = ""
mockExpiresIn = 7
mockWrongExpiresIn = 4506
) )
func TestUser_AddPATToUser(t *testing.T) { func TestUser_CreatePAT_ForSameUser(t *testing.T) {
store := newStore(t) store := newStore(t)
account := newAccountWithId(mockAccountID, mockUserID, "") account := newAccountWithId(mockAccountID, mockUserID, "")
@ -26,24 +33,19 @@ func TestUser_AddPATToUser(t *testing.T) {
Store: store, Store: store,
} }
pat := PersonalAccessToken{ pat, err := am.CreatePAT(mockAccountID, mockUserID, mockUserID, mockTokenName, mockExpiresIn)
ID: mockTokenID,
HashedToken: mockToken,
}
err = am.AddPATToUser(mockAccountID, mockUserID, &pat)
if err != nil { if err != nil {
t.Fatalf("Error when adding PAT to user: %s", err) t.Fatalf("Error when adding PAT to user: %s", err)
} }
fileStore := am.Store.(*FileStore) fileStore := am.Store.(*FileStore)
tokenID := fileStore.HashedPAT2TokenID[mockToken] tokenID := fileStore.HashedPAT2TokenID[pat.HashedToken]
if tokenID == "" { if tokenID == "" {
t.Fatal("GetTokenIDByHashedToken failed after adding PAT") t.Fatal("GetTokenIDByHashedToken failed after adding PAT")
} }
assert.Equal(t, mockTokenID, tokenID) assert.Equal(t, pat.ID, tokenID)
userID := fileStore.TokenID2UserID[tokenID] userID := fileStore.TokenID2UserID[tokenID]
if userID == "" { if userID == "" {
@ -52,15 +54,66 @@ func TestUser_AddPATToUser(t *testing.T) {
assert.Equal(t, mockUserID, userID) assert.Equal(t, mockUserID, userID)
} }
func TestUser_CreatePAT_ForDifferentUser(t *testing.T) {
store := newStore(t)
account := newAccountWithId(mockAccountID, mockUserID, "")
err := store.SaveAccount(account)
if err != nil {
t.Fatalf("Error when saving account: %s", err)
}
am := DefaultAccountManager{
Store: store,
}
_, err = am.CreatePAT(mockAccountID, mockUserID, mockTargetUserId, mockTokenName, mockExpiresIn)
assert.Errorf(t, err, "Creating PAT for different user should thorw error")
}
func TestUser_CreatePAT_WithWrongExpiration(t *testing.T) {
store := newStore(t)
account := newAccountWithId(mockAccountID, mockUserID, "")
err := store.SaveAccount(account)
if err != nil {
t.Fatalf("Error when saving account: %s", err)
}
am := DefaultAccountManager{
Store: store,
}
_, err = am.CreatePAT(mockAccountID, mockUserID, mockUserID, mockTokenName, mockWrongExpiresIn)
assert.Errorf(t, err, "Wrong expiration should thorw error")
}
func TestUser_CreatePAT_WithEmptyName(t *testing.T) {
store := newStore(t)
account := newAccountWithId(mockAccountID, mockUserID, "")
err := store.SaveAccount(account)
if err != nil {
t.Fatalf("Error when saving account: %s", err)
}
am := DefaultAccountManager{
Store: store,
}
_, err = am.CreatePAT(mockAccountID, mockUserID, mockUserID, mockEmptyTokenName, mockExpiresIn)
assert.Errorf(t, err, "Wrong expiration should thorw error")
}
func TestUser_DeletePAT(t *testing.T) { func TestUser_DeletePAT(t *testing.T) {
store := newStore(t) store := newStore(t)
account := newAccountWithId(mockAccountID, mockUserID, "") account := newAccountWithId(mockAccountID, mockUserID, "")
account.Users[mockUserID] = &User{ account.Users[mockUserID] = &User{
Id: mockUserID, Id: mockUserID,
PATs: map[string]*PersonalAccessToken{ PATs: map[string]*PersonalAccessToken{
mockTokenID: { mockTokenID1: {
ID: mockTokenID, ID: mockTokenID1,
HashedToken: mockToken, HashedToken: mockToken1,
}, },
}, },
} }
@ -73,12 +126,79 @@ func TestUser_DeletePAT(t *testing.T) {
Store: store, Store: store,
} }
err = am.DeletePAT(mockAccountID, mockUserID, mockTokenID) err = am.DeletePAT(mockAccountID, mockUserID, mockUserID, mockTokenID1)
if err != nil { if err != nil {
t.Fatalf("Error when adding PAT to user: %s", err) t.Fatalf("Error when adding PAT to user: %s", err)
} }
assert.Nil(t, store.Accounts[mockAccountID].Users[mockUserID].PATs[mockTokenID]) assert.Nil(t, store.Accounts[mockAccountID].Users[mockUserID].PATs[mockTokenID1])
assert.Empty(t, store.HashedPAT2TokenID[mockToken]) assert.Empty(t, store.HashedPAT2TokenID[mockToken1])
assert.Empty(t, store.TokenID2UserID[mockTokenID]) assert.Empty(t, store.TokenID2UserID[mockTokenID1])
}
func TestUser_GetPAT(t *testing.T) {
store := newStore(t)
account := newAccountWithId(mockAccountID, mockUserID, "")
account.Users[mockUserID] = &User{
Id: mockUserID,
PATs: map[string]*PersonalAccessToken{
mockTokenID1: {
ID: mockTokenID1,
HashedToken: mockToken1,
},
},
}
err := store.SaveAccount(account)
if err != nil {
t.Fatalf("Error when saving account: %s", err)
}
am := DefaultAccountManager{
Store: store,
}
pat, err := am.GetPAT(mockAccountID, mockUserID, mockUserID, mockTokenID1)
if err != nil {
t.Fatalf("Error when adding PAT to user: %s", err)
}
assert.Equal(t, mockTokenID1, pat.ID)
assert.Equal(t, mockToken1, pat.HashedToken)
}
func TestUser_GetAllPATs(t *testing.T) {
store := newStore(t)
account := newAccountWithId(mockAccountID, mockUserID, "")
account.Users[mockUserID] = &User{
Id: mockUserID,
PATs: map[string]*PersonalAccessToken{
mockTokenID1: {
ID: mockTokenID1,
HashedToken: mockToken1,
},
mockTokenID2: {
ID: mockTokenID2,
HashedToken: mockToken2,
},
},
}
err := store.SaveAccount(account)
if err != nil {
t.Fatalf("Error when saving account: %s", err)
}
am := DefaultAccountManager{
Store: store,
}
pats, err := am.GetAllPATs(mockAccountID, mockUserID, mockUserID)
if err != nil {
t.Fatalf("Error when adding PAT to user: %s", err)
}
assert.Equal(t, 2, len(pats))
assert.Equal(t, mockTokenID1, pats[0].ID)
assert.Equal(t, mockToken1, pats[0].HashedToken)
assert.Equal(t, mockTokenID2, pats[1].ID)
assert.Equal(t, mockToken2, pats[1].HashedToken)
} }