From 9e761a906e19372938ed42f003007993cefb9280 Mon Sep 17 00:00:00 2001 From: Gerry Campion Date: Tue, 7 Feb 2023 19:51:57 -0500 Subject: [PATCH 1/5] Possibly works. need to merge main --- api/get_permissions/function.json | 18 +++++++++++++ api/get_permissions/index.ts | 16 ++++++++++++ api/providers/MSGraphUsers.ts | 8 ++++++ api/types/IUser.ts | 1 + api/types/IUsers.ts | 1 + src/components/AppContextProvider.tsx | 5 ++-- src/components/Controls/Controls.tsx | 10 +++++--- src/services/DataService.ts | 37 ++++++++++++++++----------- src/types/IUser.ts | 1 + 9 files changed, 76 insertions(+), 21 deletions(-) create mode 100644 api/get_permissions/function.json create mode 100644 api/get_permissions/index.ts diff --git a/api/get_permissions/function.json b/api/get_permissions/function.json new file mode 100644 index 0000000..329893f --- /dev/null +++ b/api/get_permissions/function.json @@ -0,0 +1,18 @@ +{ + "bindings": [ + { + "authLevel": "anonymous", + "type": "httpTrigger", + "direction": "in", + "name": "req", + "methods": ["get"], + "route": "permissions" + }, + { + "type": "http", + "direction": "out", + "name": "res" + } + ], + "scriptFile": "../dist/get_permissions/index.js" +} diff --git a/api/get_permissions/index.ts b/api/get_permissions/index.ts new file mode 100644 index 0000000..45f64d2 --- /dev/null +++ b/api/get_permissions/index.ts @@ -0,0 +1,16 @@ +import { USERS_PROVIDER } from "../providers/BaseUsers"; +import handle_response from "../utils/handle_response"; + +export default async (context, req) => { + const user = JSON.parse( + Buffer.from(req.headers["x-ms-client-principal"], "base64").toString( + "ascii" + ) + ); + await handle_response(context, async () => ({ + body: await USERS_PROVIDER.getUserPermissions({ + id: user.userId, + name: user.userDetails, + }), + })); +}; diff --git a/api/providers/MSGraphUsers.ts b/api/providers/MSGraphUsers.ts index ec13d7d..7e2b20c 100644 --- a/api/providers/MSGraphUsers.ts +++ b/api/providers/MSGraphUsers.ts @@ -96,7 +96,15 @@ const getUsersByName = async (name: string): Promise => { return users; }; +const getUserPermissions = async (user: IUser): Promise => { + var link = `/users/${user.id}/memberOf?$count=true&$filter=id eq '${process.env["CORE_AUTHOR_GROUP"]}'`; + const response = await client.api(link).get(); + user.permissions = response.value && response.value.length === 1; + return user; +}; + export default { getUsersByIds, getUsersByName, + getUserPermissions, }; diff --git a/api/types/IUser.ts b/api/types/IUser.ts index 127e530..4fbb992 100644 --- a/api/types/IUser.ts +++ b/api/types/IUser.ts @@ -2,4 +2,5 @@ export interface IUser { id: string; name?: string; company?: string; + permissions?: boolean; } diff --git a/api/types/IUsers.ts b/api/types/IUsers.ts index 4653875..d6e9e8f 100644 --- a/api/types/IUsers.ts +++ b/api/types/IUsers.ts @@ -3,4 +3,5 @@ import { IUser } from "./IUser"; export interface IUsers { getUsersByIds: (ids: string[]) => Promise<{ [id: string]: IUser }>; getUsersByName: (name: string) => Promise; + getUserPermissions: (user: IUser) => Promise; } diff --git a/src/components/AppContextProvider.tsx b/src/components/AppContextProvider.tsx index 57b9a2f..f05f251 100644 --- a/src/components/AppContextProvider.tsx +++ b/src/components/AppContextProvider.tsx @@ -77,10 +77,9 @@ const AppContextProvider: React.FC = ({ const isRuleModifiable = useCallback( () => - !isRuleSelected() || - (user && creator && user.id === creator.id) || + (user && user.permissions) || (user && user.company && user.company.toUpperCase() === "CDISC"), - [user, creator, isRuleSelected] + [user] ); const appContext = { diff --git a/src/components/Controls/Controls.tsx b/src/components/Controls/Controls.tsx index 9c3c2e0..b4c84de 100644 --- a/src/components/Controls/Controls.tsx +++ b/src/components/Controls/Controls.tsx @@ -90,7 +90,9 @@ export default function Controls() { @@ -102,7 +104,7 @@ export default function Controls() { @@ -138,7 +140,9 @@ export default function Controls() { => { - return await this.get_me() - .then(function (response) { - return response.json(); - }) - .then(function (responseJson) { - return { - id: responseJson.clientPrincipal.userId, - name: responseJson.clientPrincipal.claims.find( - (claim) => claim.typ === "name" - )?.val, - company: responseJson.clientPrincipal.claims.find( - (claim) => claim.typ === "extension_CompanyName" - )?.val, - }; - }); + const mePromise = this.get_me().then(function (response) { + return response.json(); + }); + const permissionsPromise = fetch(`/api/permissions`, { + method: "GET", + headers: { + Accept: "application/json", + }, + }).then((response) => response.json()); + const [me, permissions] = await Promise.all([ + mePromise, + permissionsPromise, + ]); + return { + id: me.clientPrincipal.userId, + name: me.clientPrincipal.claims.find((claim) => claim.typ === "name") + ?.val, + company: me.clientPrincipal.claims.find( + (claim) => claim.typ === "extension_CompanyName" + )?.val, + permissions: permissions.permissions, + }; }; rulesAbortController = new AbortController(); diff --git a/src/types/IUser.ts b/src/types/IUser.ts index 127e530..4fbb992 100644 --- a/src/types/IUser.ts +++ b/src/types/IUser.ts @@ -2,4 +2,5 @@ export interface IUser { id: string; name?: string; company?: string; + permissions?: boolean; } From 7a07920cdf4953c55b1512b214852c45f7612792 Mon Sep 17 00:00:00 2001 From: Gerry Campion Date: Wed, 8 Feb 2023 09:55:33 -0500 Subject: [PATCH 2/5] Updated readme for env var --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 70be7e7..f9b966b 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ https://cdisc-org.github.io/conformance-rules-editor/ "SWA_TENANT_ID": "", "SWA_CLIENT_ID": "", "SWA_CLIENT_SECRET": "", + "CORE_AUTHOR_GROUP": "" } } ``` From 3e364e0fe6dca3737756230e7edc1ad0493807cb Mon Sep 17 00:00:00 2001 From: Gerry Campion Date: Wed, 8 Feb 2023 10:56:26 -0500 Subject: [PATCH 3/5] Allow for missing group env var (training) --- api/providers/MSGraphUsers.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/api/providers/MSGraphUsers.ts b/api/providers/MSGraphUsers.ts index 7e2b20c..e230bfc 100644 --- a/api/providers/MSGraphUsers.ts +++ b/api/providers/MSGraphUsers.ts @@ -97,9 +97,13 @@ const getUsersByName = async (name: string): Promise => { }; const getUserPermissions = async (user: IUser): Promise => { - var link = `/users/${user.id}/memberOf?$count=true&$filter=id eq '${process.env["CORE_AUTHOR_GROUP"]}'`; - const response = await client.api(link).get(); - user.permissions = response.value && response.value.length === 1; + if ("CORE_AUTHOR_GROUP" in process.env) { + var link = `/users/${user.id}/memberOf?$count=true&$filter=id eq '${process.env["CORE_AUTHOR_GROUP"]}'`; + const response = await client.api(link).get(); + user.permissions = response.value && response.value.length === 1; + } else { + user.permissions = true; + } return user; }; From d0c59cabffff92d3a8858b05acb86a6206af5446 Mon Sep 17 00:00:00 2001 From: Gerry Campion Date: Wed, 8 Feb 2023 11:26:04 -0500 Subject: [PATCH 4/5] Added uml documentation for user permissions --- docs/dev/doc.svg | 47 ++++++++++++++++++++++++----------------------- docs/dev/doc.yuml | 2 +- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/docs/dev/doc.svg b/docs/dev/doc.svg index 737766f..2a4739b 100644 --- a/docs/dev/doc.svg +++ b/docs/dev/doc.svg @@ -4,11 +4,11 @@ - + G - + A0 @@ -253,39 +253,40 @@ A10 - - -Base Users Provider - -Get-Users-By-Ids() -Get-Users-By-Name() + + +Base Users Provider + +Get-Users-By-Ids() +Get-Users-By-Name() +Get-User-Permissions() A11 - -MS Graph Users + +MS Graph Users A10->A11 - - + + A19 - -User - -id -name + +User + +id +name A10->A19 - - + + @@ -336,13 +337,13 @@ A18->A10 - - + + A19->A7 - + diff --git a/docs/dev/doc.yuml b/docs/dev/doc.yuml index 8309703..fa653e5 100644 --- a/docs/dev/doc.yuml +++ b/docs/dev/doc.yuml @@ -19,7 +19,7 @@ [Base Storage Provider|Get-Rules();Get-Rule();Post-Rule();Patch-Rule();Delete-Rule();Max-CoreId();{bg:orange}] [Drupal Storage{bg:orange}] [Cosmos SQL Storage{bg:orange}] -[Base Users Provider|Get-Users-By-Ids();Get-Users-By-Name();{bg:orange}] +[Base Users Provider|Get-Users-By-Ids();Get-Users-By-Name();Get-User-Permissions();{bg:orange}] [MS Graph Users{bg:orange}] // Azure SWA From 6768b04b98cd2aab7a21ee4c73ee227663f9902e Mon Sep 17 00:00:00 2001 From: Gerry Campion Date: Thu, 9 Feb 2023 13:47:14 -0500 Subject: [PATCH 5/5] changed user.permissions to user.write_allowed --- api/providers/MSGraphUsers.ts | 4 +-- api/types/IUser.ts | 2 +- docs/dev/doc.svg | 44 ++++++++++++++------------- docs/dev/doc.yuml | 2 +- src/components/AppContextProvider.tsx | 2 +- src/services/DataService.ts | 2 +- src/types/IUser.ts | 2 +- 7 files changed, 30 insertions(+), 28 deletions(-) diff --git a/api/providers/MSGraphUsers.ts b/api/providers/MSGraphUsers.ts index e230bfc..09c6971 100644 --- a/api/providers/MSGraphUsers.ts +++ b/api/providers/MSGraphUsers.ts @@ -100,9 +100,9 @@ const getUserPermissions = async (user: IUser): Promise => { if ("CORE_AUTHOR_GROUP" in process.env) { var link = `/users/${user.id}/memberOf?$count=true&$filter=id eq '${process.env["CORE_AUTHOR_GROUP"]}'`; const response = await client.api(link).get(); - user.permissions = response.value && response.value.length === 1; + user.write_allowed = response.value && response.value.length === 1; } else { - user.permissions = true; + user.write_allowed = true; } return user; }; diff --git a/api/types/IUser.ts b/api/types/IUser.ts index 4fbb992..c698309 100644 --- a/api/types/IUser.ts +++ b/api/types/IUser.ts @@ -2,5 +2,5 @@ export interface IUser { id: string; name?: string; company?: string; - permissions?: boolean; + write_allowed?: boolean; } diff --git a/docs/dev/doc.svg b/docs/dev/doc.svg index 2a4739b..8210443 100644 --- a/docs/dev/doc.svg +++ b/docs/dev/doc.svg @@ -253,40 +253,42 @@ A10 - - -Base Users Provider - -Get-Users-By-Ids() -Get-Users-By-Name() -Get-User-Permissions() + + +Base Users Provider + +Get-Users-By-Ids() +Get-Users-By-Name() +Get-User-Permissions() A11 - -MS Graph Users + +MS Graph Users A10->A11 - - + + A19 - -User - -id -name + +User + +id +name +company +write_allowed A10->A19 - - + + @@ -337,13 +339,13 @@ A18->A10 - - + + A19->A7 - + diff --git a/docs/dev/doc.yuml b/docs/dev/doc.yuml index fa653e5..6429743 100644 --- a/docs/dev/doc.yuml +++ b/docs/dev/doc.yuml @@ -36,7 +36,7 @@ // Users [Users|id] -[User|id;name] +[User|id;name;company;write_allowed] // RELATIONSHIPS diff --git a/src/components/AppContextProvider.tsx b/src/components/AppContextProvider.tsx index 16f35be..9a05a01 100644 --- a/src/components/AppContextProvider.tsx +++ b/src/components/AppContextProvider.tsx @@ -76,7 +76,7 @@ const AppContextProvider: React.FC = ({ const isRuleModifiable = useCallback( () => - (user && user.permissions) || + (user && user.write_allowed) || (user && user.company && user.company.toUpperCase() === "CDISC"), [user] ); diff --git a/src/services/DataService.ts b/src/services/DataService.ts index b906b4a..ddb3f31 100644 --- a/src/services/DataService.ts +++ b/src/services/DataService.ts @@ -54,7 +54,7 @@ export class DataService { company: me.clientPrincipal.claims.find( (claim) => claim.typ === "extension_CompanyName" )?.val, - permissions: permissions.permissions, + write_allowed: permissions.write_allowed, }; }; diff --git a/src/types/IUser.ts b/src/types/IUser.ts index 4fbb992..c698309 100644 --- a/src/types/IUser.ts +++ b/src/types/IUser.ts @@ -2,5 +2,5 @@ export interface IUser { id: string; name?: string; company?: string; - permissions?: boolean; + write_allowed?: boolean; }