mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-14 11:58:02 +00:00
4c83493ad2
# Which Problems Are Solved
ZITADEL's user grants deactivation mechanism did not work correctly.
Deactivated user grants were still provided in token, which could lead
to unauthorized access to applications and resources.
Additionally, the management and auth API always returned the state as
active or did not provide any information about the state.
# How the Problems Are Solved
- Correctly check the user grant state on active for tokens and user
information (userinfo, introspection, saml attributes)
- Map state in API and display in Console
(cherry picked from commit ca1914e235
)
181 lines
6.8 KiB
Go
181 lines
6.8 KiB
Go
package user
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/zitadel/zitadel/internal/api/authz"
|
|
"github.com/zitadel/zitadel/internal/api/grpc/object"
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
"github.com/zitadel/zitadel/internal/query"
|
|
user_pb "github.com/zitadel/zitadel/pkg/grpc/user"
|
|
)
|
|
|
|
func UserGrantsToPb(assetPrefix string, grants []*query.UserGrant) []*user_pb.UserGrant {
|
|
u := make([]*user_pb.UserGrant, len(grants))
|
|
for i, grant := range grants {
|
|
u[i] = UserGrantToPb(assetPrefix, grant)
|
|
}
|
|
return u
|
|
}
|
|
|
|
func UserGrantToPb(assetPrefix string, grant *query.UserGrant) *user_pb.UserGrant {
|
|
return &user_pb.UserGrant{
|
|
Id: grant.ID,
|
|
UserId: grant.UserID,
|
|
State: UserGrantStateToPb(grant.State),
|
|
RoleKeys: grant.Roles,
|
|
ProjectId: grant.ProjectID,
|
|
OrgId: grant.ResourceOwner,
|
|
ProjectGrantId: grant.GrantID,
|
|
UserName: grant.Username,
|
|
FirstName: grant.FirstName,
|
|
LastName: grant.LastName,
|
|
Email: grant.Email,
|
|
DisplayName: grant.DisplayName,
|
|
OrgDomain: grant.OrgPrimaryDomain,
|
|
OrgName: grant.OrgName,
|
|
ProjectName: grant.ProjectName,
|
|
AvatarUrl: domain.AvatarURL(assetPrefix, grant.UserResourceOwner, grant.AvatarURL),
|
|
PreferredLoginName: grant.PreferredLoginName,
|
|
UserType: TypeToPb(grant.UserType),
|
|
GrantedOrgId: grant.GrantedOrgID,
|
|
GrantedOrgName: grant.GrantedOrgName,
|
|
GrantedOrgDomain: grant.GrantedOrgDomain,
|
|
Details: object.ToViewDetailsPb(
|
|
grant.Sequence,
|
|
grant.CreationDate,
|
|
grant.ChangeDate,
|
|
grant.ResourceOwner,
|
|
),
|
|
}
|
|
}
|
|
|
|
func UserGrantStateToPb(state domain.UserGrantState) user_pb.UserGrantState {
|
|
switch state {
|
|
case domain.UserGrantStateActive:
|
|
return user_pb.UserGrantState_USER_GRANT_STATE_ACTIVE
|
|
case domain.UserGrantStateInactive:
|
|
return user_pb.UserGrantState_USER_GRANT_STATE_INACTIVE
|
|
case domain.UserGrantStateRemoved,
|
|
domain.UserGrantStateUnspecified:
|
|
// these states should never occur here and are mainly listed for linting purposes
|
|
fallthrough
|
|
default:
|
|
return user_pb.UserGrantState_USER_GRANT_STATE_UNSPECIFIED
|
|
}
|
|
}
|
|
|
|
func UserGrantQueriesToQuery(ctx context.Context, queries []*user_pb.UserGrantQuery) (q []query.SearchQuery, err error) {
|
|
q = make([]query.SearchQuery, len(queries))
|
|
for i, query := range queries {
|
|
q[i], err = UserGrantQueryToQuery(ctx, query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return q, nil
|
|
}
|
|
|
|
func UserGrantQueryToQuery(ctx context.Context, query *user_pb.UserGrantQuery) (query.SearchQuery, error) {
|
|
switch q := query.Query.(type) {
|
|
case *user_pb.UserGrantQuery_DisplayNameQuery:
|
|
return UserGrantDisplayNameQueryToModel(q.DisplayNameQuery)
|
|
case *user_pb.UserGrantQuery_EmailQuery:
|
|
return UserGrantEmailQueryToModel(q.EmailQuery)
|
|
case *user_pb.UserGrantQuery_FirstNameQuery:
|
|
return UserGrantFirstNameQueryToModel(q.FirstNameQuery)
|
|
case *user_pb.UserGrantQuery_LastNameQuery:
|
|
return UserGrantLastNameQueryToModel(q.LastNameQuery)
|
|
case *user_pb.UserGrantQuery_OrgDomainQuery:
|
|
return UserGrantOrgDomainQueryToModel(q.OrgDomainQuery)
|
|
case *user_pb.UserGrantQuery_OrgNameQuery:
|
|
return UserGrantOrgNameQueryToModel(q.OrgNameQuery)
|
|
case *user_pb.UserGrantQuery_ProjectGrantIdQuery:
|
|
return UserGrantProjectGrantIDQueryToModel(q.ProjectGrantIdQuery)
|
|
case *user_pb.UserGrantQuery_ProjectIdQuery:
|
|
return UserGrantProjectIDQueryToModel(q.ProjectIdQuery)
|
|
case *user_pb.UserGrantQuery_ProjectNameQuery:
|
|
return UserGrantProjectNameQueryToModel(q.ProjectNameQuery)
|
|
case *user_pb.UserGrantQuery_RoleKeyQuery:
|
|
return UserGrantRoleKeyQueryToModel(q.RoleKeyQuery)
|
|
case *user_pb.UserGrantQuery_UserIdQuery:
|
|
return UserGrantUserIDQueryToModel(q.UserIdQuery)
|
|
case *user_pb.UserGrantQuery_UserNameQuery:
|
|
return UserGrantUserNameQueryToModel(q.UserNameQuery)
|
|
case *user_pb.UserGrantQuery_WithGrantedQuery:
|
|
return UserGrantWithGrantedQueryToModel(ctx, q.WithGrantedQuery)
|
|
case *user_pb.UserGrantQuery_UserTypeQuery:
|
|
return UserGrantUserTypeQueryToModel(q.UserTypeQuery)
|
|
default:
|
|
return nil, errors.New("invalid query")
|
|
}
|
|
}
|
|
|
|
func UserGrantDisplayNameQueryToModel(q *user_pb.UserGrantDisplayNameQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantDisplayNameQuery(q.DisplayName, object.TextMethodToQuery(q.Method))
|
|
}
|
|
|
|
func UserGrantEmailQueryToModel(q *user_pb.UserGrantEmailQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantEmailQuery(q.Email, object.TextMethodToQuery(q.Method))
|
|
}
|
|
|
|
func UserGrantFirstNameQueryToModel(q *user_pb.UserGrantFirstNameQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantFirstNameQuery(q.FirstName, object.TextMethodToQuery(q.Method))
|
|
}
|
|
|
|
func UserGrantLastNameQueryToModel(q *user_pb.UserGrantLastNameQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantLastNameQuery(q.LastName, object.TextMethodToQuery(q.Method))
|
|
}
|
|
|
|
func UserGrantOrgDomainQueryToModel(q *user_pb.UserGrantOrgDomainQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantDomainQuery(q.OrgDomain, object.TextMethodToQuery(q.Method))
|
|
}
|
|
|
|
func UserGrantOrgNameQueryToModel(q *user_pb.UserGrantOrgNameQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantOrgNameQuery(q.OrgName, object.TextMethodToQuery(q.Method))
|
|
}
|
|
|
|
func UserGrantProjectIDQueryToModel(q *user_pb.UserGrantProjectIDQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantProjectIDSearchQuery(q.ProjectId)
|
|
}
|
|
|
|
func UserGrantProjectGrantIDQueryToModel(q *user_pb.UserGrantProjectGrantIDQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantGrantIDSearchQuery(q.ProjectGrantId)
|
|
}
|
|
|
|
func UserGrantProjectNameQueryToModel(q *user_pb.UserGrantProjectNameQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantProjectNameQuery(q.ProjectName, object.TextMethodToQuery(q.Method))
|
|
}
|
|
|
|
func UserGrantRoleKeyQueryToModel(q *user_pb.UserGrantRoleKeyQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantRoleQuery(q.RoleKey)
|
|
}
|
|
|
|
func UserGrantUserIDQueryToModel(q *user_pb.UserGrantUserIDQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantUserIDSearchQuery(q.UserId)
|
|
}
|
|
|
|
func UserGrantUserNameQueryToModel(q *user_pb.UserGrantUserNameQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantUsernameQuery(q.UserName, object.TextMethodToQuery(q.Method))
|
|
}
|
|
|
|
func UserGrantWithGrantedQueryToModel(ctx context.Context, q *user_pb.UserGrantWithGrantedQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantWithGrantedQuery(authz.GetCtxData(ctx).OrgID)
|
|
}
|
|
|
|
func UserGrantUserTypeQueryToModel(q *user_pb.UserGrantUserTypeQuery) (query.SearchQuery, error) {
|
|
return query.NewUserGrantUserTypeQuery(grantTypeToDomain(q.Type))
|
|
}
|
|
|
|
func grantTypeToDomain(typ user_pb.Type) domain.UserType {
|
|
switch typ {
|
|
case user_pb.Type_TYPE_HUMAN:
|
|
return domain.UserTypeHuman
|
|
case user_pb.Type_TYPE_MACHINE:
|
|
return domain.UserTypeMachine
|
|
default:
|
|
return domain.UserTypeUnspecified
|
|
}
|
|
}
|