lib/app/auth0.go

163 lines
4.8 KiB
Go
Raw Permalink Normal View History

2021-01-10 18:16:20 +00:00
package app
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
"time"
2021-01-18 03:13:54 +00:00
2021-01-18 19:46:19 +00:00
"code.tnxs.net/taxnexus/lib/api/auth0/auth0_client/auth"
2021-01-18 03:13:54 +00:00
"code.tnxs.net/taxnexus/lib/api/auth0/auth0_client/user"
"code.tnxs.net/taxnexus/lib/api/auth0/auth0_models"
2021-01-10 18:16:20 +00:00
)
2021-01-18 19:46:19 +00:00
var auth0AuthToken string
var auth0Expires time.Time
// GetAuth0AuthToken is a func
func GetAuth0AuthToken() string {
2021-01-28 19:17:39 +00:00
sugar.Infof("app.getAuth0AuthToken: 📥")
2021-01-18 19:46:19 +00:00
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 {
2021-01-28 19:17:39 +00:00
sugar.Errorf("app.getAuth0AuthToken: 💣 ⛔ : %w", err)
2021-01-18 19:46:19 +00:00
}
auth0Expires = time.Now().Add(time.Duration(response.Payload.ExpiresIn) * time.Second)
auth0AuthToken = response.Payload.AccessToken
2021-01-28 19:17:39 +00:00
sugar.Debugf("app.getAuth0AuthToken: 📏 new token: %s", auth0AuthToken)
sugar.Infof("app.getAuth0AuthToken: 👍 📤 new token retrieved")
2021-01-18 19:46:19 +00:00
return auth0AuthToken
}
2021-01-18 03:13:54 +00:00
// 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
}
2021-01-10 18:16:20 +00:00
type auth0TokenResponse struct {
AccessToken string
TokenType string
}
2021-01-10 19:50:48 +00:00
const tokenURL = "https://taxnexus.auth0.com/oauth/token" //nolint:gosec // false positive
2021-01-10 18:16:20 +00:00
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 ""
}
2021-01-27 21:17:16 +00:00
defer res.Body.Close() //nolint:errcheck // it's defered
2021-01-10 18:16:20 +00:00
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
}