@@ -138,13 +138,13 @@ type Identity implements Node {
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
memberships(
|
||||
profiles(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: MembershipOrder
|
||||
): MembershipConnection @goField(forceResolver: true)
|
||||
orderBy: ProfileOrder
|
||||
): ProfileConnection @goField(forceResolver: true)
|
||||
|
||||
pendingInvitations(
|
||||
first: Int
|
||||
@@ -178,7 +178,7 @@ type Identity implements Node {
|
||||
@session(required: PRESENT)
|
||||
}
|
||||
|
||||
type MembershipProfile implements Node {
|
||||
type Profile implements Node {
|
||||
id: ID!
|
||||
fullName: String!
|
||||
additionalEmailAddresses: [EmailAddr!]!
|
||||
@@ -191,9 +191,7 @@ type MembershipProfile implements Node {
|
||||
|
||||
identity: Identity @goField(forceResolver: true)
|
||||
organization: Organization @goField(forceResolver: true)
|
||||
|
||||
# FIXME: remove when memberships are under profile
|
||||
membershipId: ID!
|
||||
membership: Membership @goField(forceResolver: true)
|
||||
|
||||
permission(action: String!): Boolean!
|
||||
@goField(forceResolver: true)
|
||||
@@ -212,13 +210,13 @@ type Organization implements Node {
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
members(
|
||||
profiles(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: MembershipOrder
|
||||
): MembershipConnection @goField(forceResolver: true)
|
||||
orderBy: ProfileOrder
|
||||
): ProfileConnection @goField(forceResolver: true)
|
||||
|
||||
invitations(
|
||||
first: Int
|
||||
@@ -238,7 +236,7 @@ type Organization implements Node {
|
||||
|
||||
scimConfiguration: SCIMConfiguration @goField(forceResolver: true)
|
||||
|
||||
viewerMembership: Membership @goField(forceResolver: true)
|
||||
viewer: Profile @goField(forceResolver: true)
|
||||
|
||||
permission(action: String!): Boolean!
|
||||
@goField(forceResolver: true)
|
||||
@@ -285,9 +283,6 @@ enum MembershipState
|
||||
type Membership implements Node {
|
||||
id: ID!
|
||||
createdAt: Datetime!
|
||||
identity: Identity @goField(forceResolver: true)
|
||||
profile: MembershipProfile @goField(forceResolver: true)
|
||||
organization: Organization @goField(forceResolver: true)
|
||||
role: MembershipRole!
|
||||
source: MembershipSource!
|
||||
state: MembershipState!
|
||||
@@ -445,7 +440,7 @@ type SCIMEvent implements Node {
|
||||
requestBody: String
|
||||
responseBody: String
|
||||
errorMessage: String
|
||||
membership: Membership @goField(forceResolver: true)
|
||||
profile: Profile @goField(forceResolver: true)
|
||||
ipAddress: String!
|
||||
createdAt: Datetime!
|
||||
|
||||
@@ -483,50 +478,6 @@ enum ReauthenticationReason {
|
||||
POLICY_REQUIREMENT
|
||||
}
|
||||
|
||||
enum MembershipOrderField
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.MembershipOrderField") {
|
||||
FULL_NAME
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.MembershipOrderFieldFullName"
|
||||
)
|
||||
ORGANIZATION_NAME
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.MembershipOrderFieldOrganizationName"
|
||||
)
|
||||
EMAIL_ADDRESS
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.MembershipOrderFieldEmailAddress"
|
||||
)
|
||||
ROLE
|
||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.MembershipOrderFieldRole")
|
||||
CREATED_AT
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.MembershipOrderFieldCreatedAt"
|
||||
)
|
||||
}
|
||||
|
||||
input MembershipOrder
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/connect/v1/types.MembershipOrderBy"
|
||||
) {
|
||||
direction: OrderDirection!
|
||||
field: MembershipOrderField!
|
||||
}
|
||||
|
||||
type MembershipConnection
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/connect/v1/types.MembershipConnection"
|
||||
) {
|
||||
edges: [MembershipEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
totalCount: Int @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type MembershipEdge {
|
||||
node: Membership!
|
||||
cursor: CursorKey!
|
||||
}
|
||||
|
||||
enum InvitationOrderField
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.InvitationOrderField") {
|
||||
FULL_NAME
|
||||
@@ -573,6 +524,45 @@ type InvitationEdge {
|
||||
cursor: CursorKey!
|
||||
}
|
||||
|
||||
enum ProfileOrderField
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.MembershipProfileOrderField") {
|
||||
FULL_NAME
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.MembershipProfileOrderFieldFullName"
|
||||
)
|
||||
CREATED_AT
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.MembershipProfileOrderFieldCreatedAt"
|
||||
)
|
||||
KIND @goEnum(value: "go.probo.inc/probo/pkg/coredata.MembershipProfileOrderFieldKind")
|
||||
ORGANIZATION_NAME
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.MembershipProfileOrderFieldOrganizationName"
|
||||
)
|
||||
}
|
||||
|
||||
input ProfileOrder
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/connect/v1/types.ProfileOrderBy"
|
||||
) {
|
||||
direction: OrderDirection!
|
||||
field: ProfileOrderField!
|
||||
}
|
||||
|
||||
type ProfileConnection
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/connect/v1/types.ProfileConnection"
|
||||
) {
|
||||
totalCount: Int @goField(forceResolver: true)
|
||||
edges: [ProfileEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type ProfileEdge {
|
||||
cursor: CursorKey!
|
||||
node: Profile!
|
||||
}
|
||||
|
||||
type SessionConnection
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/connect/v1/types.SessionConnection"
|
||||
@@ -885,7 +875,7 @@ type RevokePersonalAPIKeyPayload {
|
||||
|
||||
type CreateOrganizationPayload {
|
||||
organization: Organization
|
||||
membershipEdge: MembershipEdge!
|
||||
membership: Membership!
|
||||
}
|
||||
|
||||
type UpdateOrganizationPayload {
|
||||
@@ -905,7 +895,7 @@ type InviteMemberPayload {
|
||||
}
|
||||
|
||||
type UpdateProfilePayload {
|
||||
profile: MembershipProfile!
|
||||
profile: Profile!
|
||||
}
|
||||
|
||||
type UpdateMembershipPayload {
|
||||
@@ -917,7 +907,7 @@ type RemoveMemberPayload {
|
||||
}
|
||||
|
||||
type AcceptInvitationPayload {
|
||||
membershipEdge: MembershipEdge!
|
||||
membership: Membership!
|
||||
invitation: Invitation!
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,61 +16,14 @@ package types
|
||||
|
||||
import (
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
MembershipOrderBy OrderBy[coredata.MembershipOrderField]
|
||||
|
||||
MembershipConnection struct {
|
||||
TotalCount int
|
||||
Edges []*MembershipEdge
|
||||
PageInfo PageInfo
|
||||
|
||||
Resolver any
|
||||
ParentID gid.GID
|
||||
}
|
||||
)
|
||||
|
||||
func NewMembershipConnection(
|
||||
p *page.Page[*coredata.Membership, coredata.MembershipOrderField],
|
||||
resolver any,
|
||||
parentID gid.GID,
|
||||
) *MembershipConnection {
|
||||
edges := make([]*MembershipEdge, len(p.Data))
|
||||
for i, membership := range p.Data {
|
||||
edges[i] = NewMembershipEdge(membership, p.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &MembershipConnection{
|
||||
Edges: edges,
|
||||
PageInfo: *NewPageInfo(p),
|
||||
|
||||
Resolver: resolver,
|
||||
ParentID: parentID,
|
||||
}
|
||||
}
|
||||
|
||||
func NewMembershipEdge(membership *coredata.Membership, orderField coredata.MembershipOrderField) *MembershipEdge {
|
||||
return &MembershipEdge{
|
||||
Node: NewMembership(membership),
|
||||
Cursor: membership.CursorKey(orderField),
|
||||
}
|
||||
}
|
||||
|
||||
func NewMembership(membership *coredata.Membership) *Membership {
|
||||
return &Membership{
|
||||
ID: membership.ID,
|
||||
CreatedAt: membership.CreatedAt,
|
||||
Identity: &Identity{
|
||||
ID: membership.IdentityID,
|
||||
},
|
||||
Organization: &Organization{
|
||||
ID: membership.OrganizationID,
|
||||
},
|
||||
Role: membership.Role,
|
||||
Source: membership.Source,
|
||||
State: membership.State,
|
||||
Role: membership.Role,
|
||||
Source: membership.Source,
|
||||
State: membership.State,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,56 @@
|
||||
|
||||
package types
|
||||
|
||||
import "go.probo.inc/probo/pkg/coredata"
|
||||
import (
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
func NewMembershipProfile(profile *coredata.MembershipProfile) *MembershipProfile {
|
||||
return &MembershipProfile{
|
||||
type (
|
||||
ProfileOrderBy OrderBy[coredata.MembershipProfileOrderField]
|
||||
|
||||
ProfileConnection struct {
|
||||
TotalCount int
|
||||
Edges []*ProfileEdge
|
||||
PageInfo PageInfo
|
||||
|
||||
Resolver any
|
||||
ParentID gid.GID
|
||||
}
|
||||
)
|
||||
|
||||
func NewProfileConnection(
|
||||
p *page.Page[*coredata.MembershipProfile, coredata.MembershipProfileOrderField],
|
||||
resolver any,
|
||||
parentID gid.GID,
|
||||
) *ProfileConnection {
|
||||
edges := make([]*ProfileEdge, len(p.Data))
|
||||
for i, profile := range p.Data {
|
||||
edges[i] = NewProfileEdge(profile, p.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &ProfileConnection{
|
||||
Edges: edges,
|
||||
PageInfo: *NewPageInfo(p),
|
||||
|
||||
Resolver: resolver,
|
||||
ParentID: parentID,
|
||||
}
|
||||
}
|
||||
|
||||
func NewProfileEdge(
|
||||
profile *coredata.MembershipProfile,
|
||||
orderField coredata.MembershipProfileOrderField,
|
||||
) *ProfileEdge {
|
||||
return &ProfileEdge{
|
||||
Node: NewProfile(profile),
|
||||
Cursor: profile.CursorKey(orderField),
|
||||
}
|
||||
}
|
||||
|
||||
func NewProfile(profile *coredata.MembershipProfile) *Profile {
|
||||
return &Profile{
|
||||
ID: profile.ID,
|
||||
FullName: profile.FullName,
|
||||
AdditionalEmailAddresses: profile.AdditionalEmailAddresses,
|
||||
@@ -72,11 +72,12 @@ func NewSCIMEvent(scimEvent *coredata.SCIMEvent) *SCIMEvent {
|
||||
CreatedAt: scimEvent.CreatedAt,
|
||||
}
|
||||
|
||||
if scimEvent.MembershipID != nil {
|
||||
event.Membership = &Membership{
|
||||
ID: *scimEvent.MembershipID,
|
||||
}
|
||||
}
|
||||
// FIXME: profile
|
||||
// if scimEvent.MembershipID != nil {
|
||||
// event.Membership = &Membership{
|
||||
// ID: *scimEvent.MembershipID,
|
||||
// }
|
||||
// }
|
||||
|
||||
return event
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ type AcceptInvitationInput struct {
|
||||
}
|
||||
|
||||
type AcceptInvitationPayload struct {
|
||||
MembershipEdge *MembershipEdge `json:"membershipEdge"`
|
||||
Invitation *Invitation `json:"invitation"`
|
||||
Membership *Membership `json:"membership"`
|
||||
Invitation *Invitation `json:"invitation"`
|
||||
}
|
||||
|
||||
type AssumeOrganizationSessionInput struct {
|
||||
@@ -79,8 +79,8 @@ type CreateOrganizationInput struct {
|
||||
}
|
||||
|
||||
type CreateOrganizationPayload struct {
|
||||
Organization *Organization `json:"organization,omitempty"`
|
||||
MembershipEdge *MembershipEdge `json:"membershipEdge"`
|
||||
Organization *Organization `json:"organization,omitempty"`
|
||||
Membership *Membership `json:"membership"`
|
||||
}
|
||||
|
||||
type CreatePersonalAPIKeyInput struct {
|
||||
@@ -176,7 +176,7 @@ type Identity struct {
|
||||
EmailVerified bool `json:"emailVerified"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
Memberships *MembershipConnection `json:"memberships,omitempty"`
|
||||
Profiles *ProfileConnection `json:"profiles,omitempty"`
|
||||
PendingInvitations *InvitationConnection `json:"pendingInvitations,omitempty"`
|
||||
Sessions *SessionConnection `json:"sessions,omitempty"`
|
||||
PersonalAPIKeys *PersonalAPIKeyConnection `json:"personalAPIKeys,omitempty"`
|
||||
@@ -220,45 +220,18 @@ type InviteMemberPayload struct {
|
||||
}
|
||||
|
||||
type Membership struct {
|
||||
ID gid.GID `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Identity *Identity `json:"identity,omitempty"`
|
||||
Profile *MembershipProfile `json:"profile,omitempty"`
|
||||
Organization *Organization `json:"organization,omitempty"`
|
||||
Role coredata.MembershipRole `json:"role"`
|
||||
Source coredata.MembershipSource `json:"source"`
|
||||
State coredata.MembershipState `json:"state"`
|
||||
LastSession *Session `json:"lastSession,omitempty"`
|
||||
Permission bool `json:"permission"`
|
||||
ID gid.GID `json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Role coredata.MembershipRole `json:"role"`
|
||||
Source coredata.MembershipSource `json:"source"`
|
||||
State coredata.MembershipState `json:"state"`
|
||||
LastSession *Session `json:"lastSession,omitempty"`
|
||||
Permission bool `json:"permission"`
|
||||
}
|
||||
|
||||
func (Membership) IsNode() {}
|
||||
func (this Membership) GetID() gid.GID { return this.ID }
|
||||
|
||||
type MembershipEdge struct {
|
||||
Node *Membership `json:"node"`
|
||||
Cursor page.CursorKey `json:"cursor"`
|
||||
}
|
||||
|
||||
type MembershipProfile struct {
|
||||
ID gid.GID `json:"id"`
|
||||
FullName string `json:"fullName"`
|
||||
AdditionalEmailAddresses []mail.Addr `json:"additionalEmailAddresses"`
|
||||
Kind coredata.MembershipProfileKind `json:"kind"`
|
||||
Position *string `json:"position,omitempty"`
|
||||
ContractStartDate *time.Time `json:"contractStartDate,omitempty"`
|
||||
ContractEndDate *time.Time `json:"contractEndDate,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
Identity *Identity `json:"identity,omitempty"`
|
||||
Organization *Organization `json:"organization,omitempty"`
|
||||
MembershipID gid.GID `json:"membershipId"`
|
||||
Permission bool `json:"permission"`
|
||||
}
|
||||
|
||||
func (MembershipProfile) IsNode() {}
|
||||
func (this MembershipProfile) GetID() gid.GID { return this.ID }
|
||||
|
||||
type Mutation struct {
|
||||
}
|
||||
|
||||
@@ -273,11 +246,11 @@ type Organization struct {
|
||||
HeadquarterAddress *string `json:"headquarterAddress,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
Members *MembershipConnection `json:"members,omitempty"`
|
||||
Profiles *ProfileConnection `json:"profiles,omitempty"`
|
||||
Invitations *InvitationConnection `json:"invitations,omitempty"`
|
||||
SamlConfigurations *SAMLConfigurationConnection `json:"samlConfigurations,omitempty"`
|
||||
ScimConfiguration *SCIMConfiguration `json:"scimConfiguration,omitempty"`
|
||||
ViewerMembership *Membership `json:"viewerMembership,omitempty"`
|
||||
Viewer *Profile `json:"viewer,omitempty"`
|
||||
Permission bool `json:"permission"`
|
||||
}
|
||||
|
||||
@@ -322,6 +295,30 @@ type PersonalAPIKeyEdge struct {
|
||||
Cursor page.CursorKey `json:"cursor"`
|
||||
}
|
||||
|
||||
type Profile struct {
|
||||
ID gid.GID `json:"id"`
|
||||
FullName string `json:"fullName"`
|
||||
AdditionalEmailAddresses []mail.Addr `json:"additionalEmailAddresses"`
|
||||
Kind coredata.MembershipProfileKind `json:"kind"`
|
||||
Position *string `json:"position,omitempty"`
|
||||
ContractStartDate *time.Time `json:"contractStartDate,omitempty"`
|
||||
ContractEndDate *time.Time `json:"contractEndDate,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
Identity *Identity `json:"identity,omitempty"`
|
||||
Organization *Organization `json:"organization,omitempty"`
|
||||
Membership *Membership `json:"membership,omitempty"`
|
||||
Permission bool `json:"permission"`
|
||||
}
|
||||
|
||||
func (Profile) IsNode() {}
|
||||
func (this Profile) GetID() gid.GID { return this.ID }
|
||||
|
||||
type ProfileEdge struct {
|
||||
Cursor page.CursorKey `json:"cursor"`
|
||||
Node *Profile `json:"node"`
|
||||
}
|
||||
|
||||
type Query struct {
|
||||
}
|
||||
|
||||
@@ -448,17 +445,17 @@ func (SCIMConfiguration) IsNode() {}
|
||||
func (this SCIMConfiguration) GetID() gid.GID { return this.ID }
|
||||
|
||||
type SCIMEvent struct {
|
||||
ID gid.GID `json:"id"`
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
StatusCode int `json:"statusCode"`
|
||||
RequestBody *string `json:"requestBody,omitempty"`
|
||||
ResponseBody *string `json:"responseBody,omitempty"`
|
||||
ErrorMessage *string `json:"errorMessage,omitempty"`
|
||||
Membership *Membership `json:"membership,omitempty"`
|
||||
IPAddress string `json:"ipAddress"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Permission bool `json:"permission"`
|
||||
ID gid.GID `json:"id"`
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
StatusCode int `json:"statusCode"`
|
||||
RequestBody *string `json:"requestBody,omitempty"`
|
||||
ResponseBody *string `json:"responseBody,omitempty"`
|
||||
ErrorMessage *string `json:"errorMessage,omitempty"`
|
||||
Profile *Profile `json:"profile,omitempty"`
|
||||
IPAddress string `json:"ipAddress"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
Permission bool `json:"permission"`
|
||||
}
|
||||
|
||||
func (SCIMEvent) IsNode() {}
|
||||
@@ -564,7 +561,7 @@ type UpdateProfileInput struct {
|
||||
}
|
||||
|
||||
type UpdateProfilePayload struct {
|
||||
Profile *MembershipProfile `json:"profile"`
|
||||
Profile *Profile `json:"profile"`
|
||||
}
|
||||
|
||||
type UpdateSAMLConfigurationInput struct {
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"go.probo.inc/probo/pkg/server/api/authz"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/api/connect/v1/types"
|
||||
types1 "go.probo.inc/probo/pkg/server/api/console/v1/types"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils/types/cursor"
|
||||
)
|
||||
@@ -32,39 +33,9 @@ func (r *connectorResolver) Permission(ctx context.Context, obj *types.Connector
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// Memberships is the resolver for the memberships field.
|
||||
func (r *identityResolver) Memberships(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MembershipOrderBy) (*types.MembershipConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.MembershipConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.MembershipOrderField]{
|
||||
Field: coredata.MembershipOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.MembershipOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.AccountService.ListMemberships(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list memberships", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewMembershipConnection(page, r, obj.ID), nil
|
||||
// Profiles is the resolver for the profiles field.
|
||||
func (r *identityResolver) Profiles(ctx context.Context, obj *types.Identity, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types1.ProfileOrderBy) (*types1.ProfileConnection, error) {
|
||||
panic(fmt.Errorf("not implemented: Profiles - profiles"))
|
||||
}
|
||||
|
||||
// PendingInvitations is the resolver for the pendingInvitations field.
|
||||
@@ -267,73 +238,6 @@ func (r *invitationConnectionResolver) TotalCount(ctx context.Context, obj *type
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
// Identity is the resolver for the identity field.
|
||||
func (r *membershipResolver) Identity(ctx context.Context, obj *types.Membership) (*types.Identity, error) {
|
||||
if err := r.authorize(
|
||||
ctx,
|
||||
obj.Identity.ID,
|
||||
iam.ActionIdentityGet,
|
||||
authz.WithAttr("organization_id", obj.Organization.ID.String()),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyIDSelected(ctx) {
|
||||
return &types.Identity{
|
||||
ID: obj.Identity.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
identity, err := r.iam.AccountService.GetIdentityForMembership(ctx, obj.ID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot get identity for membership", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewIdentity(identity), nil
|
||||
}
|
||||
|
||||
// Profile is the resolver for the profile field.
|
||||
func (r *membershipResolver) Profile(ctx context.Context, obj *types.Membership) (*types.MembershipProfile, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet, authz.WithSkipAssumptionCheck()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
profile, err := r.iam.AccountService.GetProfileForMembership(ctx, obj.ID)
|
||||
if err != nil {
|
||||
var errProfileNotFound *iam.ErrProfileNotFound
|
||||
if errors.As(err, &errProfileNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot get profile for membership", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewMembershipProfile(profile), nil
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *membershipResolver) Organization(ctx context.Context, obj *types.Membership) (*types.Organization, error) {
|
||||
if err := r.authorize(ctx, obj.Organization.ID, iam.ActionOrganizationGet, authz.WithSkipAssumptionCheck()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyIDSelected(ctx) {
|
||||
return &types.Organization{
|
||||
ID: obj.Organization.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
organization, err := r.iam.OrganizationService.GetOrganizationForMembership(ctx, obj.ID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot get organization for membership", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewOrganization(organization), nil
|
||||
}
|
||||
|
||||
// LastSession is the resolver for the lastSession field.
|
||||
func (r *membershipResolver) LastSession(ctx context.Context, obj *types.Membership) (*types.Session, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipGet, authz.WithSkipAssumptionCheck()); err != nil {
|
||||
@@ -364,87 +268,6 @@ func (r *membershipResolver) Permission(ctx context.Context, obj *types.Membersh
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// TotalCount is the resolver for the totalCount field.
|
||||
func (r *membershipConnectionResolver) TotalCount(ctx context.Context, obj *types.MembershipConnection) (*int, error) {
|
||||
if err := r.authorize(ctx, obj.ParentID, iam.ActionMembershipList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch obj.Resolver.(type) {
|
||||
case *identityResolver:
|
||||
count, err := r.iam.AccountService.CountMemberships(ctx, obj.ParentID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot count memberships", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &count, nil
|
||||
case *organizationResolver:
|
||||
count, err := r.iam.OrganizationService.CountMemberships(ctx, obj.ParentID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot count memberships", 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)
|
||||
}
|
||||
|
||||
// Identity is the resolver for the identity field.
|
||||
func (r *membershipProfileResolver) Identity(ctx context.Context, obj *types.MembershipProfile) (*types.Identity, error) {
|
||||
if err := r.authorize(
|
||||
ctx,
|
||||
obj.Identity.ID,
|
||||
iam.ActionIdentityGet,
|
||||
authz.WithAttr("organization_id", obj.Organization.ID.String()),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyIDSelected(ctx) {
|
||||
return &types.Identity{
|
||||
ID: obj.Identity.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
identity, err := r.iam.AccountService.GetIdentity(ctx, obj.Identity.ID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot get identity for membership", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewIdentity(identity), nil
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *membershipProfileResolver) Organization(ctx context.Context, obj *types.MembershipProfile) (*types.Organization, error) {
|
||||
if err := r.authorize(ctx, obj.Organization.ID, iam.ActionOrganizationGet, authz.WithSkipAssumptionCheck()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyIDSelected(ctx) {
|
||||
return &types.Organization{
|
||||
ID: obj.Organization.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
organization, err := r.iam.OrganizationService.GetOrganizationForMembership(ctx, obj.ID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot get organization for membership", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewOrganization(organization), nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *membershipProfileResolver) Permission(ctx context.Context, obj *types.MembershipProfile, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// SignIn is the resolver for the signIn field.
|
||||
func (r *mutationResolver) SignIn(ctx context.Context, input types.SignInInput) (*types.SignInPayload, error) {
|
||||
identity, err := r.iam.AuthService.CheckCredentials(ctx, input.Email, input.Password)
|
||||
@@ -938,8 +761,8 @@ func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.C
|
||||
}
|
||||
|
||||
return &types.CreateOrganizationPayload{
|
||||
Organization: types.NewOrganization(organization),
|
||||
MembershipEdge: types.NewMembershipEdge(membership, coredata.MembershipOrderFieldCreatedAt),
|
||||
Organization: types.NewOrganization(organization),
|
||||
Membership: types.NewMembership(membership),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1105,7 +928,7 @@ func (r *mutationResolver) UpdateProfile(ctx context.Context, input types.Update
|
||||
}
|
||||
|
||||
return &types.UpdateProfilePayload{
|
||||
Profile: types.NewMembershipProfile(profile),
|
||||
Profile: types.NewProfile(profile),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1173,8 +996,8 @@ func (r *mutationResolver) AcceptInvitation(ctx context.Context, input types.Acc
|
||||
}
|
||||
|
||||
return &types.AcceptInvitationPayload{
|
||||
MembershipEdge: types.NewMembershipEdge(membership, coredata.MembershipOrderFieldCreatedAt),
|
||||
Invitation: types.NewInvitation(invitation),
|
||||
Membership: types.NewMembership(membership),
|
||||
Invitation: types.NewInvitation(invitation),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1387,37 +1210,9 @@ func (r *organizationResolver) HorizontalLogoURL(ctx context.Context, obj *types
|
||||
return presignedURL, nil
|
||||
}
|
||||
|
||||
// Members is the resolver for the members field.
|
||||
func (r *organizationResolver) Members(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.MembershipOrderBy) (*types.MembershipConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if gqlutils.OnlyTotalCountSelected(ctx) {
|
||||
return &types.MembershipConnection{
|
||||
Resolver: r,
|
||||
ParentID: obj.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.MembershipOrderField]{
|
||||
Field: coredata.MembershipOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy.Field = coredata.MembershipOrderField(orderBy.Field)
|
||||
pageOrderBy.Direction = page.OrderDirection(orderBy.Direction)
|
||||
}
|
||||
|
||||
cursor := cursor.NewCursor(first, after, last, before, pageOrderBy)
|
||||
|
||||
page, err := r.iam.OrganizationService.ListMembers(ctx, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list memberships", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return types.NewMembershipConnection(page, r, obj.ID), nil
|
||||
// Profiles is the resolver for the profiles field.
|
||||
func (r *organizationResolver) Profiles(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types1.ProfileOrderBy) (*types1.ProfileConnection, error) {
|
||||
panic(fmt.Errorf("not implemented: Profiles - profiles"))
|
||||
}
|
||||
|
||||
// Invitations is the resolver for the invitations field.
|
||||
@@ -1575,6 +1370,41 @@ func (r *personalAPIKeyConnectionResolver) TotalCount(ctx context.Context, obj *
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
// Identity is the resolver for the identity field.
|
||||
func (r *profileResolver) Identity(ctx context.Context, obj *types.Profile) (*types.Identity, error) {
|
||||
panic(fmt.Errorf("not implemented: Identity - identity"))
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *profileResolver) Organization(ctx context.Context, obj *types.Profile) (*types.Organization, error) {
|
||||
panic(fmt.Errorf("not implemented: Organization - organization"))
|
||||
}
|
||||
|
||||
// Membership is the resolver for the membership field.
|
||||
func (r *profileResolver) Membership(ctx context.Context, obj *types.Profile) (*types.Membership, error) {
|
||||
panic(fmt.Errorf("not implemented: Membership - membership"))
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *profileResolver) Permission(ctx context.Context, obj *types.Profile, action string) (bool, error) {
|
||||
panic(fmt.Errorf("not implemented: Permission - permission"))
|
||||
}
|
||||
|
||||
// TotalCount is the resolver for the totalCount field.
|
||||
func (r *profileConnectionResolver) TotalCount(ctx context.Context, obj *types1.ProfileConnection) (int, error) {
|
||||
panic(fmt.Errorf("not implemented: TotalCount - totalCount"))
|
||||
}
|
||||
|
||||
// Edges is the resolver for the edges field.
|
||||
func (r *profileConnectionResolver) Edges(ctx context.Context, obj *types1.ProfileConnection) ([]*types.ProfileEdge, error) {
|
||||
panic(fmt.Errorf("not implemented: Edges - edges"))
|
||||
}
|
||||
|
||||
// PageInfo is the resolver for the pageInfo field.
|
||||
func (r *profileConnectionResolver) PageInfo(ctx context.Context, obj *types1.ProfileConnection) (*types.PageInfo, error) {
|
||||
panic(fmt.Errorf("not implemented: PageInfo - pageInfo"))
|
||||
}
|
||||
|
||||
// Node is the resolver for the node field.
|
||||
func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error) {
|
||||
var (
|
||||
@@ -1620,7 +1450,7 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return types.NewMembershipProfile(profile), nil
|
||||
return types.NewProfile(profile), nil
|
||||
}
|
||||
case coredata.MembershipEntityType:
|
||||
action = iam.ActionMembershipGet
|
||||
@@ -2042,16 +1872,6 @@ func (r *Resolver) InvitationConnection() schema.InvitationConnectionResolver {
|
||||
// Membership returns schema.MembershipResolver implementation.
|
||||
func (r *Resolver) Membership() schema.MembershipResolver { return &membershipResolver{r} }
|
||||
|
||||
// MembershipConnection returns schema.MembershipConnectionResolver implementation.
|
||||
func (r *Resolver) MembershipConnection() schema.MembershipConnectionResolver {
|
||||
return &membershipConnectionResolver{r}
|
||||
}
|
||||
|
||||
// MembershipProfile returns schema.MembershipProfileResolver implementation.
|
||||
func (r *Resolver) MembershipProfile() schema.MembershipProfileResolver {
|
||||
return &membershipProfileResolver{r}
|
||||
}
|
||||
|
||||
// Mutation returns schema.MutationResolver implementation.
|
||||
func (r *Resolver) Mutation() schema.MutationResolver { return &mutationResolver{r} }
|
||||
|
||||
@@ -2066,6 +1886,14 @@ func (r *Resolver) PersonalAPIKeyConnection() schema.PersonalAPIKeyConnectionRes
|
||||
return &personalAPIKeyConnectionResolver{r}
|
||||
}
|
||||
|
||||
// Profile returns schema.ProfileResolver implementation.
|
||||
func (r *Resolver) Profile() schema.ProfileResolver { return &profileResolver{r} }
|
||||
|
||||
// ProfileConnection returns schema.ProfileConnectionResolver implementation.
|
||||
func (r *Resolver) ProfileConnection() schema.ProfileConnectionResolver {
|
||||
return &profileConnectionResolver{r}
|
||||
}
|
||||
|
||||
// Query returns schema.QueryResolver implementation.
|
||||
func (r *Resolver) Query() schema.QueryResolver { return &queryResolver{r} }
|
||||
|
||||
@@ -2108,12 +1936,12 @@ type identityResolver struct{ *Resolver }
|
||||
type invitationResolver struct{ *Resolver }
|
||||
type invitationConnectionResolver struct{ *Resolver }
|
||||
type membershipResolver struct{ *Resolver }
|
||||
type membershipConnectionResolver struct{ *Resolver }
|
||||
type membershipProfileResolver struct{ *Resolver }
|
||||
type mutationResolver struct{ *Resolver }
|
||||
type organizationResolver struct{ *Resolver }
|
||||
type personalAPIKeyResolver struct{ *Resolver }
|
||||
type personalAPIKeyConnectionResolver struct{ *Resolver }
|
||||
type profileResolver struct{ *Resolver }
|
||||
type profileConnectionResolver struct{ *Resolver }
|
||||
type queryResolver struct{ *Resolver }
|
||||
type sAMLConfigurationResolver struct{ *Resolver }
|
||||
type sAMLConfigurationConnectionResolver struct{ *Resolver }
|
||||
|
||||
Reference in New Issue
Block a user