Documentation
¶
Index ¶
- Constants
- Variables
- func GetAuthURL(res http.ResponseWriter, req *http.Request) (string, error)
- func GetMessage(id MessageID) string
- func Logout(res http.ResponseWriter, req *http.Request) error
- type AuthResponse
- type InviteEmailData
- type MessageID
- type OIDCConfiguration
- type PhoneLogin
- type ResetEmailData
- type Router
- func (ar *Router) AppID() negroni.HandlerFunc
- func (ar *Router) DumpRequest() negroni.HandlerFunc
- func (ar *Router) EnableTFA() http.HandlerFunc
- func (ar *Router) Error(w http.ResponseWriter, errID MessageID, status int, details, where string)
- func (ar *Router) FederatedLogin() http.HandlerFunc
- func (ar *Router) FederatedLoginComplete() http.HandlerFunc
- func (ar *Router) FinalizeTFA() http.HandlerFunc
- func (ar *Router) GetAppSettings() http.HandlerFunc
- func (ar *Router) GetUser() http.HandlerFunc
- func (ar *Router) HandleHello() http.HandlerFunc
- func (ar *Router) HandlePing() http.HandlerFunc
- func (ar *Router) IsLoggedIn() http.HandlerFunc
- func (ar *Router) LoginWithPassword() http.HandlerFunc
- func (ar *Router) Logout() http.HandlerFunc
- func (ar *Router) MustParseJSON(w http.ResponseWriter, r *http.Request, out interface{}) error
- func (ar *Router) OIDCConfiguration() http.HandlerFunc
- func (ar *Router) OIDCJwks() http.HandlerFunc
- func (ar *Router) PhoneLogin() http.HandlerFunc
- func (ar *Router) RefreshTokens() http.HandlerFunc
- func (ar *Router) RegisterWithPassword() http.HandlerFunc
- func (ar *Router) RemoveTrailingSlash() negroni.HandlerFunc
- func (ar *Router) RequestDisabledTFA() http.HandlerFunc
- func (ar *Router) RequestInviteLink() http.HandlerFunc
- func (ar *Router) RequestResetPassword() http.HandlerFunc
- func (ar *Router) RequestTFAReset() http.HandlerFunc
- func (ar *Router) RequestVerificationCode() http.HandlerFunc
- func (ar *Router) ResendTFA() http.HandlerFunc
- func (ar *Router) ResetPassword() http.HandlerFunc
- func (ar *Router) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (ar *Router) ServeJSON(w http.ResponseWriter, status int, v interface{})
- func (ar *Router) SignatureHandler() negroni.HandlerFunc
- func (ar *Router) Token(tokenType string, scopes []string) negroni.HandlerFunc
- func (ar *Router) UpdateUser() http.HandlerFunc
- type RouterSettings
- type SendTFAEmailData
Constants ¶
const ( // HeaderKeyAppID is a header key to keep application ID. HeaderKeyAppID = "X-Identifo-Clientid" QueryKeyAppID = "appId" )
const ( // SignatureHeaderKey header stores HMAC signature digest. SignatureHeaderKey = "Digest" // SignatureHeaderValuePrefix is a signature prefix, indicating hash algorithm, hardcoded for now, could be dynamic in the future. SignatureHeaderValuePrefix = "SHA-256=" // TimestampHeaderKey header stores timestamp. TimestampHeaderKey = "X-Identifo-Timestamp" )
const ( // ErrorAPIInternalServerError means that server got unknown error. ErrorAPIInternalServerError = "api.internal_server_error" // ErrorAPIAppAccessDenied is when access is denied. ErrorAPIAppAccessDenied = "api.app.access_denied" // ErrorAPIUserUnableToCreate is when user cannot create the resource. ErrorAPIUserUnableToCreate = "error.api.user.unable_to_create" // ErrorAPIVerificationCodeInvalid stands for invalid verification code. ErrorAPIVerificationCodeInvalid = "error.api.verification_code.invalid" // ErrorAPIUserNotFound is when user not found. ErrorAPIUserNotFound = "error.api.user.not_found" // ErrorAPIUsernameTaken is when username is already taken. ErrorAPIUsernameTaken = "error.api.username.taken" // ErrorAPIUsernameEmailOrPhoneTaken is when username or email or phone is already taken. ErrorAPIUsernameEmailOrPhoneTaken = "error.api.username_phone_email.taken" // ErrorAPIEmailTaken is when email is already taken. ErrorAPIEmailTaken = "error.api.email.taken" // ErrorAPIPhoneTaken is when phone is already taken. ErrorAPIPhoneTaken = "error.api.phone.taken" // ErrorAPIInviteTokenServerError is for invite token creation issues. ErrorAPIInviteTokenServerError = "error.api.invite_token.server_error" // ErrorAPIInviteUnableToInvalidate is when invite cannot be invalidated. ErrorAPIInviteUnableToInvalidate = "error.api.invite.unable_to_invalidate" // ErrorAPIInviteUnableToSave is when invite cannot be saved. ErrorAPIInviteUnableToSave = "error.api.invite.unable_to_save" // ErrorAPIInviteUnableToGet is when invites cannot be fetched. ErrorAPIInviteUnableToGet = "errors.api.invite.unable_to_get" // ErrorAPIEmailNotSent means that email had not been sent. ErrorAPIEmailNotSent = "error.api.email.not_sent" // ErrorAPIRequestPasswordWeak means that password didn't pass strength validation. ErrorAPIRequestPasswordWeak = "error.api.request.password.weak" // ErrorAPIRequestIncorrectLoginOrPassword is for incorrect login or password. ErrorAPIRequestIncorrectLoginOrPassword = "error.api.request.incorrect_login_or_password" // ErrorAPIRequestScopesForbidden is for forbidden request scopes. ErrorAPIRequestScopesForbidden = "error.api.request.scopes.forbidden" // ErrorAPIRequestBodyInvalid means that request body is corrupted. ErrorAPIRequestBodyInvalid = "error.api.request.body.invalid" // ErrorAPIRequestBodyParamsInvalid means that request params are corrupted. ErrorAPIRequestBodyParamsInvalid = "error.api.request.body.params.invalid" // ErrorAPIRequestBodyOldPasswordInvalid is for invalid old password. ErrorAPIRequestBodyOldPasswordInvalid = "error.api.request.body.oldpassword.invalid" // ErrorAPIRequestBodyEmailInvalid means that email in request body is corrupted. ErrorAPIRequestBodyEmailInvalid = "error.api.request.body.email.invalid" // ErrorAPIRequestSignatureInvalid is a HMAC request signature error. ErrorAPIRequestSignatureInvalid = "error.api.request.signature.invalid" // ErrorAPIRequestAppIDInvalid means that application ID header value is invalid. ErrorAPIRequestAppIDInvalid = "error.api.request.app_id.invalid" // ErrorAPIRequestCallbackUrlInvalid means that callback url is invalid. ErrorAPIRequestCallbackUrlInvalid = "error.api.request.callbackurl.invalid" // ErrorAPIRequestTokenInvalid means that the token is invalid or empty. ErrorAPIRequestTokenInvalid = "error.api.request.token.invalid" // ErrorAPIRequestTFACodeEmpty means that the 2FA code is empty. ErrorAPIRequestTFACodeEmpty = "error.api.request.2fa_code.empty" // ErrorAPIRequestTFACodeInvalid means that the 2FA code is invalid. ErrorAPIRequestTFACodeInvalid = "error.api.request.2fa_code.invalid" // ErrorAPIRequestTFAAlreadyEnabled means that 2FA is already enabled for the user. ErrorAPIRequestTFAAlreadyEnabled = "error.api.request.2fa.already_enabled" // ErrorAPIRequestPleaseEnableTFA means that user must request TFA and obtain TFA secret to be able to use the app. ErrorAPIRequestPleaseEnableTFA = "error.api.request.2fa.please_enable" // ErrorAPIRequestPleaseDisableTFA means that user must disable TFA to be able to use the app. ErrorAPIRequestPleaseDisableTFA = "error.api.request.2fa.please_disable" // ErrorAPIRequestMandatoryTFA means that user cannot disable TFA for the app. ErrorAPIRequestMandatoryTFA = "error.api.request.2fa.mandatory" // ErrorAPIRequestDisabledTFA means that app does not support TFA. ErrorAPIRequestDisabledTFA = "error.api.request.2fa.disabled" // ErrorAPIRequestPleaseSetPhoneForTFA means that user must set up their phone number to be able to receive OTPs in SMS. ErrorAPIRequestPleaseSetPhoneForTFA = "error.api.request.2fa.set_phone" // ErrorAPIRequestPleaseSetEmailForTFA means that user must set up their email address to be able to receive OTPs on the email. ErrorAPIRequestPleaseSetEmailForTFA = "error.api.request.2fa.set_email" // ErrorAPIRequestEnableTFAEmptyPhoneAndEmail means that the email and phone is empty ErrorAPIRequestEnableTFAEmptyPhoneAndEmail = "error.api.request.enable_2fa.empty_phone_and_email" // ErrorAPIRequestUnableToSendOTP means that there is error sending the otp code while login to user ErrorAPIRequestUnableToSendOTP = "error.api.request.2fa.unable to send OTP code to email or sms" // ErrorAPIAppInactive means that the reqesting app is inactive. ErrorAPIAppInactive = "error.api.app.inactive" // ErrorAPIAppRegistrationForbidden means that registration is forbidden. ErrorAPIAppRegistrationForbidden = "error.api.app.registration_forbidden" // ErrorAPIAppResetTokenNotCreated means that registration is forbidden. ErrorAPIAppResetTokenNotCreated = "error.api.app.unable_to_create_reset_token" // ErrorAPIAppAccessTokenNotCreated means that registration is forbidden. ErrorAPIAppAccessTokenNotCreated = "error.api.app.unable_to_create_access_token" // ErrorAPIAppRefreshTokenNotCreated means that registration is forbidden. ErrorAPIAppRefreshTokenNotCreated = "error.api.app.unable_to_create_refresh_token" // ErrorAPIAppCannotExtractTokenSubject is when we cannot extract token "sub". ErrorAPIAppCannotExtractTokenSubject = "error.api.request.token.sub" // ErrorAPIAppCannotInitAuthorizer is when we cannot init internal authorizer. ErrorAPIAppCannotInitAuthorizer = "error.api.request.authorizer.internal.init" // ErrorAPIAppFederatedProviderNotSupported means that the federated ID provider is not supported. ErrorAPIAppFederatedProviderNotSupported = "api.app.federated.provider.not_supported" // ErrorAPIAppFederatedProviderEmptyUserID means that the federated provider returns empty user ID, maybe access token does not have required permissions. ErrorAPIAppFederatedEmptyRedirect = "api.app.federated.provider.empty_redirect" ErrorAPIAppFederatedEmptyProvider = "api.app.federated.provider.empty" ErrorAPIAppFederatedCantComplete = "api.app.federated.provider.cant_complete" // ErrorAPIAppFederatedLoginNotSupported means that the app does not support federated login. // ErrorAPIAppFederatedLoginNotSupported = "api.app.federated.login.not_supported" // ErrorAPIAppLoginWithUsernameNotSupported means that the app does not support login by username. ErrorAPIAppLoginWithUsernameNotSupported = "api.app.username.login.not_supported" // ErrorAPIAppPhoneLoginNotSupported means that the app does not support login by phone number. ErrorAPIAppPhoneLoginNotSupported = "api.app.phone.login.not_supported" )
const SessionName = "_federated_session"
SessionName is the key used to access the session store.
const (
// TokenHeaderKey is a header name for Bearer token.
TokenHeaderKey = "Authorization"
)
Variables ¶
var CompleteUserAuth = func(res http.ResponseWriter, req *http.Request) (goth.User, error) { if !keySet && defaultStore == Store { fmt.Println("goth/gothic: no SESSION_SECRET environment variable is set. The default cookie store is not available and any calls will fail. Ignore this warning if you are using a different store.") } providerName, err := getProviderName(req) if err != nil { return goth.User{}, err } app, _ := getApp(req) if err != nil { return goth.User{}, err } provider, err := goth.GetProvider(providerName) if err != nil { return goth.User{}, err } value, err := getFromSession(getSessionName(app.ID, providerName), req) if err != nil { return goth.User{}, err } defer Logout(res, req) fsess, err := model.UnmarshalFederatedSession(value) if err != nil { return goth.User{}, err } sess, err := provider.UnmarshalSession(fsess.ProviderSession) if err != nil { return goth.User{}, err } err = validateState(req, sess) if err != nil { return goth.User{}, err } user, err := provider.FetchUser(sess) if err == nil { return user, err } params := req.URL.Query() if params.Encode() == "" && req.Method == "POST" { req.ParseForm() params = req.Form } _, err = sess.Authorize(provider, params) if err != nil { return goth.User{}, err } err = storeInSession(getSessionName(app.ID, providerName), fsess.Marshal(), req, res) if err != nil { return goth.User{}, err } gu, err := provider.FetchUser(sess) return gu, err }
CompleteUserAuth does what it says on the tin. It completes the authentication process and fetches all of the basic information about the user from the provider. It expects to be able to get the name of the provider from the query parameters as either "provider" or ":provider". See https://github.com/markbates/goth/examples/main.go to see this in action.
var (
Store sessions.Store
)
Store can/should be set by applications using gothic. The default is a cookie store.
Functions ¶
func GetAuthURL ¶
GetAuthURL starts the authentication process with the requested provided. It will return a URL that should be used to send users to. It expects to be able to get the name of the provider from the query parameters as either "provider"
Types ¶
type AuthResponse ¶
type AuthResponse struct { AccessToken string `json:"access_token,omitempty" bson:"access_token,omitempty"` RefreshToken string `json:"refresh_token,omitempty" bson:"refresh_token,omitempty"` User model.User `json:"user,omitempty" bson:"user,omitempty"` Require2FA bool `json:"require_2fa" bson:"require_2fa"` Enabled2FA bool `json:"enabled_2fa" bson:"enabled_2fa"` CallbackUrl string `json:"callback_url,omitempty" bson:"callback_url,omitempty"` Scopes []string `json:"scopes,omitempty" bson:"scopes,omitempty"` }
AuthResponse is a response with successful auth data.
type InviteEmailData ¶
type OIDCConfiguration ¶
type OIDCConfiguration struct { Issuer string `json:"issuer"` JwksURI string `json:"jwks_uri"` ScopesSupported []string `json:"scopes_supported"` SupportedIDSigningAlgs []string `json:"id_token_signing_alg_values_supported"` }
OIDCConfiguration describes OIDC configuration. Additional info: https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata. Identifo is not an OIDC provider, that's why we only provide the information for token validation.
type PhoneLogin ¶
type PhoneLogin struct { PhoneNumber string `json:"phone_number"` Code string `json:"code"` Scopes []string `json:"scopes"` }
PhoneLogin is used to parse input data from the client during phone login.
type ResetEmailData ¶
type Router ¶
type Router struct { Authorizer *authorization.Authorizer Host string SupportedLoginWays model.LoginWith LoginAppPath string LoginPasswordResetPath string LoggerSettings model.LoggerSettings // contains filtered or unexported fields }
Router is a router that handles all API requests.
func NewRouter ¶
func NewRouter(settings RouterSettings) (*Router, error)
NewRouter creates and inits new router.
func (*Router) AppID ¶
func (ar *Router) AppID() negroni.HandlerFunc
AppID extracts application ID from the header and writes corresponding app to the context.
func (*Router) DumpRequest ¶
func (ar *Router) DumpRequest() negroni.HandlerFunc
DumpRequest logs the request.
func (*Router) EnableTFA ¶
func (ar *Router) EnableTFA() http.HandlerFunc
EnableTFA enables two-factor authentication for the user.
func (*Router) FederatedLogin ¶
func (ar *Router) FederatedLogin() http.HandlerFunc
func (*Router) FederatedLoginComplete ¶
func (ar *Router) FederatedLoginComplete() http.HandlerFunc
func (*Router) FinalizeTFA ¶
func (ar *Router) FinalizeTFA() http.HandlerFunc
FinalizeTFA finalizes two-factor authentication.
func (*Router) GetAppSettings ¶
func (ar *Router) GetAppSettings() http.HandlerFunc
GetAppSettings return app settings
func (*Router) GetUser ¶
func (ar *Router) GetUser() http.HandlerFunc
GetUser return current user info with sanitized tfa
func (*Router) HandleHello ¶
func (ar *Router) HandleHello() http.HandlerFunc
HandleHello returns hello message.
func (*Router) HandlePing ¶
func (ar *Router) HandlePing() http.HandlerFunc
HandlePing returns pong message.
func (*Router) IsLoggedIn ¶
func (ar *Router) IsLoggedIn() http.HandlerFunc
IsLoggedIn is for checking whether user is logged in or not. In fact, all needed work is done in Token middleware. If we reached this code, user is logged in (presented valid and not blacklisted access token).
func (*Router) LoginWithPassword ¶
func (ar *Router) LoginWithPassword() http.HandlerFunc
LoginWithPassword logs user in with email and password.
func (*Router) Logout ¶
func (ar *Router) Logout() http.HandlerFunc
Logout logs user out and deactivates their tokens.
func (*Router) MustParseJSON ¶
MustParseJSON parses request body json data to the `out` struct. If error happens, writes it to ResponseWriter.
func (*Router) OIDCConfiguration ¶
func (ar *Router) OIDCConfiguration() http.HandlerFunc
OIDCConfiguration provides an OpenID Connect Discovery information (https://openid.net/specs/openid-connect-discovery-1_0.html). It should return RFC5785-compatible documentation (https://tools.ietf.org/html/rfc5785). This endpoint allows using Identifo as Federated identity provider. For example, AWS AppSync (https://docs.aws.amazon.com/appsync/latest/devguide/security.html#openid-connect-authorization).
func (*Router) OIDCJwks ¶
func (ar *Router) OIDCJwks() http.HandlerFunc
OIDCJwks returns JSON Web Keys object. Identifo supports two algorithms for signing JSON Web Tokens (JWTs): RS256 and ES256. RS256 and ES256 generate an asymmetric signature, which means a private key must be used to sign the JWT, and a different public key must be used to verify the signature.
At the most basic level, the JWKS is a set of keys containing the public keys that should be used to verify any JWT issued by the authorization server. This endpoint exposes a JWKS endpoint for each tenant, which can be found at https://YOUR_IDENTIFO_DOMAIN/.well-known/jwks.json. Currently Identifo only supports a single JWK for signing, however it is important to assume this endpoint technically could contain multiple JWKs.
func (*Router) PhoneLogin ¶
func (ar *Router) PhoneLogin() http.HandlerFunc
PhoneLogin authenticates user with phone number and verification code. If user exists - create new session and return token. If user does not exist - register and then login (create session and return token). If code is invalid - return error.
func (*Router) RefreshTokens ¶
func (ar *Router) RefreshTokens() http.HandlerFunc
RefreshTokens issues new access and, if requsted, refresh token for provided refresh token. After new tokens are issued, the old refresh token gets invalidated (via blacklisting).
func (*Router) RegisterWithPassword ¶
func (ar *Router) RegisterWithPassword() http.HandlerFunc
RegisterWithPassword registers new user with password.
func (*Router) RemoveTrailingSlash ¶
func (ar *Router) RemoveTrailingSlash() negroni.HandlerFunc
func (*Router) RequestDisabledTFA ¶
func (ar *Router) RequestDisabledTFA() http.HandlerFunc
RequestDisabledTFA requests link for disabling TFA.
func (*Router) RequestInviteLink ¶
func (ar *Router) RequestInviteLink() http.HandlerFunc
RequestInviteLink requests invite link. Invite link will be returned in response even if email or access_role is not specified.
func (*Router) RequestResetPassword ¶
func (ar *Router) RequestResetPassword() http.HandlerFunc
RequestResetPassword requests password reset
func (*Router) RequestTFAReset ¶
func (ar *Router) RequestTFAReset() http.HandlerFunc
RequestTFAReset requests link for resetting TFA: deleting old shared secret and establishing the new one.
func (*Router) RequestVerificationCode ¶
func (ar *Router) RequestVerificationCode() http.HandlerFunc
RequestVerificationCode requests SMS with verification code. To authenticate, user must have a valid phone number.
func (*Router) ResendTFA ¶
func (ar *Router) ResendTFA() http.HandlerFunc
func (*Router) ResetPassword ¶
func (ar *Router) ResetPassword() http.HandlerFunc
ResetPassword handles password reset form submission (POST request).
func (*Router) ServeHTTP ¶
func (ar *Router) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements identifo.Router interface.
func (*Router) ServeJSON ¶
func (ar *Router) ServeJSON(w http.ResponseWriter, status int, v interface{})
ServeJSON sends status code, headers and data and send it back to the user
func (*Router) SignatureHandler ¶
func (ar *Router) SignatureHandler() negroni.HandlerFunc
SignatureHandler returns middleware that handles request signature. More info: https://identifo.madappgang.com/#ca6498ab-b3dc-4c1e-a5b0-2dd633831e2d.
func (*Router) Token ¶
func (ar *Router) Token(tokenType string, scopes []string) negroni.HandlerFunc
Token middleware extracts token and validates it.
func (*Router) UpdateUser ¶
func (ar *Router) UpdateUser() http.HandlerFunc
UpdateUser allows to change user login and password.