@@ -119,6 +119,7 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return types.NewPersonalAPIKey(personalAPIKey), nil
|
||||
}
|
||||
case coredata.SCIMConfigurationEntityType:
|
||||
@@ -128,6 +129,7 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return types.NewSCIMConfiguration(scimConfiguration), nil
|
||||
}
|
||||
case coredata.SCIMEventEntityType:
|
||||
@@ -137,6 +139,7 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return types.NewSCIMEvent(scimEvent), nil
|
||||
}
|
||||
default:
|
||||
@@ -174,6 +177,7 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot load node", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -44,5 +44,6 @@ func NewGraphQLHandler(svc *iam.Service, logger *log.Logger, baseURL *baseurl.Ba
|
||||
|
||||
es := schema.NewExecutableSchema(config)
|
||||
gqlh := gqlutils.NewHandler(es, logger)
|
||||
|
||||
return gqlh
|
||||
}
|
||||
|
||||
@@ -168,9 +168,11 @@ func (r *identityResolver) SsoLoginURL(ctx context.Context, obj *types.Identity)
|
||||
r.logger.ErrorCtx(ctx, "cannot find SAML config")
|
||||
return nil, gqlutils.NotFoundf(ctx, "cannot find SAML config")
|
||||
}
|
||||
|
||||
samlConfig := samlConfigs[0]
|
||||
|
||||
loginURL := r.SSOLoginURL(samlConfig.ID)
|
||||
|
||||
return &loginURL, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -36,8 +36,10 @@ func (r *mutationResolver) InviteUser(ctx context.Context, input types.InviteUse
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
var errOrganizationNotFound *iam.ErrOrganizationNotFound
|
||||
var errUserAlreadyExists *iam.ErrUserAlreadyExists
|
||||
var (
|
||||
errOrganizationNotFound *iam.ErrOrganizationNotFound
|
||||
errUserAlreadyExists *iam.ErrUserAlreadyExists
|
||||
)
|
||||
|
||||
if errors.As(err, &errOrganizationNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
@@ -48,6 +50,7 @@ func (r *mutationResolver) InviteUser(ctx context.Context, input types.InviteUse
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot invite user", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ func (r *membershipResolver) LastSession(ctx context.Context, obj *types.Members
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get active session for membership", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ func toOAuth2Error(err error) *oauth2server.OAuth2Error {
|
||||
if oauthErr, ok := errors.AsType[*oauth2server.OAuth2Error](err); ok {
|
||||
return oauthErr
|
||||
}
|
||||
|
||||
return oauth2server.NewError(oauth2server.ErrServerError, oauth2server.WithDescription("internal error"))
|
||||
}
|
||||
}
|
||||
@@ -108,12 +109,15 @@ func redirectWithError(w http.ResponseWriter, r *http.Request, redirectURI, stat
|
||||
|
||||
q := u.Query()
|
||||
q.Set("error", oauthErr.ErrorCode())
|
||||
|
||||
if desc := oauthErr.Description(); desc != "" {
|
||||
q.Set("error_description", desc)
|
||||
}
|
||||
|
||||
if state != "" {
|
||||
q.Set("state", state)
|
||||
}
|
||||
|
||||
u.RawQuery = q.Encode()
|
||||
|
||||
http.Redirect(w, r, u.String(), http.StatusFound)
|
||||
|
||||
@@ -98,6 +98,7 @@ func (h *OAuth2Handler) BearerTokenMiddleware(next http.Handler) http.Handler {
|
||||
if err != nil {
|
||||
w.Header().Set("WWW-Authenticate", `Bearer error="invalid_token"`)
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -105,6 +106,7 @@ func (h *OAuth2Handler) BearerTokenMiddleware(next http.Handler) http.Handler {
|
||||
if err != nil {
|
||||
w.Header().Set("WWW-Authenticate", `Bearer error="invalid_token"`)
|
||||
http.Error(w, "unauthorized", http.StatusUnauthorized)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -160,6 +162,7 @@ func (h *OAuth2Handler) AuthorizeHandler(w http.ResponseWriter, r *http.Request)
|
||||
WithQuery("continue", continueURL).
|
||||
MustString()
|
||||
http.Redirect(w, r, loginURL, http.StatusFound)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -170,6 +173,7 @@ func (h *OAuth2Handler) AuthorizeHandler(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
session := authn.SessionFromContext(r.Context())
|
||||
|
||||
authTime := time.Now()
|
||||
if session != nil {
|
||||
authTime = session.CreatedAt
|
||||
@@ -197,12 +201,14 @@ func (h *OAuth2Handler) AuthorizeHandler(w http.ResponseWriter, r *http.Request)
|
||||
WithQuery("consent_id", consentErr.ConsentID.String()).
|
||||
MustString()
|
||||
http.Redirect(w, r, consentURL, http.StatusFound)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
oauthErr := toOAuth2Error(err)
|
||||
h.handleAuthorizeError(w, r, oauthErr, in.RedirectURI, in.State)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -282,6 +288,7 @@ func (h *OAuth2Handler) RevokeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
h.logger.ErrorCtx(r.Context(), "cannot revoke token", log.Error(err))
|
||||
w.Header().Set("Retry-After", "30")
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -340,21 +347,26 @@ func (h *OAuth2Handler) RegisterHandler(w http.ResponseWriter, r *http.Request)
|
||||
r,
|
||||
oauth2server.NewError(oauth2server.ErrInvalidRequest, oauth2server.WithDescription("invalid JSON body")),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if len(in.GrantTypes) == 0 {
|
||||
in.GrantTypes = []coredata.OAuth2GrantType{coredata.OAuth2GrantTypeAuthorizationCode}
|
||||
}
|
||||
|
||||
if len(in.ResponseTypes) == 0 {
|
||||
in.ResponseTypes = []coredata.OAuth2ResponseType{coredata.OAuth2ResponseTypeCode}
|
||||
}
|
||||
|
||||
if in.TokenEndpointAuthMethod == "" {
|
||||
in.TokenEndpointAuthMethod = coredata.OAuth2ClientTokenEndpointAuthMethodClientSecretBasic
|
||||
}
|
||||
|
||||
if in.Visibility == "" {
|
||||
in.Visibility = coredata.OAuth2ClientVisibilityPrivate
|
||||
}
|
||||
|
||||
if len(in.Scopes) == 0 {
|
||||
in.Scopes = coredata.OAuth2Scopes{
|
||||
coredata.OAuth2ScopeOpenID,
|
||||
@@ -539,9 +551,11 @@ func redirectWithCode(w http.ResponseWriter, r *http.Request, redirectURI, code,
|
||||
u, _ := url.Parse(redirectURI)
|
||||
q := u.Query()
|
||||
q.Set("code", code)
|
||||
|
||||
if state != "" {
|
||||
q.Set("state", state)
|
||||
}
|
||||
|
||||
u.RawQuery = q.Encode()
|
||||
|
||||
http.Redirect(w, r, u.String(), http.StatusFound)
|
||||
|
||||
@@ -50,6 +50,7 @@ func (r *mutationResolver) AuthorizeDevice(ctx context.Context, input types.Auth
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot authorize device", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -89,12 +90,15 @@ func (r *mutationResolver) ApproveConsent(ctx context.Context, input types.Appro
|
||||
q := u.Query()
|
||||
q.Set("error", "access_denied")
|
||||
q.Set("error_description", "user denied the request")
|
||||
|
||||
if result.State != "" {
|
||||
q.Set("state", result.State)
|
||||
}
|
||||
|
||||
u.RawQuery = q.Encode()
|
||||
|
||||
redirectURL := u.String()
|
||||
|
||||
return &types.ApproveConsentPayload{
|
||||
RedirectURL: &redirectURL,
|
||||
}, nil
|
||||
@@ -109,12 +113,15 @@ func (r *mutationResolver) ApproveConsent(ctx context.Context, input types.Appro
|
||||
u, _ := url.Parse(result.RedirectURI)
|
||||
q := u.Query()
|
||||
q.Set("code", result.Code)
|
||||
|
||||
if result.State != "" {
|
||||
q.Set("state", result.State)
|
||||
}
|
||||
|
||||
u.RawQuery = q.Encode()
|
||||
|
||||
redirectURL := u.String()
|
||||
|
||||
return &types.ApproveConsentPayload{
|
||||
RedirectURL: &redirectURL,
|
||||
}, nil
|
||||
|
||||
@@ -81,6 +81,7 @@ func (h *OIDCHandler) LoginHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
h.logger.ErrorCtx(ctx, "cannot initiate OIDC login", log.Error(err))
|
||||
httpserver.RenderError(w, http.StatusInternalServerError, errors.New("internal server error"))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -105,6 +106,7 @@ func (h *OIDCHandler) CallbackHandler(w http.ResponseWriter, r *http.Request) {
|
||||
log.String("error_description", r.URL.Query().Get("error_description")),
|
||||
)
|
||||
httpserver.RenderError(w, http.StatusUnauthorized, errors.New("authentication failed"))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -120,6 +122,7 @@ func (h *OIDCHandler) CallbackHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
h.logger.ErrorCtx(ctx, "cannot handle OIDC callback", log.Error(err))
|
||||
httpserver.RenderError(w, http.StatusUnauthorized, errors.New("authentication failed"))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -131,6 +134,7 @@ func (h *OIDCHandler) CallbackHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
h.logger.ErrorCtx(ctx, "cannot open root session", log.Error(err))
|
||||
httpserver.RenderError(w, http.StatusInternalServerError, errors.New("internal server error"))
|
||||
|
||||
return
|
||||
}
|
||||
case rootSession.IdentityID != identity.ID:
|
||||
@@ -138,6 +142,7 @@ func (h *OIDCHandler) CallbackHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
h.logger.ErrorCtx(ctx, "cannot close session", log.Error(err))
|
||||
httpserver.RenderError(w, http.StatusInternalServerError, errors.New("internal server error"))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -145,6 +150,7 @@ func (h *OIDCHandler) CallbackHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
h.logger.ErrorCtx(ctx, "cannot open root session", log.Error(err))
|
||||
httpserver.RenderError(w, http.StatusInternalServerError, errors.New("internal server error"))
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.C
|
||||
Size: input.HorizontalLogoFile.Size,
|
||||
}
|
||||
}
|
||||
|
||||
organization, profile, err := r.iam.OrganizationService.CreateOrganization(
|
||||
ctx,
|
||||
identity.ID,
|
||||
@@ -71,6 +72,7 @@ func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.C
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot create organization", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -267,6 +269,7 @@ func (r *organizationResolver) ScimConfiguration(ctx context.Context, obj *types
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get scim configuration", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -307,16 +310,20 @@ func (r *organizationResolver) AuditLogEntries(ctx context.Context, obj *types.O
|
||||
c := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
coredataFilter := coredata.NewAuditLogEntryFilter()
|
||||
|
||||
if filter != nil {
|
||||
if filter.Action != nil {
|
||||
coredataFilter.WithAction(*filter.Action)
|
||||
}
|
||||
|
||||
if filter.ActorID != nil {
|
||||
coredataFilter.WithActorID(*filter.ActorID)
|
||||
}
|
||||
|
||||
if filter.ResourceType != nil {
|
||||
coredataFilter.WithResourceType(*filter.ResourceType)
|
||||
}
|
||||
|
||||
if filter.ResourceID != nil {
|
||||
coredataFilter.WithResourceID(*filter.ResourceID)
|
||||
}
|
||||
@@ -347,6 +354,7 @@ func (r *organizationResolver) Viewer(ctx context.Context, obj *types.Organizati
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get profile", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ func (r *personalAPIKeyConnectionResolver) TotalCount(ctx context.Context, obj *
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ func (r *mutationResolver) CreateUser(ctx context.Context, input types.CreateUse
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot create user", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -66,7 +67,6 @@ func (r *mutationResolver) DeactivateUser(ctx context.Context, input types.Deact
|
||||
input.ProfileID,
|
||||
coredata.ProfileStateInactive,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot deactivate profile", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
@@ -113,8 +113,10 @@ func (r *mutationResolver) RemoveUser(ctx context.Context, input types.RemoveUse
|
||||
|
||||
err := r.iam.OrganizationService.RemoveUser(ctx, input.OrganizationID, input.ProfileID)
|
||||
if err != nil {
|
||||
var errManagedBySCIM *iam.ErrUserManagedBySCIM
|
||||
var errLastActiveOwner *iam.ErrLastActiveOwner
|
||||
var (
|
||||
errManagedBySCIM *iam.ErrUserManagedBySCIM
|
||||
errLastActiveOwner *iam.ErrLastActiveOwner
|
||||
)
|
||||
|
||||
if errors.As(err, &errManagedBySCIM) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
@@ -125,6 +127,7 @@ func (r *mutationResolver) RemoveUser(ctx context.Context, input types.RemoveUse
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot remove user from organization", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -150,6 +153,7 @@ func (r *profileResolver) Identity(ctx context.Context, obj *types.Profile) (*ty
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get identity", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -170,6 +174,7 @@ func (r *profileResolver) Organization(ctx context.Context, obj *types.Profile)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get organization", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -190,6 +195,7 @@ func (r *profileResolver) Membership(ctx context.Context, obj *types.Profile) (*
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get membership", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -232,6 +238,7 @@ func (r *profileConnectionResolver) TotalCount(ctx context.Context, obj *types.P
|
||||
r.logger.ErrorCtx(ctx, "cannot count profiles", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &count, nil
|
||||
case *organizationResolver:
|
||||
count, err := r.iam.OrganizationService.CountProfiles(ctx, obj.ParentID, obj.Filters)
|
||||
@@ -239,10 +246,12 @@ func (r *profileConnectionResolver) TotalCount(ctx context.Context, obj *types.P
|
||||
r.logger.ErrorCtx(ctx, "cannot count profiles", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &count, nil
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -100,9 +100,9 @@ func (h *SAMLHandler) ConsumeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
continueURL := "/organizations/" + membership.OrganizationID.String()
|
||||
|
||||
if len(relayState) > gid.EncodedGIDSize {
|
||||
unescapedContinueURL, err := url.QueryUnescape(relayState[gid.EncodedGIDSize:])
|
||||
|
||||
if err != nil {
|
||||
h.logger.WarnCtx(ctx, "cannot unescape continue URL from RelayState", log.Error(err))
|
||||
} else {
|
||||
@@ -118,6 +118,7 @@ func (h *SAMLHandler) ConsumeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
h.logger.ErrorCtx(ctx, "cannot open root session", log.Error(err))
|
||||
h.renderInternalServerError(w)
|
||||
|
||||
return
|
||||
}
|
||||
case rootSession.IdentityID != user.ID:
|
||||
@@ -125,6 +126,7 @@ func (h *SAMLHandler) ConsumeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
h.logger.ErrorCtx(ctx, "cannot close session", log.Error(err))
|
||||
h.renderInternalServerError(w)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -132,6 +134,7 @@ func (h *SAMLHandler) ConsumeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
h.logger.ErrorCtx(ctx, "cannot open root session", log.Error(err))
|
||||
h.renderInternalServerError(w)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -140,6 +143,7 @@ func (h *SAMLHandler) ConsumeHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
h.logger.ErrorCtx(ctx, "cannot open SAML child session", log.Error(err))
|
||||
h.renderInternalServerError(w)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ func (r *mutationResolver) CreateSAMLConfiguration(ctx context.Context, input ty
|
||||
input.OrganizationID,
|
||||
req,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
var errSAMLConfigurationEmailDomainAlreadyExists *iam.ErrSAMLConfigurationEmailDomainAlreadyExists
|
||||
if errors.As(err, &errSAMLConfigurationEmailDomainAlreadyExists) {
|
||||
@@ -51,6 +50,7 @@ func (r *mutationResolver) CreateSAMLConfiguration(ctx context.Context, input ty
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot create saml configuration", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -133,10 +133,12 @@ func (r *sAMLConfigurationConnectionResolver) TotalCount(ctx context.Context, ob
|
||||
r.logger.ErrorCtx(ctx, "cannot count saml configurations", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &count, nil
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,7 @@ func (h *SCIMHandler) BearerTokenMiddleware(next http.Handler) http.Handler {
|
||||
|
||||
h.logger.ErrorCtx(r.Context(), "SCIM token validation error", log.Error(err))
|
||||
httpserver.RenderError(w, http.StatusInternalServerError, errors.New("internal server error"))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -157,13 +158,17 @@ func (rc *scimRequestContext) logAndWrapError(err error, logMsg string) error {
|
||||
if scimErr.Status == http.StatusNotFound {
|
||||
userName = ""
|
||||
}
|
||||
|
||||
rc.handler.handler.iam.SCIMService.LogEvent(rc.ctx, rc.config, rc.method, rc.path, userName, rc.ipAddress, scimErr.Status, &errMsg)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
rc.handler.handler.logger.ErrorCtx(rc.ctx, logMsg, log.Error(err))
|
||||
|
||||
errMsg := "internal server error"
|
||||
rc.handler.handler.iam.SCIMService.LogEvent(rc.ctx, rc.config, rc.method, rc.path, rc.userName, rc.ipAddress, 500, &errMsg)
|
||||
|
||||
return scimerrors.ScimErrorInternal
|
||||
}
|
||||
|
||||
@@ -236,6 +241,7 @@ func (h *scimResourceHandler) GetAll(r *http.Request, params scim.ListRequestPar
|
||||
}
|
||||
|
||||
var filterExpr scimfilter.Expression
|
||||
|
||||
if params.FilterValidator != nil {
|
||||
if err := params.FilterValidator.Validate(); err != nil {
|
||||
return scim.Page{}, rc.logAndWrapError(scimerrors.ScimErrorBadRequest(err.Error()), "invalid filter")
|
||||
@@ -250,6 +256,7 @@ func (h *scimResourceHandler) GetAll(r *http.Request, params scim.ListRequestPar
|
||||
}
|
||||
|
||||
rc.logSuccess(200)
|
||||
|
||||
return scim.Page{
|
||||
TotalResults: totalCount,
|
||||
Resources: resources,
|
||||
|
||||
@@ -44,6 +44,7 @@ func (r *mutationResolver) CreateSCIMConfiguration(ctx context.Context, input ty
|
||||
r.logger.ErrorCtx(ctx, "cannot create scim bridge", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
bridge = types.NewSCIMBridge(scimBridge)
|
||||
}
|
||||
|
||||
@@ -188,6 +189,7 @@ func (r *sCIMConfigurationResolver) Organization(ctx context.Context, obj *types
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get organization for scim configuration", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -212,6 +214,7 @@ func (r *sCIMConfigurationResolver) Bridge(ctx context.Context, obj *types.SCIMC
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get scim bridge", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -267,10 +270,12 @@ func (r *sCIMEventConnectionResolver) TotalCount(ctx context.Context, obj *types
|
||||
r.logger.ErrorCtx(ctx, "cannot count scim events", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &count, nil
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ func (r *mutationResolver) SignIn(ctx context.Context, input types.SignInInput)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot check credentials", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -46,6 +47,7 @@ func (r *mutationResolver) SignIn(ctx context.Context, input types.SignInInput)
|
||||
switch {
|
||||
case session == nil:
|
||||
var err error
|
||||
|
||||
session, err = r.iam.AuthService.OpenSessionWithPassword(
|
||||
ctx,
|
||||
identity.ID,
|
||||
@@ -75,17 +77,21 @@ func (r *mutationResolver) SignIn(ctx context.Context, input types.SignInInput)
|
||||
|
||||
if input.OrganizationID != nil {
|
||||
var err error
|
||||
|
||||
_, _, err = r.iam.SessionService.OpenPasswordChildSessionForOrganization(ctx, session.ID, *input.OrganizationID)
|
||||
if err != nil {
|
||||
// Here session middleware already took care of expired/nil root session so we only handle membership related errors
|
||||
var errMembershipNotFound *iam.ErrMembershipNotFound
|
||||
var errUserInactive *iam.ErrUserInactive
|
||||
var (
|
||||
errMembershipNotFound *iam.ErrMembershipNotFound
|
||||
errUserInactive *iam.ErrUserInactive
|
||||
)
|
||||
|
||||
if errors.As(err, &errMembershipNotFound) || errors.As(err, &errUserInactive) {
|
||||
return nil, gqlutils.Forbiddenf(ctx, "forbidden")
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot assume organization", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
}
|
||||
@@ -118,6 +124,7 @@ func (r *mutationResolver) SignUp(ctx context.Context, input types.SignUpInput)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot create identity with password", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -141,6 +148,7 @@ func (r *mutationResolver) SignOut(ctx context.Context) (*types.SignOutPayload,
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot close session", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -163,7 +171,6 @@ func (r *mutationResolver) ActivateAccount(ctx context.Context, input types.Acti
|
||||
r.logger.ErrorCtx(ctx, "cannot close session", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
w := gqlutils.HTTPResponseWriterFromContext(ctx)
|
||||
@@ -196,10 +203,12 @@ func (r *mutationResolver) ActivateAccount(ctx context.Context, input types.Acti
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot activate account from invitation", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
var ssoLoginURL *string
|
||||
|
||||
samlConfigs, err := r.iam.AccountService.ListSAMLConfigurationsForEmail(ctx, user.EmailAddress)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list saml configurations", log.Error(err))
|
||||
@@ -223,6 +232,7 @@ func (r *mutationResolver) ActivateAccount(ctx context.Context, input types.Acti
|
||||
}
|
||||
|
||||
var createPasswordToken *string
|
||||
|
||||
if identity.HashedPassword == nil {
|
||||
token, err := r.iam.AuthService.GetResetPasswordToken(ctx, identity.EmailAddress)
|
||||
if err != nil {
|
||||
@@ -272,6 +282,7 @@ func (r *mutationResolver) ResetPassword(ctx context.Context, input types.ResetP
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot reset password", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -307,6 +318,7 @@ func (r *mutationResolver) VerifyEmail(ctx context.Context, input types.VerifyEm
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot verify email", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -344,6 +356,7 @@ func (r *mutationResolver) ChangePassword(ctx context.Context, input types.Chang
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot change password", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -379,6 +392,7 @@ func (r *mutationResolver) ChangeEmail(ctx context.Context, input types.ChangeEm
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot change email", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -447,6 +461,7 @@ func (r *mutationResolver) RevokeSession(ctx context.Context, input types.Revoke
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot revoke session", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
@@ -506,6 +521,7 @@ func (r *sessionConnectionResolver) TotalCount(ctx context.Context, obj *types.S
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ func parseScopes(s string) (coredata.OAuth2Scopes, error) {
|
||||
if err := scopes.UnmarshalText([]byte(s)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return scopes, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
func NewPageInfo[T page.Paginable[O], O page.OrderField](p *page.Page[T, O]) *PageInfo {
|
||||
data := pageinfo.NewPageInfo(p)
|
||||
|
||||
return &PageInfo{
|
||||
HasNextPage: data.HasNextPage,
|
||||
HasPreviousPage: data.HasPreviousPage,
|
||||
|
||||
Reference in New Issue
Block a user