func assertStringClaim(claims jose.Claims, k string) string { s, ok, err := claims.StringClaim(k) if !ok || err != nil { panic(fmt.Sprintf("claims were not validated correctly, missing or wrong claim: %v", k)) } return s }
// Generate creates a Capabilities Token given some configuration values. // See https://www.twilio.com/docs/api/client/capability-tokens for details. func Generate(c Capabilities, expires time.Duration) (string, error) { signer := jose.NewSignerHMAC("", []byte(c.AuthToken)) claims := jose.Claims{} claims.Add("iss", c.AccountSid) claims.Add("exp", Clock.Now().Add(expires).Unix()) scopes := []string{} if c.AllowClientOutgoing != "" { scope := fmt.Sprintf("scope:client:outgoing?appSid=%s", c.AllowClientOutgoing) if c.AllowClientIncoming != "" { scope += fmt.Sprintf("&clientName=%s", c.AllowClientIncoming) } scopes = append(scopes, scope) } if c.AllowClientIncoming != "" { scopes = append(scopes, fmt.Sprintf("scope:client:incoming?clientName=%s", c.AllowClientIncoming)) } claims.Add("scope", strings.Join(scopes, " ")) jwt, err := jose.NewSignedJWT(claims, signer) if err != nil { return "", err } return jwt.Encode(), nil }
// Assumes that parseAndVerifyTokenClaims has already been called on claims func verifyPasswordResetClaims(claims jose.Claims) (PasswordReset, error) { cb, ok, err := claims.StringClaim(ClaimPasswordResetCallback) if err != nil { return PasswordReset{}, err } if _, err := url.Parse(cb); err != nil { return PasswordReset{}, fmt.Errorf("callback URL not parseable: %v", cb) } pw, ok, err := claims.StringClaim(ClaimPasswordResetPassword) if err != nil { return PasswordReset{}, err } if !ok || pw == "" { return PasswordReset{}, fmt.Errorf("no %q claim", ClaimPasswordResetPassword) } return PasswordReset{claims}, nil }
// addClaimsFromScope adds claims that are based on the scopes that the client requested. // Currently, these include cross-client claims (aud, azp). func (s *Server) addClaimsFromScope(claims jose.Claims, scopes scope.Scopes, clientID string) error { crossClientIDs := scopes.CrossClientIDs() if len(crossClientIDs) > 0 { var aud []string for _, id := range crossClientIDs { if clientID == id { aud = append(aud, id) continue } allowed, err := s.CrossClientAuthAllowed(clientID, id) if err != nil { log.Errorf("Failed to check cross client auth. reqClientID %v; authClient:ID %v; err: %v", clientID, id, err) return oauth2.NewError(oauth2.ErrorServerError) } if !allowed { err := oauth2.NewError(oauth2.ErrorInvalidRequest) err.Description = fmt.Sprintf( "%q is not authorized to perform cross-client requests for %q", clientID, id) return err } aud = append(aud, id) } if len(aud) == 1 { claims.Add("aud", aud[0]) } else { claims.Add("aud", aud) } claims.Add("azp", clientID) } return nil }
func IdentityFromClaims(claims jose.Claims) (*Identity, error) { if claims == nil { return nil, errors.New("nil claim set") } var ident Identity var err error var ok bool if ident.ID, ok, err = claims.StringClaim("sub"); err != nil { return nil, err } else if !ok { return nil, errors.New("missing required claim: sub") } if ident.Email, _, err = claims.StringClaim("email"); err != nil { return nil, err } exp, ok, err := claims.TimeClaim("exp") if err != nil { return nil, err } else if ok { ident.ExpiresAt = exp } return &ident, nil }
// Assumes that parseAndVerifyTokenClaims has already been called on claims func verifyEmailVerificationClaims(claims jose.Claims) (EmailVerification, error) { email, ok, err := claims.StringClaim(ClaimEmailVerificationEmail) if err != nil { return EmailVerification{}, err } if !ok || email == "" { return EmailVerification{}, fmt.Errorf("no %q claim", ClaimEmailVerificationEmail) } cb, ok, err := claims.StringClaim(ClaimEmailVerificationCallback) if err != nil { return EmailVerification{}, err } if !ok || cb == "" { return EmailVerification{}, fmt.Errorf("no %q claim", ClaimEmailVerificationCallback) } if _, err := url.Parse(cb); err != nil { return EmailVerification{}, fmt.Errorf("callback URL not parseable: %v", cb) } return EmailVerification{claims}, nil }
// AddToClaims adds basic information about the user to the given Claims. // http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims func (u *User) AddToClaims(claims jose.Claims) { claims.Add("name", u.DisplayName) if u.Email != "" { claims.Add("email", u.Email) if u.EmailVerified { claims.Add("email_verified", true) } } }