Link account id with the external user store (#184)

* get account id from access token claim

* use GetOrCreateAccountByUser and add test

* correct account id claim

* remove unused account

* Idp manager interface

* auth0 idp manager

* use if instead of switch case

* remove unnecessary lock

* NewAuth0Manager

* move idpmanager to its own package

* update metadata when accountId is not supplied

* update tests with idpmanager field

* format

* new idp manager and config support

* validate if we fetch the interface before converting to string

* split getJWTToken

* improve tests

* proper json fields and handle defer body close

* fix ci lint notes

* documentation and proper defer position

* UpdateUserAppMetadata tests

* update documentation

* ManagerCredentials interface

* Marshal and Unmarshal functions

* fix tests

* ManagerHelper and ManagerHTTPClient

* further tests with mocking

* rename package and custom http client

* sync local packages

* remove idp suffix
This commit is contained in:
Maycon Santos
2022-01-24 11:21:30 +01:00
committed by GitHub
parent 2ad899b066
commit fd7282d3cf
21 changed files with 806 additions and 28 deletions

View File

@@ -13,6 +13,7 @@ import (
//Peers is a handler that returns peers of the account
type Peers struct {
accountManager *server.AccountManager
authAudience string
}
//PeerResponse is a response sent to the client
@@ -29,9 +30,10 @@ type PeerRequest struct {
Name string
}
func NewPeers(accountManager *server.AccountManager) *Peers {
func NewPeers(accountManager *server.AccountManager, authAudience string) *Peers {
return &Peers{
accountManager: accountManager,
authAudience: authAudience,
}
}
@@ -62,8 +64,9 @@ func (h *Peers) deletePeer(accountId string, peer *server.Peer, w http.ResponseW
}
func (h *Peers) HandlePeer(w http.ResponseWriter, r *http.Request) {
userId := extractUserIdFromRequestContext(r)
account, err := h.accountManager.GetOrCreateAccountByUser(userId)
userId, accountId := extractUserAndAccountIdFromRequestContext(r, h.authAudience)
//new user -> create a new account
account, err := h.accountManager.GetAccountByUserOrAccountId(userId, accountId)
if err != nil {
log.Errorf("failed getting account of a user %s: %v", userId, err)
http.Redirect(w, r, "/", http.StatusInternalServerError)
@@ -102,9 +105,9 @@ func (h *Peers) HandlePeer(w http.ResponseWriter, r *http.Request) {
func (h *Peers) GetPeers(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
userId := extractUserIdFromRequestContext(r)
userId, accountId := extractUserAndAccountIdFromRequestContext(r, h.authAudience)
//new user -> create a new account
account, err := h.accountManager.GetOrCreateAccountByUser(userId)
account, err := h.accountManager.GetAccountByUserOrAccountId(userId, accountId)
if err != nil {
log.Errorf("failed getting account of a user %s: %v", userId, err)
http.Redirect(w, r, "/", http.StatusInternalServerError)

View File

@@ -15,6 +15,7 @@ import (
// SetupKeys is a handler that returns a list of setup keys of the account
type SetupKeys struct {
accountManager *server.AccountManager
authAudience string
}
// SetupKeyResponse is a response sent to the client
@@ -39,9 +40,10 @@ type SetupKeyRequest struct {
Revoked bool
}
func NewSetupKeysHandler(accountManager *server.AccountManager) *SetupKeys {
func NewSetupKeysHandler(accountManager *server.AccountManager, authAudience string) *SetupKeys {
return &SetupKeys{
accountManager: accountManager,
authAudience: authAudience,
}
}
@@ -118,8 +120,8 @@ func (h *SetupKeys) createKey(accountId string, w http.ResponseWriter, r *http.R
}
func (h *SetupKeys) HandleKey(w http.ResponseWriter, r *http.Request) {
userId := extractUserIdFromRequestContext(r)
account, err := h.accountManager.GetOrCreateAccountByUser(userId)
userId, accountId := extractUserAndAccountIdFromRequestContext(r, h.authAudience)
account, err := h.accountManager.GetAccountByUserOrAccountId(userId, accountId)
if err != nil {
log.Errorf("failed getting account of a user %s: %v", userId, err)
http.Redirect(w, r, "/", http.StatusInternalServerError)
@@ -147,9 +149,8 @@ func (h *SetupKeys) HandleKey(w http.ResponseWriter, r *http.Request) {
func (h *SetupKeys) GetKeys(w http.ResponseWriter, r *http.Request) {
userId := extractUserIdFromRequestContext(r)
//new user -> create a new account
account, err := h.accountManager.GetOrCreateAccountByUser(userId)
userId, accountId := extractUserAndAccountIdFromRequestContext(r, h.authAudience)
account, err := h.accountManager.GetAccountByUserOrAccountId(userId, accountId)
if err != nil {
log.Errorf("failed getting account of a user %s: %v", userId, err)
http.Redirect(w, r, "/", http.StatusInternalServerError)

View File

@@ -8,13 +8,17 @@ import (
"time"
)
// extractUserIdFromRequestContext extracts accountId from the request context previously filled by the JWT token (after auth)
func extractUserIdFromRequestContext(r *http.Request) string {
// extractUserAndAccountIdFromRequestContext extracts accountId from the request context previously filled by the JWT token (after auth)
func extractUserAndAccountIdFromRequestContext(r *http.Request, authAudiance string) (userId, accountId string) {
token := r.Context().Value("user").(*jwt.Token)
claims := token.Claims.(jwt.MapClaims)
//actually a user id but for now we have a 1 to 1 mapping.
return claims["sub"].(string)
userId = claims["sub"].(string)
accountIdInt, ok := claims[authAudiance+"wt_account_id"]
if ok {
accountId = accountIdInt.(string)
}
return userId, accountId
}
//writeJSONObject simply writes object to the HTTP reponse in JSON format

View File

@@ -73,8 +73,8 @@ func (s *Server) Start() error {
r := mux.NewRouter()
r.Use(jwtMiddleware.Handler, corsMiddleware.Handler)
peersHandler := handler.NewPeers(s.accountManager)
keysHandler := handler.NewSetupKeysHandler(s.accountManager)
peersHandler := handler.NewPeers(s.accountManager, s.config.AuthAudience)
keysHandler := handler.NewSetupKeysHandler(s.accountManager, s.config.AuthAudience)
r.HandleFunc("/api/peers", peersHandler.GetPeers).Methods("GET", "OPTIONS")
r.HandleFunc("/api/peers/{id}", peersHandler.HandlePeer).Methods("GET", "PUT", "DELETE", "OPTIONS")