Skip to content

Commit

Permalink
refactor: deprecate team-authorization.service and move logic to sess…
Browse files Browse the repository at this point in the history
…ion (#377)
  • Loading branch information
jrassa authored May 10, 2024
1 parent e3fed12 commit bfe93f4
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 50 deletions.
27 changes: 24 additions & 3 deletions src/app/core/auth/session.model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { Role } from './role.model';
import { User } from './user.model';

type Team = { _id: string };
type TeamRole = { role: string };

export class Session {
public user?: User;

Expand All @@ -26,6 +29,9 @@ export class Session {
return externalRoles.indexOf(role) !== -1;
}

/**
* User Role utilities
*/
public hasRole(role: string | Role): boolean {
role = this.roleToString(role);

Expand All @@ -46,14 +52,29 @@ export class Session {
}

public isUser(): boolean {
return this.hasRole(Role.USER.role);
return this.hasRole(Role.USER);
}

public isAdmin(): boolean {
return this.hasRole(Role.ADMIN.role);
return this.hasRole(Role.ADMIN);
}

/**
* Team Role utilities
*/
public hasTeamRole(team: Pick<Team, '_id'>, role: string | TeamRole): boolean {
return this.user?.getTeamRole(team) === this.roleToString(role);
}

public hasSomeTeamRoles(team: Pick<Team, '_id'>, roles: Array<string | TeamRole>): boolean {
return roles.some((role: string | TeamRole) => this.hasTeamRole(team, role));
}

public hasEveryTeamRole(team: Pick<Team, '_id'>, roles: Array<string | TeamRole>): boolean {
return roles.every((role: string | TeamRole) => this.hasTeamRole(team, role));
}

private roleToString(role: string | Role) {
private roleToString(role: string | Role | TeamRole) {
if (typeof role !== 'string') {
return role.role;
}
Expand Down
9 changes: 8 additions & 1 deletion src/app/core/auth/user.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class User {

public externalRoles: string[] = [];
public externalGroups: string[] = [];
public teams: any[] = [];
public teams: { _id: string; role: string }[] = [];
public canMasquerade = false;
public bypassAccessCheck = false;

Expand Down Expand Up @@ -46,6 +46,13 @@ export class User {
public setEua(eua?: EndUserAgreement) {
this.eua = eua;
}

public getTeamRole(team: { _id: string }): string | undefined {
const teams = this?.teams ?? [];

// Find the role of this user in the team
return teams.find((t) => t._id === team._id)?.role;
}
}

export class EditUser extends User {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { NgIf } from '@angular/common';
import { Directive, effect, inject, input } from '@angular/core';

import { APP_SESSION } from '../../tokens';
import { TeamAuthorizationService } from '../team-authorization.service';
import { TeamRole } from '../team-role.model';
import { Team } from '../team.model';

Expand All @@ -18,7 +17,6 @@ import { Team } from '../team.model';
})
export class HasSomeTeamRolesDirective {
readonly #ngIfDirective = inject(NgIf);
readonly #teamAuthorizationService = inject(TeamAuthorizationService);
readonly #session = inject(APP_SESSION);

readonly team = input.required<Pick<Team, '_id'>>({ alias: 'hasSomeTeamRoles' });
Expand All @@ -34,8 +32,7 @@ export class HasSomeTeamRolesDirective {

protected checkPermission(): boolean {
return (
this.#session().isAdmin() ||
this.#teamAuthorizationService.hasSomeRoles(this.team(), this.roles())
this.#session().isAdmin() || this.#session().hasSomeTeamRoles(this.team(), this.roles())
);
}

Expand Down
7 changes: 1 addition & 6 deletions src/app/core/teams/directives/has-team-role.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { NgIf } from '@angular/common';
import { Directive, effect, inject, input } from '@angular/core';

import { APP_SESSION } from '../../tokens';
import { TeamAuthorizationService } from '../team-authorization.service';
import { TeamRole } from '../team-role.model';
import { Team } from '../team.model';

Expand All @@ -18,7 +17,6 @@ import { Team } from '../team.model';
})
export class HasTeamRoleDirective {
readonly #ngIfDirective = inject(NgIf);
readonly #teamAuthorizationService = inject(TeamAuthorizationService);
readonly #session = inject(APP_SESSION);

readonly team = input.required<Pick<Team, '_id'>>({ alias: 'hasTeamRole' });
Expand All @@ -33,10 +31,7 @@ export class HasTeamRoleDirective {
}

protected checkPermission(): boolean {
return (
this.#session().isAdmin() ||
this.#teamAuthorizationService.hasRole(this.team(), this.role())
);
return this.#session().isAdmin() || this.#session().hasTeamRole(this.team(), this.role());
}

private updateNgIf() {
Expand Down
33 changes: 13 additions & 20 deletions src/app/core/teams/team-authorization.service.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,47 @@
import { Injectable, computed, inject } from '@angular/core';
import { Injectable, inject } from '@angular/core';

import { APP_SESSION } from '../tokens';
import { TeamMember } from './team-member.model';
import { TeamRole } from './team-role.model';
import { Team } from './team.model';

/**
* @deprecated Implementation moved to Session.
*/
@Injectable({
providedIn: 'root'
})
export class TeamAuthorizationService {
readonly #session = inject(APP_SESSION);
readonly #member = computed(() => new TeamMember(this.#session().user));

public hasRole(team: Pick<Team, '_id'>, role: string | TeamRole): boolean {
return this.#member().getRoleInTeam(team) === this.roleToString(role);
return this.#session().hasTeamRole(team, role);
}

public hasAnyRole(team: Pick<Team, '_id'>): boolean {
return TeamRole.ROLES.some((role: TeamRole) => this.hasRole(team, role));
return this.#session().hasSomeTeamRoles(team, TeamRole.ROLES);
}

public hasSomeRoles(team: Pick<Team, '_id'>, roles: Array<string | TeamRole>): boolean {
return roles.some((role: string | TeamRole) => this.hasRole(team, role));
return this.#session().hasSomeTeamRoles(team, roles);
}

public hasEveryRole(team: Pick<Team, '_id'>, roles: Array<string | TeamRole>): boolean {
return roles.every((role: string | TeamRole) => this.hasRole(team, role));
// return roles.reduce( (p: boolean, c: string) => p && this.hasRole(c), true);
return this.#session().hasEveryTeamRole(team, roles);
}

public isMember(team: Pick<Team, '_id'>): boolean {
return this.hasRole(team, TeamRole.MEMBER.role);
return this.#session().hasTeamRole(team, TeamRole.MEMBER);
}

public isEditor(team: Pick<Team, '_id'>): boolean {
return this.hasRole(team, TeamRole.EDITOR.role);
}

public canManageResources(team: Pick<Team, '_id'>): boolean {
return this.isAdmin(team) || this.isEditor(team);
return this.#session().hasTeamRole(team, TeamRole.EDITOR);
}

public isAdmin(team: Pick<Team, '_id'>): boolean {
return this.hasRole(team, TeamRole.ADMIN.role);
return this.#session().hasRole(TeamRole.ADMIN);
}

private roleToString(role: string | TeamRole) {
if (typeof role !== 'string') {
return role?.role;
}
return role;
public canManageResources(team: Pick<Team, '_id'>): boolean {
return this.#session().hasSomeTeamRoles(team, [TeamRole.EDITOR, TeamRole.ADMIN]);
}
}
14 changes: 1 addition & 13 deletions src/app/core/teams/team-member.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,12 @@ export class TeamMember extends User {
this.explicit = (model.teams?.length ?? 0) > 0;

if (team) {
this.role = this.getRoleInTeam(team) ?? TeamRole.MEMBER.role;
this.role = this.getTeamRole(team) ?? TeamRole.MEMBER.role;
this.roleDisplay = TeamRole.getDisplay(this.role);

this.explicit = model.teams.map((t: any) => t._id).includes(team._id);
}

return this;
}

public getRoleInTeam(team: Pick<Team, '_id'>): string | null {
const teams = this?.teams ?? [];
// Find the role of this user in the team
const ndx = teams.findIndex((t: any) => t._id === team._id);

if (-1 !== ndx) {
return teams[ndx].role;
}

return null;
}
}
5 changes: 2 additions & 3 deletions src/app/core/teams/teams.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { AbstractEntityService, ServiceMethod } from '../../common/abstract-enti
import { NULL_PAGING_RESULTS, PagingOptions, PagingResults } from '../../common/paging.model';
import { User } from '../auth';
import { APP_SESSION } from '../tokens';
import { TeamAuthorizationService } from './team-authorization.service';
import { TeamMember } from './team-member.model';
import { TeamRole } from './team-role.model';
import { Team } from './team.model';

export interface AddedMember {
Expand All @@ -36,7 +36,6 @@ export const teamResolver: ResolveFn<Team | null> = (
})
export class TeamsService extends AbstractEntityService<Team> {
#session = inject(APP_SESSION);
#teamAuthorizationService = inject(TeamAuthorizationService);

constructor() {
super({
Expand Down Expand Up @@ -132,7 +131,7 @@ export class TeamsService extends AbstractEntityService<Team> {
teams.filter(
(team) =>
this.#session().isAdmin() ||
this.#teamAuthorizationService.canManageResources(team)
this.#session().hasSomeTeamRoles(team, [TeamRole.EDITOR, TeamRole.ADMIN])
)
)
);
Expand Down

0 comments on commit bfe93f4

Please sign in to comment.