Skip to content

Commit 7d4ee66

Browse files
committed
WIP for connection requests
1 parent f004219 commit 7d4ee66

15 files changed

Lines changed: 353 additions & 176 deletions

client/src/api/index.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,12 @@ export function deleteAllInvitations(organization) {
303303
}
304304

305305
//IdentityProvider
306-
export function connectServiceProviderToIdentityProvider(applicationManageIdentifier, entityType, idpManageIdentifier) {
306+
export function connectServiceProviderToIdentityProvider(applicationManageIdentifier, entityType, idpManageIdentifier, message) {
307307
const body = {
308308
applicationManageIdentifier: applicationManageIdentifier,
309309
entityType: entityType,
310-
idpManageIdentifier: idpManageIdentifier
310+
idpManageIdentifier: idpManageIdentifier,
311+
message
311312
};
312313
return postPutJson("/api/v1/idp/connect", body, "PUT")
313314
}

client/src/components/Entities.scss

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,6 @@
125125
}
126126
}
127127

128-
svg.impersonate {
129-
width: 26px;
130-
height: auto;
131-
cursor: pointer;
132-
color: var(--sds--color--blue--400);
133-
134-
}
135-
136-
137128
table {
138129
width: 100%;
139130
table-layout: fixed;
@@ -290,6 +281,13 @@
290281
height: auto;
291282
color: var(--sds--color--gray--300);
292283
border-radius: 12px;
284+
285+
&.impersonate {
286+
width: 26px;
287+
height: auto;
288+
cursor: pointer;
289+
color: var(--sds--color--blue--400);
290+
}
293291
}
294292
}
295293

client/src/locale/en.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,7 @@ const en = {
976976
new: "Nieuwe applicatie toevoegen",
977977
name: "App",
978978
vendor: "Vendor",
979+
connectRequested: "Requested",
979980
status: "Status",
980981
created: "Date connected",
981982
searchPlaceHolder: "Search...",
@@ -1022,11 +1023,25 @@ const en = {
10221023
applicationConnect: {
10231024
connect: "Connect",
10241025
request: "Request connection",
1026+
requestMember: "Request application",
10251027
back: "← Back to other apps",
10261028
defaultAccess: "Hoe wil je default toegang instellen?",
1029+
requestConnection: "Koppeling met deze applicatie moet worden aangevraagd",
1030+
requestConnectionInfo: "De leverancier van deze applicatie ontvangt en beoordeelt de aanvraag. ",
10271031
access: {
10281032
all:"Iedereen van de {{orgName}} heeft direct automatisch toegang",
10291033
some: "Pas toegangsregels toe"
1034+
},
1035+
memberRequestInfo: [
1036+
"Om een applicatie gekoppelde te krijgen met het SURF Access platform, moet akkoord gegeven worden worden door de SURF Access Verantwoordelijke van de {{orgName}}.",
1037+
"Geef hieronder aan waarom je deze applicatie geactiveerd wil hebben. Wij versturen het bericht naar hem of haar, je ontvangt zelf ook een kopie."
1038+
],
1039+
messagePlaceholder: "Your message",
1040+
sendMessage: "Send message",
1041+
flash: {
1042+
requestConnectionByMember: "Your request has been send",
1043+
makeConnection: "Application access has been set",
1044+
requestConnection: "Application access is requested"
10301045
}
10311046
}
10321047
}

client/src/pages/ApplicationDetail.jsx

Lines changed: 267 additions & 154 deletions
Large diffs are not rendered by default.

client/src/pages/ApplicationDetail.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ div.application-detail-container {
1616
background-color: var(--sds--color--gray--background);
1717
border-radius: 6px;
1818
}
19+
h3 {
20+
margin-bottom: 20px;
21+
}
1922
}
2023

2124
.application-detail-header-container {

client/src/pages/ApplicationOverview.jsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import React, {useEffect, useState} from "react";
33
import {publicServiceProviders} from "../api/index.js";
44
import I18n from "../locale/I18n.js";
55
import {useNavigate} from "react-router-dom";
6-
import {Loader} from "@surfnet/sds";
6+
import {Loader, Chip, ChipType} from "@surfnet/sds";
77
import SelectField from "../components/SelectField.jsx";
88
import {isEmpty} from "../utils/Utils.js";
9-
import {providerName, providerOrganizationName} from "../utils/Manage.js";
9+
import {CHANGE_REQUEST_TYPE, providerName, providerOrganizationName} from "../utils/Manage.js";
1010
import {useAppStore} from "../stores/AppStore.js";
1111
import {Entities} from "../components/Entities.jsx";
1212
import {isOrganizationAdmin} from "../utils/Permissions.js";
@@ -40,19 +40,24 @@ const ApplicationOverview = ({accessible}) => {
4040
publicServiceProviders()
4141
.then(res => {
4242
//Scope the services on the allowed-entities of the IdP of the user
43+
const openConnectionRequests = (user.changeRequests || [])
44+
.filter(changeRequest => changeRequest.requestType === CHANGE_REQUEST_TYPE.LINK_REQUEST &&
45+
changeRequest.pathUpdateType === "ADDITION")
46+
.map(changeRequest => changeRequest.pathUpdates.allowedEntities.name);
4347
if (accessible) {
4448
const allowedAll = user.identityProvider.data.allowedall;
4549
const allowedEntities = user.identityProvider.data.allowedEntities.map(entity => entity.name);
46-
res = res.filter(entity => allowedAll || allowedEntities.includes(entity.data.entityid))
50+
res = res.filter(entity => allowedAll || allowedEntities.includes(entity.data.entityid) || openConnectionRequests.includes(entity.data.entityid))
4751
} else {
4852
//In the case of eduID / external user, we don't have an identityProvider
4953
const allowedEntities = (user.identityProvider?.data?.allowedEntities || []).map(entity => entity.name);
50-
res = res.filter(entity => !allowedEntities.includes(entity.data.entityid))
54+
res = res.filter(entity => !allowedEntities.includes(entity.data.entityid) && !openConnectionRequests.includes(entity.data.entityid))
5155
}
5256
res.forEach(entity => {
5357
entity.name = providerName(I18n.locale, entity);
5458
entity.vendor = providerOrganizationName(I18n.locale, entity);
5559
entity.created = entity.revision.created
60+
entity.connectionRequest = openConnectionRequests.includes(entity.data.entityid);
5661
});
5762
res = res
5863
.sort((sp1, sp2) => sp1.name.toLowerCase()
@@ -166,7 +171,9 @@ const ApplicationOverview = ({accessible}) => {
166171
{
167172
key: "name",
168173
header: I18n.t("accessibleApps.name"),
169-
mapper: entity => entity.name
174+
mapper: entity => <div className="app-name">
175+
{entity.name}{entity.connectionRequest && <Chip type={ChipType.Status_error}
176+
label={I18n.t("accessibleApps.connectRequested")}/>}</div>
170177
},
171178
{
172179
key: "vendor",

client/src/pages/ApplicationOverview.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ div.accessible-apps-container {
2424
}
2525
}
2626

27+
.app-name {
28+
display: flex;
29+
button {
30+
margin: 0 15px 0 auto;
31+
}
32+
}
33+
2734
.accessible-apps-header-container {
2835
background-color: var(--sds--color--gray--background);
2936
padding: 25px 50px 25px 50px;

client/src/stores/AppStore.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export const useAppStore = create(set => ({
1414
setFlash: (message, type) => {
1515
set({flash: {msg: message, type: type || "info"}});
1616
if (!type || type === "info") {
17-
setTimeout(() => set({flash: {}}), 5000);
17+
setTimeout(() => set({flash: {}}), 6500);
1818
}
1919
},
2020
clearFlash: () => set({flash: {}}),

client/src/utils/Manage.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,15 @@ export const ENVIRONMENTS = {
6161
TEST: "TEST", PROD: "PROD"
6262
}
6363

64+
export const CHANGE_REQUEST_TYPE = {
65+
PRODUCTION_STATUS_REQUEST: "ProductionStatusRequest",
66+
LINK_REQUEST: "LinkRequest",
67+
UNLINK_REQUEST:"UnlinkRequest",
68+
CHANGE:"Change",
69+
LINK_INVITE:"LinkInvite",
70+
UNLINK_INVITE: "UnlinkInvite"
71+
}
72+
6473
export const APPLICATION_LINKS = [
6574
{
6675
locale: "applicationDetail.website",

server/src/main/java/access/api/IdentityProviderController.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.springframework.web.bind.annotation.RequestMapping;
2525
import org.springframework.web.bind.annotation.RestController;
2626

27+
import java.util.ArrayList;
2728
import java.util.List;
2829
import java.util.Map;
2930

@@ -93,6 +94,9 @@ public ResponseEntity<Map<String, Object>> connect(User user, @RequestBody @Vali
9394
String deeplink = String.format("/application-detail/%s/%s",
9495
serviceProvider.get("type"),
9596
serviceProvider.get("id"));
97+
//Avoid UnsupportedException for immutable collections
98+
admins = new ArrayList<>(admins);
99+
admins.add(user);
96100
mailBox.sendConnectionRequest(userFromDB, admins, organization, getProviderName(serviceProvider),
97101
connectionRequest.getMessage(), deeplink);
98102
return Results.createResult();

0 commit comments

Comments
 (0)