Skip to content

Commit

Permalink
Merge pull request #86 from uatisdeproblem/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
uatisdeproblem committed Mar 21, 2024
2 parents 3bb6c18 + 7282381 commit 3067c29
Show file tree
Hide file tree
Showing 19 changed files with 106 additions and 38 deletions.
10 changes: 5 additions & 5 deletions back-end/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion back-end/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.8.6",
"version": "1.8.7",
"name": "back-end",
"scripts": {
"lint": "eslint --ext .ts",
Expand Down
9 changes: 6 additions & 3 deletions back-end/src/handlers/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ const authorizeHTTPApi = async (
const user = await verifyTokenAndGetESNAccountsUser(authorization);

if (user) {
if (user.isAdministrator || user.canManageOpportunities) await verifyUserPermissions(user);
if (user.isAdministrator || user.canManageOpportunities || user.canManageDashboard)
await verifyUserPermissions(user);
result.context = { principalId: user.userId, user };
result.isAuthorized = true;
}
Expand All @@ -50,7 +51,8 @@ const authorizeWebSocketApi = async (event: any): Promise<WebSocketAuthResult> =
const result: WebSocketAuthResult = {};

if (user) {
if (user.isAdministrator || user.canManageOpportunities) await verifyUserPermissions(user);
if (user.isAdministrator || user.canManageOpportunities || user.canManageDashboard)
await verifyUserPermissions(user);
result.principalId = user.userId;
}

Expand All @@ -77,11 +79,12 @@ const verifyTokenAndGetESNAccountsUser = async (token: string): Promise<User> =>
}
};
const verifyUserPermissions = async (user: User): Promise<void> => {
const { administratorsIds, opportunitiesManagersIds } = new Configurations(
const { administratorsIds, opportunitiesManagersIds, dashboardManagersIds } = new Configurations(
await ddb.get({ TableName: DDB_TABLES.configurations, Key: { PK: Configurations.PK } })
);
user.isAdministrator = administratorsIds.includes(user.userId);
user.canManageOpportunities = user.isAdministrator || opportunitiesManagersIds.includes(user.userId);
user.canManageDashboard = user.isAdministrator || dashboardManagersIds.includes(user.userId);
};

const getPolicyDocumentToAllowWebSocketRequest = (methodArn: string, allow: boolean): any => {
Expand Down
14 changes: 9 additions & 5 deletions back-end/src/handlers/communications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Communications extends ResourceController {
await ddb.get({ TableName: DDB_TABLES.communications, Key: { communicationId: this.resourceId } })
);
} catch (err) {
throw new HandledError('Link not found');
throw new HandledError('Communication not found');
}
}

Expand Down Expand Up @@ -83,7 +83,8 @@ class Communications extends ResourceController {
}

protected async postResources(): Promise<Communication> {
if (!this.galaxyUser.isAdministrator) throw new HandledError('Unauthorized');
if (!(this.galaxyUser.isAdministrator || this.galaxyUser.canManageDashboard))
throw new HandledError('Unauthorized');

this.communication = new Communication(this.body);
this.communication.communicationId = await ddb.IUNID(PROJECT);
Expand All @@ -97,7 +98,8 @@ class Communications extends ResourceController {
}

protected async putResource(): Promise<Communication> {
if (!this.galaxyUser.isAdministrator) throw new HandledError('Unauthorized');
if (!(this.galaxyUser.isAdministrator || this.galaxyUser.canManageDashboard))
throw new HandledError('Unauthorized');

const oldCommunication = new Communication(this.communication);
this.communication.safeLoad(this.body, oldCommunication);
Expand All @@ -116,7 +118,8 @@ class Communications extends ResourceController {
}
}
private async manageArchive(archive: boolean): Promise<Communication> {
if (!this.galaxyUser.isAdministrator) throw new HandledError('Unauthorized');
if (!(this.galaxyUser.isAdministrator || this.galaxyUser.canManageDashboard))
throw new HandledError('Unauthorized');

if (archive) this.communication.archivedAt = new Date().toISOString();
else delete this.communication.archivedAt;
Expand All @@ -126,7 +129,8 @@ class Communications extends ResourceController {
}

protected async deleteResource(): Promise<void> {
if (!this.galaxyUser.isAdministrator) throw new HandledError('Unauthorized');
if (!(this.galaxyUser.isAdministrator || this.galaxyUser.canManageDashboard))
throw new HandledError('Unauthorized');

await ddb.delete({
TableName: DDB_TABLES.communications,
Expand Down
11 changes: 7 additions & 4 deletions back-end/src/handlers/deadlines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Deadlines extends ResourceController {
await ddb.get({ TableName: DDB_TABLES.deadlines, Key: { deadlineId: this.resourceId } })
);
} catch (err) {
throw new HandledError('Link not found');
throw new HandledError('Deadline not found');
}
}

Expand Down Expand Up @@ -83,7 +83,8 @@ class Deadlines extends ResourceController {
}

protected async postResources(): Promise<Deadline> {
if (!this.galaxyUser.isAdministrator) throw new HandledError('Unauthorized');
if (!(this.galaxyUser.isAdministrator || this.galaxyUser.canManageDashboard))
throw new HandledError('Unauthorized');

this.deadline = new Deadline(this.body);
this.deadline.deadlineId = await ddb.IUNID(PROJECT);
Expand All @@ -97,7 +98,8 @@ class Deadlines extends ResourceController {
}

protected async putResource(): Promise<Deadline> {
if (!this.galaxyUser.isAdministrator) throw new HandledError('Unauthorized');
if (!(this.galaxyUser.isAdministrator || this.galaxyUser.canManageDashboard))
throw new HandledError('Unauthorized');

const oldDeadline = new Deadline(this.deadline);
this.deadline.safeLoad(this.body, oldDeadline);
Expand All @@ -106,7 +108,8 @@ class Deadlines extends ResourceController {
}

protected async deleteResource(): Promise<void> {
if (!this.galaxyUser.isAdministrator) throw new HandledError('Unauthorized');
if (!(this.galaxyUser.isAdministrator || this.galaxyUser.canManageDashboard))
throw new HandledError('Unauthorized');

await ddb.delete({ TableName: DDB_TABLES.deadlines, Key: { deadlineId: this.deadline.deadlineId } });
}
Expand Down
7 changes: 5 additions & 2 deletions back-end/src/handlers/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ class Login extends ResourceController {
const attributes = data['cas:attributes'][0];
const userId = String(data['cas:user'][0]).toLowerCase();

const { administratorsIds, opportunitiesManagersIds } = await this.loadOrInitConfigurations(userId);
const { administratorsIds, opportunitiesManagersIds, dashboardManagersIds } = await this.loadOrInitConfigurations(
userId
);

const user = new User({
userId,
Expand All @@ -77,7 +79,8 @@ class Login extends ResourceController {
country: attributes['cas:country'][0],
avatarURL: attributes['cas:picture'][0],
isAdministrator: administratorsIds.includes(userId),
canManageOpportunities: administratorsIds.includes(userId) || opportunitiesManagersIds.includes(userId)
canManageOpportunities: administratorsIds.includes(userId) || opportunitiesManagersIds.includes(userId),
canManageDashboard: administratorsIds.includes(userId) || dashboardManagersIds.includes(userId)
});
this.logger.info('ESN Accounts login', { user });

Expand Down
3 changes: 2 additions & 1 deletion back-end/src/handlers/media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ class Media extends ResourceController {
}

protected async checkAuthBeforeRequest(): Promise<void> {
if (!this.galaxyUser.isAdministrator) throw new HandledError('Unauthorized');
if (!(this.galaxyUser.isAdministrator || this.galaxyUser.canManageDashboard))
throw new HandledError('Unauthorized');
}

protected async postResources(): Promise<SignedURL> {
Expand Down
9 changes: 6 additions & 3 deletions back-end/src/handlers/usefulLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ class UsefulLinks extends ResourceController {
}

protected async postResources(): Promise<UsefulLink> {
if (!this.galaxyUser.isAdministrator) throw new HandledError('Unauthorized');
if (!(this.galaxyUser.isAdministrator || this.galaxyUser.canManageDashboard))
throw new HandledError('Unauthorized');

this.usefulLink = new UsefulLink(this.body);
this.usefulLink.linkId = await ddb.IUNID(PROJECT);
Expand All @@ -91,7 +92,8 @@ class UsefulLinks extends ResourceController {
}

protected async putResource(): Promise<UsefulLink> {
if (!this.galaxyUser.isAdministrator) throw new HandledError('Unauthorized');
if (!(this.galaxyUser.isAdministrator || this.galaxyUser.canManageDashboard))
throw new HandledError('Unauthorized');

const oldLink = new UsefulLink(this.usefulLink);
this.usefulLink.safeLoad(this.body, oldLink);
Expand Down Expand Up @@ -126,7 +128,8 @@ class UsefulLinks extends ResourceController {
}

protected async deleteResource(): Promise<void> {
if (!this.galaxyUser.isAdministrator) throw new HandledError('Unauthorized');
if (!(this.galaxyUser.isAdministrator || this.galaxyUser.canManageDashboard))
throw new HandledError('Unauthorized');

await ddb.delete({ TableName: DDB_TABLES.usefulLinks, Key: { linkId: this.usefulLink.linkId } });
}
Expand Down
5 changes: 5 additions & 0 deletions back-end/src/models/configurations.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export class Configurations extends Resource {
* The IDs of the platform's administrators.
*/
administratorsIds: string[];
/**
* The IDs of the users that can manage the dashboard.
*/
dashboardManagersIds: string[];
/**
* The IDs of the users that can open and manage opportunities.
*/
Expand Down Expand Up @@ -75,6 +79,7 @@ export class Configurations extends Resource {
super.load(x);
this.administratorsIds = this.cleanArray(x.administratorsIds, String).map(x => x.toLowerCase());
this.opportunitiesManagersIds = this.cleanArray(x.opportunitiesManagersIds, String).map(x => x.toLowerCase());
this.dashboardManagersIds = this.cleanArray(x.dashboardManagersIds, String).map(x => x.toLowerCase());
this.bannedUsersIds = this.cleanArray(x.bannedUsersIds, String).map(x => x.toLowerCase());

this.appTitle = this.clean(x.appTitle, String, 'Assembly app');
Expand Down
6 changes: 6 additions & 0 deletions back-end/src/models/user.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ export class User extends Resource {
* A change in this permission will require a new sign-in to take full place.
*/
canManageOpportunities: boolean;
/**
* Whether the user can manage the dashboard, based on the platform's configurations.
* A change in this permission will require a new sign-in to take full place.
*/
canManageDashboard: boolean;

/**
* Whether the user has one of the allowed roles.
Expand Down Expand Up @@ -121,6 +126,7 @@ export class User extends Resource {
this.avatarURL = this.clean(x.avatarURL, String);
this.isAdministrator = this.clean(x.isAdministrator, Boolean);
this.canManageOpportunities = this.clean(x.canManageOpportunities, Boolean);
this.canManageDashboard = this.clean(x.canManageDashboard, Boolean);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion back-end/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ openapi: 3.0.3

info:
title: ESN Assembly app
version: 1.8.6
version: 1.8.7
contact:
name: Matteo Carbone
email: [email protected]
Expand Down
16 changes: 8 additions & 8 deletions front-end/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion front-end/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "esn-assembly",
"version": "1.8.6",
"version": "1.8.7",
"author": "Matteo Carbone",
"homepage": "https://matteocarbone.com/",
"scripts": {
Expand Down
26 changes: 26 additions & 0 deletions front-end/src/app/tabs/configurations/configurations.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,32 @@ <h2>{{ 'CONFIGURATIONS.OPPORTUNITIES_MANAGERS' | translate }}</h2>
<ion-icon icon="trash-outline" slot="icon-only"></ion-icon>
</ion-button>
</ion-item>
<ion-list-header class="ion-padding-top">
<ion-label>
<h2>{{ 'CONFIGURATIONS.DASHBOARD_MANAGERS' | translate }}</h2>
<p>{{ 'CONFIGURATIONS.DASHBOARD_MANAGERS_I' | translate }}</p>
</ion-label>
<ion-button (click)="addDashboardManager()">{{ 'COMMON.ADD' | translate }}</ion-button>
</ion-list-header>
<ion-item *ngIf="!configurations">
<ion-label><ion-skeleton-text animated></ion-skeleton-text></ion-label>
</ion-item>
<ion-item
class="noElements"
*ngIf="configurations?.dashboardManagersIds && !configurations.dashboardManagersIds.length"
>
<ion-label>{{ 'CONFIGURATIONS.NO_USERS_ADDED' | translate }}</ion-label>
</ion-item>
<ion-item *ngFor="let managerId of configurations?.dashboardManagersIds">
<ion-label>{{ managerId }}</ion-label>
<ion-button fill="clear" color="medium" slot="end" (click)="app.openUserProfileById(managerId)">
<ion-icon icon="open-outline" slot="icon-only"></ion-icon>
</ion-button>
<ion-button fill="clear" color="danger" slot="end" (click)="removeDashboardManagerById(managerId)">
<ion-icon icon="trash-outline" slot="icon-only"></ion-icon>
</ion-button>
</ion-item>

<ion-list-header class="ion-padding-top">
<ion-label>
<h2>{{ 'CONFIGURATIONS.BANNED_USERS' | translate }}</h2>
Expand Down
6 changes: 6 additions & 0 deletions front-end/src/app/tabs/configurations/configurations.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ export class ConfigurationsPage implements OnInit {
addOpportunitiesManager(): void {
this.addUserToList('opportunitiesManagersIds', 'ADD_OPPORTUNITIES_MANAGER');
}
addDashboardManager(): void {
this.addUserToList('dashboardManagersIds', 'ADD_DASHBOARD_MANAGER');
}
addBannedUser(): void {
this.addUserToList('bannedUsersIds', 'ADD_BANNED_USER');
}
Expand Down Expand Up @@ -76,6 +79,9 @@ export class ConfigurationsPage implements OnInit {
removeOpportunitiesManagerById(userId: string): void {
this.removeUserFromListById(userId, 'opportunitiesManagersIds');
}
removeDashboardManagerById(userId: string): void {
this.removeUserFromListById(userId, 'dashboardManagersIds');
}
removeBannedUserById(userId: string): void {
this.removeUserFromListById(userId, 'bannedUsersIds');
}
Expand Down
7 changes: 6 additions & 1 deletion front-end/src/app/tabs/dashboard/dashboard.page.html
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,12 @@ <h1 *ngIf="!app.isInMobileMode()">{{ 'DASHBOARD.USEFUL_LINKS' | translate }}</h1
</ion-row>
</ion-grid>
</ion-content>
<ion-fab slot="fixed" vertical="bottom" horizontal="end" *ngIf="app.user.isAdministrator">
<ion-fab
slot="fixed"
vertical="bottom"
horizontal="end"
*ngIf="(app.user.isAdministrator || app.user.canManageDashboard)"
>
<ion-fab-button color="ESNgreen" size="small" [title]="'COMMON.MANAGE' | translate" (click)="editMode = !editMode">
<ion-icon [icon]="editMode ?'checkmark' : 'build'"></ion-icon>
</ion-fab-button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ import { Deadline } from '@models/deadline.model';
</ion-label>
<ion-input [(ngModel)]="deadline.name"></ion-input>
</ion-item>
<ion-item [class.fieldHasError]="hasFieldAnError('action')">
<ion-item [class.fieldHasError]="hasFieldAnError('action')" counter>
<ion-label position="stacked">
{{ 'DEADLINES.ACTION' | translate }}
</ion-label>
<ion-input [(ngModel)]="deadline.action"></ion-input>
<ion-input [(ngModel)]="deadline.action" maxlength="15"></ion-input>
</ion-item>
<ion-item *ngIf="deadline.action" [class.fieldHasError]="hasFieldAnError('actionColor')">
<ion-label position="stacked">
Expand Down
Loading

0 comments on commit 3067c29

Please sign in to comment.