@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<1a9ee1bf35493db9d5edbbd07f917ff5>>
|
* @generated SignedSource<<d9ec1da794fdbe09fbffc7ed32d22707>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -229,6 +229,13 @@ return {
|
|||||||
"name": "role",
|
"name": "role",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "source",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
@@ -389,12 +396,12 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "7d90790bce5773e286196cec19c376c9",
|
"cacheID": "bdedd349fa3a3dec43d7cb6171d1cc6d",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "MemberListFragment_RefetchQuery",
|
"name": "MemberListFragment_RefetchQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query MemberListFragment_RefetchQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 20\n $last: Int = null\n $order: MembershipOrder = {direction: ASC, field: CREATED_AT}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...MemberListFragment_16fISc\n id\n }\n}\n\nfragment MemberListFragment_16fISc on Organization {\n members(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n totalCount\n edges {\n node {\n id\n ...MemberListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment MemberListItemFragment on Membership {\n id\n role\n profile {\n fullName\n id\n }\n identity {\n email\n id\n }\n createdAt\n canUpdate: permission(action: \"iam:membership:update\")\n canDelete: permission(action: \"iam:membership:delete\")\n}\n"
|
"text": "query MemberListFragment_RefetchQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 20\n $last: Int = null\n $order: MembershipOrder = {direction: ASC, field: CREATED_AT}\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...MemberListFragment_16fISc\n id\n }\n}\n\nfragment MemberListFragment_16fISc on Organization {\n members(first: $first, after: $after, last: $last, before: $before, orderBy: $order) {\n totalCount\n edges {\n node {\n id\n ...MemberListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment MemberListItemFragment on Membership {\n id\n role\n source\n profile {\n fullName\n id\n }\n identity {\n email\n id\n }\n createdAt\n canUpdate: permission(action: \"iam:membership:update\")\n canDelete: permission(action: \"iam:membership:delete\")\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<a6bd5e4c2270a79d2e4ab1a56c0f9e12>>
|
* @generated SignedSource<<8ffe3696f618050456f80b7a7098a882>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
import { ReaderFragment } from 'relay-runtime';
|
import { ReaderFragment } from 'relay-runtime';
|
||||||
export type MembershipRole = "ADMIN" | "AUDITOR" | "EMPLOYEE" | "OWNER" | "VIEWER";
|
export type MembershipRole = "ADMIN" | "AUDITOR" | "EMPLOYEE" | "OWNER" | "VIEWER";
|
||||||
|
export type MembershipSource = "MANUAL" | "SAML";
|
||||||
import { FragmentRefs } from "relay-runtime";
|
import { FragmentRefs } from "relay-runtime";
|
||||||
export type MemberListItemFragment$data = {
|
export type MemberListItemFragment$data = {
|
||||||
readonly canDelete: boolean;
|
readonly canDelete: boolean;
|
||||||
@@ -23,6 +24,7 @@ export type MemberListItemFragment$data = {
|
|||||||
readonly fullName: string;
|
readonly fullName: string;
|
||||||
};
|
};
|
||||||
readonly role: MembershipRole;
|
readonly role: MembershipRole;
|
||||||
|
readonly source: MembershipSource;
|
||||||
readonly " $fragmentType": "MemberListItemFragment";
|
readonly " $fragmentType": "MemberListItemFragment";
|
||||||
};
|
};
|
||||||
export type MemberListItemFragment$key = {
|
export type MemberListItemFragment$key = {
|
||||||
@@ -50,6 +52,13 @@ const node: ReaderFragment = {
|
|||||||
"name": "role",
|
"name": "role",
|
||||||
"storageKey": null
|
"storageKey": null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "source",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"kind": "RequiredField",
|
"kind": "RequiredField",
|
||||||
"field": {
|
"field": {
|
||||||
@@ -132,6 +141,6 @@ const node: ReaderFragment = {
|
|||||||
"abstractKey": null
|
"abstractKey": null
|
||||||
};
|
};
|
||||||
|
|
||||||
(node as any).hash = "a7adb3da099816d296abd56c0b8dde16";
|
(node as any).hash = "573655b969ddacac10dc8beb4585a4a1";
|
||||||
|
|
||||||
export default node;
|
export default node;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @generated SignedSource<<3ba2ace33d45535d6c6981f283be9643>>
|
* @generated SignedSource<<0f7c89bd92b5743593efd542812568a7>>
|
||||||
* @lightSyntaxTransform
|
* @lightSyntaxTransform
|
||||||
* @nogrep
|
* @nogrep
|
||||||
*/
|
*/
|
||||||
@@ -335,6 +335,13 @@ return {
|
|||||||
"selections": [
|
"selections": [
|
||||||
(v10/*: any*/),
|
(v10/*: any*/),
|
||||||
(v11/*: any*/),
|
(v11/*: any*/),
|
||||||
|
{
|
||||||
|
"alias": null,
|
||||||
|
"args": null,
|
||||||
|
"kind": "ScalarField",
|
||||||
|
"name": "source",
|
||||||
|
"storageKey": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"args": null,
|
"args": null,
|
||||||
@@ -509,12 +516,12 @@ return {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"params": {
|
"params": {
|
||||||
"cacheID": "a5ff95870e5a269d1b03a123a459678e",
|
"cacheID": "b7d449bd737c6165219640affcc0260a",
|
||||||
"id": null,
|
"id": null,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"name": "MembersPageQuery",
|
"name": "MembersPageQuery",
|
||||||
"operationKind": "query",
|
"operationKind": "query",
|
||||||
"text": "query MembersPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...InviteUserDialog_currentRoleFragment\n ...MemberListFragment_1jRT0c\n members(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n }\n ...InvitationListFragment_1jRT0c\n invitations(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n }\n canInviteUser: permission(action: \"iam:invitation:create\")\n }\n id\n }\n}\n\nfragment InvitationListFragment_1jRT0c on Organization {\n invitations(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n edges {\n node {\n id\n ...InvitationListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment InvitationListItemFragment on Invitation {\n id\n fullName\n email\n role\n status\n createdAt\n expiresAt\n acceptedAt\n canDelete: permission(action: \"iam:invitation:delete\")\n}\n\nfragment InviteUserDialog_currentRoleFragment on Organization {\n viewerMembership {\n role\n id\n }\n}\n\nfragment MemberListFragment_1jRT0c on Organization {\n members(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n edges {\n node {\n id\n ...MemberListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment MemberListItemFragment on Membership {\n id\n role\n profile {\n fullName\n id\n }\n identity {\n email\n id\n }\n createdAt\n canUpdate: permission(action: \"iam:membership:update\")\n canDelete: permission(action: \"iam:membership:delete\")\n}\n"
|
"text": "query MembersPageQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n ...InviteUserDialog_currentRoleFragment\n ...MemberListFragment_1jRT0c\n members(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n }\n ...InvitationListFragment_1jRT0c\n invitations(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n }\n canInviteUser: permission(action: \"iam:invitation:create\")\n }\n id\n }\n}\n\nfragment InvitationListFragment_1jRT0c on Organization {\n invitations(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n edges {\n node {\n id\n ...InvitationListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment InvitationListItemFragment on Invitation {\n id\n fullName\n email\n role\n status\n createdAt\n expiresAt\n acceptedAt\n canDelete: permission(action: \"iam:invitation:delete\")\n}\n\nfragment InviteUserDialog_currentRoleFragment on Organization {\n viewerMembership {\n role\n id\n }\n}\n\nfragment MemberListFragment_1jRT0c on Organization {\n members(first: 20, orderBy: {direction: ASC, field: CREATED_AT}) {\n totalCount\n edges {\n node {\n id\n ...MemberListItemFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment MemberListItemFragment on Membership {\n id\n role\n source\n profile {\n fullName\n id\n }\n identity {\n email\n id\n }\n createdAt\n canUpdate: permission(action: \"iam:membership:update\")\n canDelete: permission(action: \"iam:membership:delete\")\n}\n"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ const fragment = graphql`
|
|||||||
fragment MemberListItemFragment on Membership {
|
fragment MemberListItemFragment on Membership {
|
||||||
id
|
id
|
||||||
role
|
role
|
||||||
|
source
|
||||||
profile @required(action: THROW) {
|
profile @required(action: THROW) {
|
||||||
fullName
|
fullName
|
||||||
}
|
}
|
||||||
@@ -70,7 +71,7 @@ export function MemberListItem(props: {
|
|||||||
{
|
{
|
||||||
successMessage: __("Member removed successfully"),
|
successMessage: __("Member removed successfully"),
|
||||||
errorMessage: __("Failed to remove member"),
|
errorMessage: __("Failed to remove member"),
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleRemove = async () => {
|
const handleRemove = async () => {
|
||||||
@@ -89,9 +90,9 @@ export function MemberListItem(props: {
|
|||||||
{
|
{
|
||||||
message: sprintf(
|
message: sprintf(
|
||||||
__("Are you sure you want to remove %s?"),
|
__("Are you sure you want to remove %s?"),
|
||||||
membership.profile.fullName,
|
membership.profile.fullName
|
||||||
),
|
),
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -104,10 +105,7 @@ export function MemberListItem(props: {
|
|||||||
<Td>
|
<Td>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{membership.identity.email}
|
{membership.identity.email}
|
||||||
{/* FIXME: put back */}
|
<Badge variant="info">{membership.source}</Badge>
|
||||||
{/* {membership.authMethod === "SAML" && (
|
|
||||||
<Badge variant="info">SAML</Badge>
|
|
||||||
)} */}
|
|
||||||
</div>
|
</div>
|
||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<Td>
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ type (
|
|||||||
IdentityID gid.GID `db:"identity_id"`
|
IdentityID gid.GID `db:"identity_id"`
|
||||||
OrganizationID gid.GID `db:"organization_id"`
|
OrganizationID gid.GID `db:"organization_id"`
|
||||||
Role MembershipRole `db:"role"`
|
Role MembershipRole `db:"role"`
|
||||||
|
Source MembershipSource `db:"source"`
|
||||||
FullName string `db:"full_name"`
|
FullName string `db:"full_name"`
|
||||||
EmailAddress mail.Addr `db:"email_address"`
|
EmailAddress mail.Addr `db:"email_address"`
|
||||||
CreatedAt time.Time `db:"created_at"`
|
CreatedAt time.Time `db:"created_at"`
|
||||||
@@ -67,6 +68,7 @@ WITH mbr AS (
|
|||||||
identity_id,
|
identity_id,
|
||||||
organization_id,
|
organization_id,
|
||||||
role,
|
role,
|
||||||
|
source,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
@@ -80,6 +82,7 @@ SELECT
|
|||||||
mbr.identity_id,
|
mbr.identity_id,
|
||||||
mbr.organization_id,
|
mbr.organization_id,
|
||||||
mbr.role,
|
mbr.role,
|
||||||
|
mbr.source,
|
||||||
COALESCE(mp.full_name, i.full_name, '') as full_name,
|
COALESCE(mp.full_name, i.full_name, '') as full_name,
|
||||||
i.email_address,
|
i.email_address,
|
||||||
mbr.created_at,
|
mbr.created_at,
|
||||||
@@ -122,6 +125,7 @@ INSERT INTO
|
|||||||
identity_id,
|
identity_id,
|
||||||
organization_id,
|
organization_id,
|
||||||
role,
|
role,
|
||||||
|
source,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
)
|
)
|
||||||
@@ -131,6 +135,7 @@ VALUES (
|
|||||||
@identity_id,
|
@identity_id,
|
||||||
@organization_id,
|
@organization_id,
|
||||||
@role,
|
@role,
|
||||||
|
@source,
|
||||||
@created_at,
|
@created_at,
|
||||||
@updated_at
|
@updated_at
|
||||||
);
|
);
|
||||||
@@ -142,6 +147,7 @@ VALUES (
|
|||||||
"identity_id": m.IdentityID,
|
"identity_id": m.IdentityID,
|
||||||
"organization_id": m.OrganizationID,
|
"organization_id": m.OrganizationID,
|
||||||
"role": m.Role,
|
"role": m.Role,
|
||||||
|
"source": m.Source,
|
||||||
"created_at": m.CreatedAt,
|
"created_at": m.CreatedAt,
|
||||||
"updated_at": m.UpdatedAt,
|
"updated_at": m.UpdatedAt,
|
||||||
}
|
}
|
||||||
@@ -176,6 +182,7 @@ WITH mbr AS (
|
|||||||
identity_id,
|
identity_id,
|
||||||
organization_id,
|
organization_id,
|
||||||
role,
|
role,
|
||||||
|
source,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
@@ -189,6 +196,7 @@ SELECT
|
|||||||
mbr.identity_id,
|
mbr.identity_id,
|
||||||
mbr.organization_id,
|
mbr.organization_id,
|
||||||
mbr.role,
|
mbr.role,
|
||||||
|
mbr.source,
|
||||||
COALESCE(mp.full_name, i.full_name, '') as full_name,
|
COALESCE(mp.full_name, i.full_name, '') as full_name,
|
||||||
i.email_address,
|
i.email_address,
|
||||||
mbr.created_at,
|
mbr.created_at,
|
||||||
@@ -325,6 +333,7 @@ WITH mbr AS (
|
|||||||
am.identity_id,
|
am.identity_id,
|
||||||
am.organization_id,
|
am.organization_id,
|
||||||
am.role,
|
am.role,
|
||||||
|
am.source,
|
||||||
am.created_at,
|
am.created_at,
|
||||||
am.updated_at
|
am.updated_at
|
||||||
FROM
|
FROM
|
||||||
@@ -339,6 +348,7 @@ SELECT
|
|||||||
mbr.identity_id,
|
mbr.identity_id,
|
||||||
mbr.organization_id,
|
mbr.organization_id,
|
||||||
mbr.role,
|
mbr.role,
|
||||||
|
mbr.source,
|
||||||
COALESCE(mp.full_name, i.full_name, '') as full_name,
|
COALESCE(mp.full_name, i.full_name, '') as full_name,
|
||||||
i.email_address,
|
i.email_address,
|
||||||
mbr.created_at,
|
mbr.created_at,
|
||||||
@@ -452,6 +462,7 @@ WITH mbr AS (
|
|||||||
identity_id,
|
identity_id,
|
||||||
organization_id,
|
organization_id,
|
||||||
role,
|
role,
|
||||||
|
source,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
@@ -467,6 +478,7 @@ SELECT
|
|||||||
mbr.identity_id,
|
mbr.identity_id,
|
||||||
mbr.organization_id,
|
mbr.organization_id,
|
||||||
mbr.role,
|
mbr.role,
|
||||||
|
mbr.source,
|
||||||
COALESCE(mp.full_name, i.full_name, '') as full_name,
|
COALESCE(mp.full_name, i.full_name, '') as full_name,
|
||||||
i.email_address,
|
i.email_address,
|
||||||
mbr.created_at,
|
mbr.created_at,
|
||||||
@@ -517,6 +529,7 @@ WITH membership_with_profile AS (
|
|||||||
m.identity_id,
|
m.identity_id,
|
||||||
m.organization_id,
|
m.organization_id,
|
||||||
m.role,
|
m.role,
|
||||||
|
m.source,
|
||||||
COALESCE(mp.full_name, i.full_name, '') AS full_name,
|
COALESCE(mp.full_name, i.full_name, '') AS full_name,
|
||||||
i.email_address,
|
i.email_address,
|
||||||
m.created_at,
|
m.created_at,
|
||||||
@@ -536,6 +549,7 @@ SELECT
|
|||||||
identity_id,
|
identity_id,
|
||||||
organization_id,
|
organization_id,
|
||||||
role,
|
role,
|
||||||
|
source,
|
||||||
full_name,
|
full_name,
|
||||||
email_address,
|
email_address,
|
||||||
created_at,
|
created_at,
|
||||||
@@ -633,6 +647,7 @@ SELECT
|
|||||||
identity_id,
|
identity_id,
|
||||||
organization_id,
|
organization_id,
|
||||||
role,
|
role,
|
||||||
|
source,
|
||||||
'' as full_name,
|
'' as full_name,
|
||||||
NULL as email_address,
|
NULL as email_address,
|
||||||
created_at,
|
created_at,
|
||||||
|
|||||||
57
pkg/coredata/membership_source.go
Normal file
57
pkg/coredata/membership_source.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
package coredata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql/driver"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MembershipSource string
|
||||||
|
|
||||||
|
const (
|
||||||
|
MembershipSourceManual MembershipSource = "MANUAL"
|
||||||
|
MembershipSourceSAML MembershipSource = "SAML"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s MembershipSource) String() string {
|
||||||
|
return string(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *MembershipSource) Scan(value any) error {
|
||||||
|
var str string
|
||||||
|
switch v := value.(type) {
|
||||||
|
case string:
|
||||||
|
str = v
|
||||||
|
case []byte:
|
||||||
|
str = string(v)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported type for MembershipSource: %T", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch str {
|
||||||
|
case "MANUAL":
|
||||||
|
*s = MembershipSourceManual
|
||||||
|
case "SAML":
|
||||||
|
*s = MembershipSourceSAML
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid MembershipSource value: %q", str)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s MembershipSource) Value() (driver.Value, error) {
|
||||||
|
return s.String(), nil
|
||||||
|
}
|
||||||
2
pkg/coredata/migrations/20260104T151807Z.sql
Normal file
2
pkg/coredata/migrations/20260104T151807Z.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER TABLE iam_memberships ADD COLUMN source TEXT NOT NULL DEFAULT 'MANUAL';
|
||||||
|
ALTER TABLE iam_memberships ALTER COLUMN source DROP DEFAULT;
|
||||||
@@ -248,6 +248,7 @@ func (s *AccountService) AcceptInvitation(
|
|||||||
IdentityID: identityID,
|
IdentityID: identityID,
|
||||||
OrganizationID: invitation.OrganizationID,
|
OrganizationID: invitation.OrganizationID,
|
||||||
Role: invitation.Role,
|
Role: invitation.Role,
|
||||||
|
Source: coredata.MembershipSourceManual,
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -489,6 +489,7 @@ func (s *OrganizationService) CreateOrganization(
|
|||||||
IdentityID: identityID,
|
IdentityID: identityID,
|
||||||
OrganizationID: organizationID,
|
OrganizationID: organizationID,
|
||||||
Role: coredata.MembershipRoleOwner,
|
Role: coredata.MembershipRoleOwner,
|
||||||
|
Source: coredata.MembershipSourceManual,
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -298,6 +298,7 @@ func (s *Service) HandleAssertion(
|
|||||||
IdentityID: identity.ID,
|
IdentityID: identity.ID,
|
||||||
OrganizationID: config.OrganizationID,
|
OrganizationID: config.OrganizationID,
|
||||||
Role: coredata.MembershipRoleViewer,
|
Role: coredata.MembershipRoleViewer,
|
||||||
|
Source: coredata.MembershipSourceSAML,
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,6 +234,13 @@ enum MembershipRole
|
|||||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.MembershipRoleAuditor")
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.MembershipRoleAuditor")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum MembershipSource
|
||||||
|
@goModel(model: "go.probo.inc/probo/pkg/coredata.MembershipSource") {
|
||||||
|
MANUAL
|
||||||
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.MembershipSourceManual")
|
||||||
|
SAML @goEnum(value: "go.probo.inc/probo/pkg/coredata.MembershipSourceSAML")
|
||||||
|
}
|
||||||
|
|
||||||
type Membership implements Node {
|
type Membership implements Node {
|
||||||
id: ID!
|
id: ID!
|
||||||
createdAt: Datetime!
|
createdAt: Datetime!
|
||||||
@@ -241,6 +248,7 @@ type Membership implements Node {
|
|||||||
profile: MembershipProfile @goField(forceResolver: true)
|
profile: MembershipProfile @goField(forceResolver: true)
|
||||||
organization: Organization @goField(forceResolver: true)
|
organization: Organization @goField(forceResolver: true)
|
||||||
role: MembershipRole!
|
role: MembershipRole!
|
||||||
|
source: MembershipSource!
|
||||||
|
|
||||||
lastSession: Session @goField(forceResolver: true) @isViewer
|
lastSession: Session @goField(forceResolver: true) @isViewer
|
||||||
|
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ type ComplexityRoot struct {
|
|||||||
Permission func(childComplexity int, action string) int
|
Permission func(childComplexity int, action string) int
|
||||||
Profile func(childComplexity int) int
|
Profile func(childComplexity int) int
|
||||||
Role func(childComplexity int) int
|
Role func(childComplexity int) int
|
||||||
|
Source func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
MembershipConnection struct {
|
MembershipConnection struct {
|
||||||
@@ -862,6 +863,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
return e.complexity.Membership.Role(childComplexity), true
|
return e.complexity.Membership.Role(childComplexity), true
|
||||||
|
case "Membership.source":
|
||||||
|
if e.complexity.Membership.Source == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Membership.Source(childComplexity), true
|
||||||
|
|
||||||
case "MembershipConnection.edges":
|
case "MembershipConnection.edges":
|
||||||
if e.complexity.MembershipConnection.Edges == nil {
|
if e.complexity.MembershipConnection.Edges == nil {
|
||||||
@@ -2198,6 +2205,13 @@ enum MembershipRole
|
|||||||
@goEnum(value: "go.probo.inc/probo/pkg/coredata.MembershipRoleAuditor")
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.MembershipRoleAuditor")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum MembershipSource
|
||||||
|
@goModel(model: "go.probo.inc/probo/pkg/coredata.MembershipSource") {
|
||||||
|
MANUAL
|
||||||
|
@goEnum(value: "go.probo.inc/probo/pkg/coredata.MembershipSourceManual")
|
||||||
|
SAML @goEnum(value: "go.probo.inc/probo/pkg/coredata.MembershipSourceSAML")
|
||||||
|
}
|
||||||
|
|
||||||
type Membership implements Node {
|
type Membership implements Node {
|
||||||
id: ID!
|
id: ID!
|
||||||
createdAt: Datetime!
|
createdAt: Datetime!
|
||||||
@@ -2205,6 +2219,7 @@ type Membership implements Node {
|
|||||||
profile: MembershipProfile @goField(forceResolver: true)
|
profile: MembershipProfile @goField(forceResolver: true)
|
||||||
organization: Organization @goField(forceResolver: true)
|
organization: Organization @goField(forceResolver: true)
|
||||||
role: MembershipRole!
|
role: MembershipRole!
|
||||||
|
source: MembershipSource!
|
||||||
|
|
||||||
lastSession: Session @goField(forceResolver: true) @isViewer
|
lastSession: Session @goField(forceResolver: true) @isViewer
|
||||||
|
|
||||||
@@ -5163,6 +5178,35 @@ func (ec *executionContext) fieldContext_Membership_role(_ context.Context, fiel
|
|||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Membership_source(ctx context.Context, field graphql.CollectedField, obj *types.Membership) (ret graphql.Marshaler) {
|
||||||
|
return graphql.ResolveField(
|
||||||
|
ctx,
|
||||||
|
ec.OperationContext,
|
||||||
|
field,
|
||||||
|
ec.fieldContext_Membership_source,
|
||||||
|
func(ctx context.Context) (any, error) {
|
||||||
|
return obj.Source, nil
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
ec.marshalNMembershipSource2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐMembershipSource,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Membership_source(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Membership",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type MembershipSource does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Membership_lastSession(ctx context.Context, field graphql.CollectedField, obj *types.Membership) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Membership_lastSession(ctx context.Context, field graphql.CollectedField, obj *types.Membership) (ret graphql.Marshaler) {
|
||||||
return graphql.ResolveField(
|
return graphql.ResolveField(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -5421,6 +5465,8 @@ func (ec *executionContext) fieldContext_MembershipEdge_node(_ context.Context,
|
|||||||
return ec.fieldContext_Membership_organization(ctx, field)
|
return ec.fieldContext_Membership_organization(ctx, field)
|
||||||
case "role":
|
case "role":
|
||||||
return ec.fieldContext_Membership_role(ctx, field)
|
return ec.fieldContext_Membership_role(ctx, field)
|
||||||
|
case "source":
|
||||||
|
return ec.fieldContext_Membership_source(ctx, field)
|
||||||
case "lastSession":
|
case "lastSession":
|
||||||
return ec.fieldContext_Membership_lastSession(ctx, field)
|
return ec.fieldContext_Membership_lastSession(ctx, field)
|
||||||
case "permission":
|
case "permission":
|
||||||
@@ -7711,6 +7757,8 @@ func (ec *executionContext) fieldContext_Organization_viewerMembership(_ context
|
|||||||
return ec.fieldContext_Membership_organization(ctx, field)
|
return ec.fieldContext_Membership_organization(ctx, field)
|
||||||
case "role":
|
case "role":
|
||||||
return ec.fieldContext_Membership_role(ctx, field)
|
return ec.fieldContext_Membership_role(ctx, field)
|
||||||
|
case "source":
|
||||||
|
return ec.fieldContext_Membership_source(ctx, field)
|
||||||
case "lastSession":
|
case "lastSession":
|
||||||
return ec.fieldContext_Membership_lastSession(ctx, field)
|
return ec.fieldContext_Membership_lastSession(ctx, field)
|
||||||
case "permission":
|
case "permission":
|
||||||
@@ -7864,6 +7912,8 @@ func (ec *executionContext) fieldContext_OrganizationSessionCreated_membership(_
|
|||||||
return ec.fieldContext_Membership_organization(ctx, field)
|
return ec.fieldContext_Membership_organization(ctx, field)
|
||||||
case "role":
|
case "role":
|
||||||
return ec.fieldContext_Membership_role(ctx, field)
|
return ec.fieldContext_Membership_role(ctx, field)
|
||||||
|
case "source":
|
||||||
|
return ec.fieldContext_Membership_source(ctx, field)
|
||||||
case "lastSession":
|
case "lastSession":
|
||||||
return ec.fieldContext_Membership_lastSession(ctx, field)
|
return ec.fieldContext_Membership_lastSession(ctx, field)
|
||||||
case "permission":
|
case "permission":
|
||||||
@@ -10496,6 +10546,8 @@ func (ec *executionContext) fieldContext_UpdateMembershipPayload_membership(_ co
|
|||||||
return ec.fieldContext_Membership_organization(ctx, field)
|
return ec.fieldContext_Membership_organization(ctx, field)
|
||||||
case "role":
|
case "role":
|
||||||
return ec.fieldContext_Membership_role(ctx, field)
|
return ec.fieldContext_Membership_role(ctx, field)
|
||||||
|
case "source":
|
||||||
|
return ec.fieldContext_Membership_source(ctx, field)
|
||||||
case "lastSession":
|
case "lastSession":
|
||||||
return ec.fieldContext_Membership_lastSession(ctx, field)
|
return ec.fieldContext_Membership_lastSession(ctx, field)
|
||||||
case "permission":
|
case "permission":
|
||||||
@@ -14408,6 +14460,11 @@ func (ec *executionContext) _Membership(ctx context.Context, sel ast.SelectionSe
|
|||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
atomic.AddUint32(&out.Invalids, 1)
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
|
case "source":
|
||||||
|
out.Values[i] = ec._Membership_source(ctx, field, obj)
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
|
}
|
||||||
case "lastSession":
|
case "lastSession":
|
||||||
field := field
|
field := field
|
||||||
|
|
||||||
@@ -17574,6 +17631,34 @@ var (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalNMembershipSource2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐMembershipSource(ctx context.Context, v any) (coredata.MembershipSource, error) {
|
||||||
|
tmp, err := graphql.UnmarshalString(v)
|
||||||
|
res := unmarshalNMembershipSource2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐMembershipSource[tmp]
|
||||||
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalNMembershipSource2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐMembershipSource(ctx context.Context, sel ast.SelectionSet, v coredata.MembershipSource) graphql.Marshaler {
|
||||||
|
_ = sel
|
||||||
|
res := graphql.MarshalString(marshalNMembershipSource2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐMembershipSource[v])
|
||||||
|
if res == graphql.Null {
|
||||||
|
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||||
|
graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
unmarshalNMembershipSource2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐMembershipSource = map[string]coredata.MembershipSource{
|
||||||
|
"MANUAL": coredata.MembershipSourceManual,
|
||||||
|
"SAML": coredata.MembershipSourceSAML,
|
||||||
|
}
|
||||||
|
marshalNMembershipSource2goᚗproboᚗincᚋproboᚋpkgᚋcoredataᚐMembershipSource = map[coredata.MembershipSource]string{
|
||||||
|
coredata.MembershipSourceManual: "MANUAL",
|
||||||
|
coredata.MembershipSourceSAML: "SAML",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalNOrderDirection2goᚗproboᚗincᚋproboᚋpkgᚋpageᚐOrderDirection(ctx context.Context, v any) (page.OrderDirection, error) {
|
func (ec *executionContext) unmarshalNOrderDirection2goᚗproboᚗincᚋproboᚋpkgᚋpageᚐOrderDirection(ctx context.Context, v any) (page.OrderDirection, error) {
|
||||||
tmp, err := graphql.UnmarshalString(v)
|
tmp, err := graphql.UnmarshalString(v)
|
||||||
res := unmarshalNOrderDirection2goᚗproboᚗincᚋproboᚋpkgᚋpageᚐOrderDirection[tmp]
|
res := unmarshalNOrderDirection2goᚗproboᚗincᚋproboᚋpkgᚋpageᚐOrderDirection[tmp]
|
||||||
|
|||||||
@@ -73,9 +73,6 @@ func NewMembership(membership *coredata.Membership) *Membership {
|
|||||||
ID: membership.ID,
|
ID: membership.ID,
|
||||||
},
|
},
|
||||||
Role: membership.Role,
|
Role: membership.Role,
|
||||||
// Permissions: membership.Permissions,
|
Source: membership.Source,
|
||||||
// ProvisionedBy: membership.ProvisionedBy,
|
|
||||||
// Active: membership.Active,
|
|
||||||
// LastSyncedAt: membership.LastSyncedAt,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ type Membership struct {
|
|||||||
Profile *MembershipProfile `json:"profile,omitempty"`
|
Profile *MembershipProfile `json:"profile,omitempty"`
|
||||||
Organization *Organization `json:"organization,omitempty"`
|
Organization *Organization `json:"organization,omitempty"`
|
||||||
Role coredata.MembershipRole `json:"role"`
|
Role coredata.MembershipRole `json:"role"`
|
||||||
|
Source coredata.MembershipSource `json:"source"`
|
||||||
LastSession *Session `json:"lastSession,omitempty"`
|
LastSession *Session `json:"lastSession,omitempty"`
|
||||||
Permission bool `json:"permission"`
|
Permission bool `json:"permission"`
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user