Skip to content

Commit

Permalink
Merge pull request #87 from bcgov/feature/bceid
Browse files Browse the repository at this point in the history
add display of business profile on access approval page
  • Loading branch information
ikethecoder authored Jun 30, 2021
2 parents a608b4b + 8495da5 commit 006045b
Show file tree
Hide file tree
Showing 17 changed files with 1,122 additions and 229 deletions.
286 changes: 143 additions & 143 deletions src/authz/matrix.csv

Large diffs are not rendered by default.

27 changes: 26 additions & 1 deletion src/authz/whitelist.json
Original file line number Diff line number Diff line change
Expand Up @@ -721,5 +721,30 @@
"referer": "http://localhost:4180/manager/service-accounts",
"query": "\n mutation CreateServiceAccount($resourceId: String!, $scopes: [String]!) {\n createServiceAccount(resourceId: $resourceId, scopes: $scopes) {\n id\n name\n credentials\n }\n }\n",
"added": "2021-06-16T05:56:54.209Z"
},
"b13519f4421dc481f3c23247dcb63d12": {
"referer": "http://localhost:4180/manager/consumers",
"query": "\n query GetAccessRequest($id: ID!, $rid: String!) {\n AccessRequest(where: { id: $id }) {\n id\n name\n isApproved\n isIssued\n controls\n additionalDetails\n createdAt\n requestor {\n name\n username\n }\n application {\n name\n }\n serviceAccess {\n id\n }\n productEnvironment {\n name\n product {\n name\n }\n credentialIssuer {\n availableScopes\n clientRoles\n }\n }\n }\n\n allActivities(sortBy: createdAt_DESC, where: { refId: $rid }) {\n id\n type\n name\n action\n result\n message\n context\n refId\n namespace\n extRefId\n createdAt\n actor {\n name\n username\n }\n }\n }\n",
"added": "2021-06-24T05:32:11.325Z"
},
"1f3608db1a9f3c60ea6fc0eaa283c4e6": {
"referer": "http://localhost:4180/manager/requests/609daa814a180ccfaaedbe0d",
"query": "\n query GetBusinessProfile($serviceAccessId: ID!) {\n BusinessProfile(serviceAccessId: $serviceAccessId) {\n user {\n displayName\n firstname\n surname\n email\n isSuspended\n isManagerDisabled\n }\n institution {\n type\n legalName\n address {\n addressLine1\n addressLine2\n city\n postal\n province\n country\n }\n isSuspended\n businessTypeOther\n }\n }\n }\n",
"added": "2021-06-24T05:43:48.010Z"
},
"e500280ae6fa283e22d0e9095e1174c7": {
"referer": "http://localhost:4180/manager/consumers",
"query": "\n query GetPendingAccessRequests {\n allAccessRequestsByNamespace(where: { isIssued_not: true }) {\n id\n name\n requestor {\n name\n username\n }\n }\n }\n",
"added": "2021-06-29T22:14:01.196Z"
},
"0ebc74e357250ab2d8cdca8afd3aff7e": {
"referer": "http://localhost:4180/manager/requests/60dba098fb76a41bf6a8e74e",
"query": "\n query GetAccessRequest($id: ID!, $rid: String!) {\n AccessRequest(where: { id: $id }) {\n id\n name\n isApproved\n isIssued\n controls\n additionalDetails\n createdAt\n requestor {\n name\n username\n email\n }\n application {\n name\n }\n serviceAccess {\n id\n }\n productEnvironment {\n name\n product {\n name\n }\n credentialIssuer {\n availableScopes\n clientRoles\n }\n }\n }\n\n allActivities(sortBy: createdAt_DESC, where: { refId: $rid }) {\n id\n type\n name\n action\n result\n message\n context\n refId\n namespace\n extRefId\n createdAt\n actor {\n name\n username\n }\n }\n }\n",
"added": "2021-06-29T22:42:13.261Z"
},
"4eccdd9ef225022880be1cc65bfcf5a3": {
"referer": "http://localhost:4180/manager/requests/60dba098fb76a41bf6a8e74e",
"query": "\n query GetAccessRequest($id: ID!, $rid: String!) {\n AccessRequest(where: { id: $id }) {\n id\n name\n isApproved\n isIssued\n controls\n additionalDetails\n createdAt\n requestor {\n name\n username\n email\n }\n application {\n name\n }\n serviceAccess {\n id\n }\n productEnvironment {\n name\n additionalDetailsToRequest\n product {\n name\n }\n credentialIssuer {\n availableScopes\n clientRoles\n }\n }\n }\n\n allActivities(sortBy: createdAt_DESC, where: { refId: $rid }) {\n id\n type\n name\n action\n result\n message\n context\n refId\n namespace\n extRefId\n createdAt\n actor {\n name\n username\n }\n }\n }\n",
"added": "2021-06-29T22:48:41.365Z"
}
}
}
95 changes: 95 additions & 0 deletions src/lists/extensions/BusinessProfile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { EnforcementPoint } from '../../authz/enforcement';

import { lookupCredentialReferenceByServiceAccess } from '../../services/keystone';

import { ConfigService } from '../../services/bceid/config.service';
import { BCeIDService } from '../../services/bceid/bceid.service';

const typeBusinessProfile = `
type BusinessProfile {
user: UserDetails
institution: InstitutionDetails
}
`;

const typeUserDetails = `
type UserDetails {
guid: String
displayName: String
firstname: String
surname: String
email: String
isSuspended: Boolean
isManagerDisabled: Boolean
}
`;

const typeInstitutionDetails = `
type InstitutionDetails {
guid: String
type: String
legalName: String
address: AddressDetails
isSuspended: Boolean
businessTypeOther: String
}
`;

const typeAddressDetails = `
type AddressDetails {
addressLine1: String
addressLine2: String
city: String
postal: String
province: String
country: String
}
`;

module.exports = {
extensions: [
(keystone: any) => {
keystone.extendGraphQLSchema({
types: [
{ type: typeBusinessProfile },
{ type: typeUserDetails },
{ type: typeInstitutionDetails },
{ type: typeAddressDetails },
],
queries: [
{
schema: 'BusinessProfile(serviceAccessId: ID!): BusinessProfile',
resolver: async (
item: any,
args: any,
context: any,
info: any,
{ query, access }: any
) => {
const serviceAccess = await lookupCredentialReferenceByServiceAccess(
context,
args.serviceAccessId
);

const fullUsername = serviceAccess.application?.owner.username;

if (fullUsername != null && fullUsername.endsWith('@bceid')) {
const username = fullUsername.substring(
0,
fullUsername.length - 6
);

const bc = new BCeIDService(new ConfigService());
return await bc.getAccountDetails(username);
} else {
return {};
}
},
access: EnforcementPoint,
},
],
mutations: [],
});
},
],
};
12 changes: 9 additions & 3 deletions src/nextapp/components/access-requests/access-requests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const query = gql`
name
requestor {
name
username
}
}
}
Expand All @@ -47,11 +48,14 @@ const AccessRequests: React.FC = () => {
);
const total = data?.allAccessRequestsByNamespace.length ?? 0;
const isShowingAll = total > initialSlice && sliceIndex !== initialSlice;
const color = data?.allAccessRequestsByNamespace.length === 0 ? 'blue' : 'yellow';
const color =
data?.allAccessRequestsByNamespace.length === 0 ? 'blue' : 'yellow';
const handleShowMore = React.useCallback(
() =>
setSliceIndex((s) =>
s === initialSlice ? data.allAccessRequestsByNamespace.length : initialSlice
s === initialSlice
? data.allAccessRequestsByNamespace.length
: initialSlice
),
[data, setSliceIndex]
);
Expand Down Expand Up @@ -110,7 +114,9 @@ const AccessRequests: React.FC = () => {
{d.requestor && (
<>
<Text as="span" fontWeight="bold">
{d.requestor?.name}
{d.requestor?.name
? d.requestor?.name
: d.requestor.username}
</Text>{' '}
is requesting access to{' '}
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as React from 'react';
import { Box, SkeletonText } from '@chakra-ui/react';

const BusinessProfileLoading: React.FC = () => {
return (
<Box p={0}>
<SkeletonText noOfLines={1} spacing={2} skeletonHeight="4" />
<SkeletonText noOfLines={8} spacing={2} skeletonHeight="2" />
</Box>
);
};

export default BusinessProfileLoading;
90 changes: 90 additions & 0 deletions src/nextapp/components/business-profile/business-profile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import * as React from 'react';
import { Heading, Text } from '@chakra-ui/react';
import { gql } from 'graphql-request';
import { useApi } from '@/shared/services/api';

import Loading from './business-profile-loading';

interface BusinessProfileProps {
serviceAccessId: string;
}

const BusinessProfileComponent: React.FC<BusinessProfileProps> = ({
serviceAccessId,
}) => {
const { data } = useApi(
['BusinessProfile', serviceAccessId],
{
query,
variables: { serviceAccessId },
},
{ suspense: false }
);

if (!data) {
return <Loading />;
}
if (data.BusinessProfile.institution == null) {
return <></>;
}
const institution = data.BusinessProfile.institution;
const contact = data.BusinessProfile.user;
return (
<>
<Heading size="sm" mb={2}>
Business Profile
</Heading>
<Heading size="xs" mt={3} mb={1}>
{institution.businessTypeOther}
</Heading>
<Text mb={0}>{institution.legalName}</Text>
<Text mb={0}>{institution.address.addressLine1}</Text>
<Text mb={0}>{institution.address.addressLine2}</Text>
<Text mb={0}>
{institution.address.city} {institution.address.province}
</Text>
<Text mb={0}>{institution.address.postal}</Text>
<Text mb={0}>{institution.address.country}</Text>

<Heading size="xs" mt={3} mb={1}>
Contact
</Heading>
<Text mb={0}>{contact.displayName}</Text>
<Text mb={0}>
{contact.surname}, {contact.firstname}
</Text>
<Text mb={0}>{contact.email}</Text>
</>
);
};

export default BusinessProfileComponent;

const query = gql`
query GetBusinessProfile($serviceAccessId: ID!) {
BusinessProfile(serviceAccessId: $serviceAccessId) {
user {
displayName
firstname
surname
email
isSuspended
isManagerDisabled
}
institution {
type
legalName
address {
addressLine1
addressLine2
city
postal
province
country
}
isSuspended
businessTypeOther
}
}
}
`;
1 change: 1 addition & 0 deletions src/nextapp/components/business-profile/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './business-profile';
16 changes: 13 additions & 3 deletions src/nextapp/pages/devportal/requests/new/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,12 @@ import { dehydrate } from 'react-query/hydration';
import { FieldsetBox, RadioGroup } from '@/components/forms';
import { FaBook } from 'react-icons/fa';
import { useRouter } from 'next/router';
import isString from 'lodash/isString';

const queryKey = 'newAccessRequest';

const isNotBlank = (v: any) => isString(v) && v.length > 0;

export const getServerSideProps: GetServerSideProps = async (context) => {
const { id } = context.params;
const queryClient = new QueryClient();
Expand Down Expand Up @@ -121,7 +124,11 @@ const NewRequestsPage: React.FC<

try {
const payload = {
name: `${dataset.name} FOR ${data.allTemporaryIdentities[0].name}`,
name: `${dataset.name} FOR ${
data.allTemporaryIdentities[0].name
? data.allTemporaryIdentities[0].name
: data.allTemporaryIdentities[0].username
}`,
controls: JSON.stringify({
clientGenCertificate:
selectedEnvironment?.credentialIssuer?.clientAuthenticator ===
Expand Down Expand Up @@ -233,10 +240,13 @@ const NewRequestsPage: React.FC<
</FieldsetBox>

<FieldsetBox
isRequired={hasSelectedEnvironment}
isRequired={
hasSelectedEnvironment &&
isNotBlank(selectedEnvironment?.additionalDetailsToRequest)
}
title="Additional Information & Terms"
>
{selectedEnvironment?.additionalDetailsToRequest && (
{isNotBlank(selectedEnvironment?.additionalDetailsToRequest) && (
<Box pb={4}>
<Text>
<Text as="strong">From the API Provider</Text>:{' '}
Expand Down
Loading

0 comments on commit 006045b

Please sign in to comment.