zitadel/pkg/auth/api/oidc/client.go
Livio Amstutz e653eaab86
fix: login (#242)
* password in init user only if needed

* reactivate user session

* set context AuthorizeClientIDSecret

* fix qr code for light

* fix copy

* check user and org active in auth

* add org view provider

* handle inactive projects

* translate error messages
2020-06-19 14:52:04 +02:00

98 lines
2.7 KiB
Go

package oidc
import (
"context"
"github.com/caos/oidc/pkg/oidc"
"github.com/caos/oidc/pkg/op"
"github.com/caos/zitadel/internal/api/auth"
"github.com/caos/zitadel/internal/errors"
proj_model "github.com/caos/zitadel/internal/project/model"
user_model "github.com/caos/zitadel/internal/user/model"
)
const (
scopeOpenID = "openid"
scopeProfile = "profile"
scopeEmail = "email"
scopePhone = "phone"
scopeAddress = "address"
oidcCtx = "oidc"
)
func (o *OPStorage) GetClientByClientID(ctx context.Context, id string) (op.Client, error) {
client, err := o.repo.ApplicationByClientID(ctx, id)
if err != nil {
return nil, err
}
if client.State != proj_model.APPSTATE_ACTIVE {
return nil, errors.ThrowPreconditionFailed(nil, "OIDC-sdaGg", "client is not active")
}
return ClientFromBusiness(client, o.defaultLoginURL, o.defaultAccessTokenLifetime, o.defaultIdTokenLifetime)
}
func (o *OPStorage) AuthorizeClientIDSecret(ctx context.Context, id string, secret string) error {
ctx = auth.SetCtxData(ctx, auth.CtxData{
UserID: oidcCtx,
OrgID: oidcCtx,
})
return o.repo.AuthorizeOIDCApplication(ctx, id, secret)
}
func (o *OPStorage) GetUserinfoFromToken(ctx context.Context, tokenID string) (*oidc.Userinfo, error) {
token, err := o.repo.TokenByID(ctx, tokenID)
if err != nil {
return nil, err
}
return o.GetUserinfoFromScopes(ctx, token.UserID, token.Scopes)
}
func (o *OPStorage) GetUserinfoFromScopes(ctx context.Context, userID string, scopes []string) (*oidc.Userinfo, error) {
user, err := o.repo.UserByID(ctx, userID)
if err != nil {
return nil, err
}
userInfo := new(oidc.Userinfo)
for _, scope := range scopes {
switch scope {
case scopeOpenID:
userInfo.Subject = user.ID
case scopeEmail:
userInfo.Email = user.Email
userInfo.EmailVerified = user.IsEmailVerified
case scopeProfile:
userInfo.Name = user.DisplayName
userInfo.FamilyName = user.LastName
userInfo.GivenName = user.FirstName
userInfo.Nickname = user.NickName
userInfo.PreferredUsername = user.PreferredLoginName
userInfo.UpdatedAt = user.ChangeDate
userInfo.Gender = oidc.Gender(getGender(user.Gender))
case scopePhone:
userInfo.PhoneNumber = user.Phone
userInfo.PhoneNumberVerified = user.IsPhoneVerified
case scopeAddress:
userInfo.Address.StreetAddress = user.StreetAddress
userInfo.Address.Locality = user.Locality
userInfo.Address.Region = user.Region
userInfo.Address.PostalCode = user.PostalCode
userInfo.Address.Country = user.Country
}
}
return userInfo, nil
}
func getGender(gender user_model.Gender) string {
switch gender {
case user_model.GENDER_FEMALE:
return "female"
case user_model.GENDER_MALE:
return "male"
case user_model.GENDER_DIVERSE:
return "diverse"
}
return ""
}