package app import ( "encoding/json" "fmt" "io/ioutil" "net/http" "strings" "time" "code.tnxs.net/taxnexus/lib/api/auth0/auth0_client/auth" "code.tnxs.net/taxnexus/lib/api/auth0/auth0_client/user" "code.tnxs.net/taxnexus/lib/api/auth0/auth0_models" ) var auth0AuthToken string var auth0Expires time.Time // GetAuth0AuthToken is a func func GetAuth0AuthToken() string { sugar.Infof("board.getAuth0AuthToken: 📥") if auth0Expires.After(time.Now()) { return auth0AuthToken } apiParams := auth.NewPostCredentialsParamsWithTimeout(getTimeout) apiParams.CredentialsRequest = &auth0_models.CredentialsRequest{ ClientID: GetServiceAccount("auth0").ClientID, ClientSecret: GetServiceAccount("auth0").ClientSecret, Audience: "https://taxnexus.auth0.com/api/v2/", GrantType: "client_credentials", } response, err := auth0Client.Auth.PostCredentials(apiParams) if err != nil { sugar.Errorf("board.getAuth0AuthToken: 💣 ⛔ : %w", err) } auth0Expires = time.Now().Add(time.Duration(response.Payload.ExpiresIn) * time.Second) auth0AuthToken = response.Payload.AccessToken sugar.Debugf("board.getAuth0AuthToken: 📏 new token: %s", auth0AuthToken) sugar.Infof("board.getAuth0AuthToken: 👍 📤 new token retrieved") return auth0AuthToken } // GetAuth0UserByEmail looks up Auth0 user by email func GetAuth0UserByEmail(email string) (string, error) { sugar.Info("app.GetAuth0UserByEmail: 📥") authToken := GetAuth0AccessToken() if authToken == "" { return "", fmt.Errorf("app.GetAuth0UserByEmail: 💣⛔ Error obtaining bearer token") } auth0Params := user.NewGetUserByEmailParamsWithTimeout(getTimeout) auth0Params.Authorization = "Bearer " + authToken auth0Params.Email = email auth0Response, err := auth0Client.User.GetUserByEmail(auth0Params) if err != nil { return "", err } if len(auth0Response.Payload) == 0 { sugar.Infof("app.GetAuth0UserByEmail: 👍📤 %s not found", email) return constNotFound, nil } sugar.Infof("app.GetAuth0UserByEmail: 👍📤 %s found %s", email, auth0Response.Payload[0].UserID) return auth0Response.Payload[0].UserID, nil } // CreateNewAuth0User creates a new Auth0 User func CreateNewAuth0User(newUser *NewAuth0User) (string, error) { sugar.Info("app.CreateNewAuth0User: 📥") authToken := GetAuth0AccessToken() if authToken == "" { return "", fmt.Errorf("app.CreateNewAuth0User: 💣⛔ Error obtaining bearer token") } auth0Params := user.NewPostUsersParamsWithTimeout(postTimeout) auth0Params.Authorization = "Bearer " + authToken auth0Params.UserRequest.Users = []*auth0_models.NewUser{ { Email: newUser.Email, Name: newUser.Name, FamilyName: newUser.FamilyName, GivenName: newUser.GivenName, Nickname: newUser.Nickname, Password: newUser.Password, PhoneNumber: newUser.PhoneNumber, Blocked: newUser.Blocked, Connection: newUser.Connection, EmailVerified: newUser.EmailVerified, PhoneVerified: newUser.PhoneVerified, Picture: newUser.Picture, UserID: newUser.UserID, Username: newUser.Username, VerifyEmail: newUser.VerifyEmail, }, } _, err := auth0Client.User.PostUsers(auth0Params) if err != nil { return "", err } auth0UserID, err := GetAuth0UserByEmail(newUser.Email) if err != nil { return "", err } if auth0UserID != constNotFound { return "", fmt.Errorf("app.CreateNewAuth0User: 💣⛔ Auth0 user exists: %s", auth0UserID) } return auth0UserID, nil } type auth0TokenResponse struct { AccessToken string TokenType string } const tokenURL = "https://taxnexus.auth0.com/oauth/token" //nolint:gosec // false positive const tokenTimeout = 86400 * time.Second const requestTemplate = ` { "client_id": "%s", "client_secret": "%s" "audience": "%s", "grant_type": "client_credentials" } ` var accessToken string var authTokenTime time.Time // GetAuth0AccessToken uses conf file values to get an Auth0 access token func GetAuth0AccessToken() string { if time.Now().Before(authTokenTime) && accessToken != "" { return accessToken } serviceAccount := GetServiceAccount("auth0") payload := strings.NewReader( fmt.Sprintf(requestTemplate, serviceAccount.ClientID, serviceAccount.ClientSecret, serviceAccount.Endpoint.Scheme+"://"+ serviceAccount.Endpoint.Host+ serviceAccount.Endpoint.BasePath) + "/") req, err := http.NewRequest("POST", tokenURL, payload) if err != nil { return "" } req.Header.Add("content-type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { return "" } defer res.Body.Close() //nolint:errcheck // it's defered body, err := ioutil.ReadAll(res.Body) if err != nil { return "" } var response *auth0TokenResponse err = json.Unmarshal(body, response) if err != nil { return "" } accessToken = response.AccessToken authTokenTime = time.Now().Add(tokenTimeout) return accessToken }