Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
softwaremagico committed Jun 20, 2024
2 parents b72be54 + 1896048 commit 468e0df
Show file tree
Hide file tree
Showing 12 changed files with 65 additions and 66 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[![GitHub commit activity](https://img.shields.io/github/commit-activity/y/softwaremagico/KendoTournamentManager)](https://github.com/softwaremagico/KendoTournamentManager)
[![GitHub last commit](https://img.shields.io/github/last-commit/softwaremagico/KendoTournamentManager)](https://github.com/softwaremagico/KendoTournamentManager)
[![CircleCI](https://circleci.com/gh/softwaremagico/KendoTournamentManager.svg?style=shield)](https://circleci.com/gh/softwaremagico/KendoTournamentManager)
[![Time](https://img.shields.io/badge/development-633.5h-blueviolet.svg)]()
[![Time](https://img.shields.io/badge/development-635h-blueviolet.svg)]()

[![Powered by](https://img.shields.io/badge/powered%20by%20java-orange.svg?logo=OpenJDK&logoColor=white)]()
[![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=kendo-tournament-backend&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=kendo-tournament-backend)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,15 +319,15 @@ public void updateUserPassword(@Parameter(description = "username", required = t
}
}

@PreAuthorize("hasAnyRole('ROLE_VIEWER', 'ROLE_EDITOR', 'ROLE_ADMIN')")
@PreAuthorize("hasAnyRole('ROLE_VIEWER', 'ROLE_EDITOR', 'ROLE_ADMIN', 'ROLE_PARTICIPANT', 'ROLE_GUEST')")
@Operation(summary = "Get roles.", security = @SecurityRequirement(name = "bearerAuth"))
@GetMapping(path = "/roles", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(value = HttpStatus.ACCEPTED)
public Set<String> getRoles(Authentication authentication, HttpServletRequest httpRequest) {
return authenticatedUserController.getRoles(authentication.getName());
}

@PreAuthorize("hasAnyRole('ROLE_VIEWER', 'ROLE_EDITOR', 'ROLE_ADMIN')")
@PreAuthorize("hasAnyRole('ROLE_VIEWER', 'ROLE_EDITOR', 'ROLE_ADMIN', 'ROLE_PARTICIPANT', 'ROLE_GUEST')")
@Operation(summary = "Renew JWT Token.", security = @SecurityRequirement(name = "bearerAuth"))
@GetMapping(path = "/jwt/renew", produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(value = HttpStatus.ACCEPTED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@
type="button">
<mat-icon color="primary">download_file</mat-icon>
</button>
<app-tournament-brackets #tournamentBracketsComponent class="tournament-brackets" [class.started] = "droppingDisabled" [tournament]="tournament"
<app-tournament-brackets #tournamentBracketsComponent class="tournament-brackets"
[class.started] = "droppingDisabled || !(RbacActivity.EDIT_GROUP | rbac : this.rbacService.getActivities())"
[tournament]="tournament"
[droppingDisabled]="droppingDisabled">
</app-tournament-brackets>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
}"
class="group"
[ngClass]="['group-' + index ,'group-' + level + '-' + index]">
<div class="group-title">Group {{index + 1}}</div>
<div class="group-title">{{ 'group'| translate }} {{ index + 1 }}</div>
<div class="group-content" [class]="'group-content-' + level + '-' + index" (cdkDropListDropped)="dropTeam($event)"
[cdkDropListData]="this.groupsByLevel.get(this.level)![this.index].teams" cdkDropList
[cdkDropListSortingDisabled]="false"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
padding: 0 10px;
line-height: 24px;
/* Rotate from top left corner (not default) */
writing-mode: sideways-lr;
writing-mode: vertical-rl;
transform: rotate(180deg);
text-align: center;
height: 100%;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ export class TournamentBracketsComponent implements OnInit {
}

ngOnInit(): void {
this.groupsUpdatedService.areGroupsUpdated.subscribe((_groups: Group[]): void => {
this.groupsByLevel = TournamentBracketsComponent.convert(_groups);
this.shiaijosByLevel = this.getShiaijos();
});
this.updateShiaijos();
this.groupsUpdatedService.areRelationsUpdated.subscribe((_relations: Map<number, {
src: number,
dest: number,
Expand All @@ -55,6 +52,13 @@ export class TournamentBracketsComponent implements OnInit {
});
}

private updateShiaijos(): void {
this.groupsUpdatedService.areGroupsUpdated.subscribe((_groups: Group[]): void => {
this.groupsByLevel = TournamentBracketsComponent.convert(_groups);
this.shiaijosByLevel = this.getShiaijos();
});
}

public static convert(groups: Group[]): Map<number, Group[]> {
const groupsByLevel: Map<number, Group[]> = new Map();
if (groups) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {DragDropModule} from "@angular/cdk/drag-drop";
import {GroupContainerComponent} from './group-container/group-container.component';
import {TeamCardModule} from "../../team-card/team-card.module";
import {ShiaijoModule} from "./shiaijo/shiaijo.module";
import {TranslateModule} from "@ngx-translate/core";


@NgModule({
Expand All @@ -16,7 +17,8 @@ import {ShiaijoModule} from "./shiaijo/shiaijo.module";
ArrowModule,
DragDropModule,
TeamCardModule,
ShiaijoModule
ShiaijoModule,
TranslateModule
]
})
export class TournamentBracketsModule {
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/app/interceptors/logged-in.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export class LoggedInService {
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
const context: string = state.url.substring(0, state.url.indexOf('?') > 0 ? state.url.indexOf('?') : state.url.length);
if (this.loginService.getJwtValue() || this.whiteListedPages.includes(context)) {
//Read roles from JWT if it is a returning user.
this.loginService.refreshDataFormJwt();
// JWT Token exists, is a registered participant.
this.isUserLoggedIn.next(true);
//return this.userLoginPageDependingOnRoles(context);
Expand Down
78 changes: 32 additions & 46 deletions frontend/src/app/services/login.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {Injectable} from '@angular/core';
import {HttpClient, HttpHeaders} from "@angular/common/http";
import {Observable} from "rxjs";
import {map, tap} from "rxjs/operators";
import {CookieService} from "ngx-cookie-service";

import {AuthenticatedUser} from "../models/authenticated-user";
import {AuthRequest} from "./models/auth-request";
Expand All @@ -11,6 +10,7 @@ import {Router} from "@angular/router";
import {ActivityService} from "./rbac/activity.service";
import {AuthGuestRequest} from "./models/auth-guest-request";
import {TemporalToken} from "./models/temporal-token";
import {UserRoles} from "./rbac/user-roles";

@Injectable({
providedIn: 'root'
Expand All @@ -22,7 +22,7 @@ export class LoginService {
private interval: NodeJS.Timeout | null;

constructor(private http: HttpClient, private environmentService: EnvironmentService,
private cookies: CookieService, private activityService: ActivityService, private router: Router) {
private activityService: ActivityService, private router: Router) {
if (this.getJwtExpirationValue() !== undefined && this.getJwtExpirationValue() > 0) {
this.autoRenewToken(this.getJwtValue(), (this.getJwtExpirationValue() - (new Date()).getTime()) - LoginService.JWT_RENEW_MARGIN,
(jwt: string, expires: number): void => {
Expand Down Expand Up @@ -75,33 +75,10 @@ export class LoginService {
}));
}

//Basic login for guests.
setUserSession(username: string, password: string): void {
this.login(username, password).subscribe({
next: (authenticatedUser: AuthenticatedUser): void => {
this.setJwtValue(authenticatedUser.jwt, authenticatedUser.expires);
this.autoRenewToken(authenticatedUser.jwt, (authenticatedUser.expires - (new Date()).getTime()) - LoginService.JWT_RENEW_MARGIN,
(): void => {
});
this.activityService.setRoles(authenticatedUser.roles);
localStorage.setItem('username', username);
},
error: (error): void => {
this.router.navigate(["/"]);
}
});
}

setGuestUserSession(tournamentId: number, callback: (token: string, expiration: number) => void): void {
this.loginAsGuest(tournamentId).subscribe({
next: (authenticatedUser: AuthenticatedUser): void => {
this.setJwtValue(authenticatedUser.jwt, authenticatedUser.expires);
this.autoRenewToken(authenticatedUser.jwt, (authenticatedUser.expires - (new Date()).getTime()) - LoginService.JWT_RENEW_MARGIN,
(): void => {
});
this.activityService.setRoles(authenticatedUser.roles);
localStorage.setItem('username', 'guest');
callback(authenticatedUser.jwt, authenticatedUser.expires);
this.setAuthenticatedUser(authenticatedUser, callback);
},
error: (): void => {
this.router.navigate(["/"]);
Expand All @@ -112,47 +89,56 @@ export class LoginService {
setParticipantUserSession(temporalToken: string, callback: (token: string, expiration: number) => void): void {
this.loginAsParticipant(temporalToken).subscribe({
next: (authenticatedUser: AuthenticatedUser): void => {
this.setJwtValue(authenticatedUser.jwt, authenticatedUser.expires);
this.autoRenewToken(authenticatedUser.jwt, (authenticatedUser.expires - (new Date()).getTime()) - LoginService.JWT_RENEW_MARGIN,
(): void => {
});
this.activityService.setRoles(authenticatedUser.roles);
localStorage.setItem('username', authenticatedUser.username);
callback(authenticatedUser.jwt, authenticatedUser.expires);
this.setAuthenticatedUser(authenticatedUser, callback);
},
error: (): void => {
this.router.navigate(["/"]);
}
});
}

setAuthenticatedUser(authenticatedUser: AuthenticatedUser, callback: (token: string, expiration: number) => void): void {
this.setJwtValue(authenticatedUser.jwt, authenticatedUser.expires);
this.autoRenewToken(authenticatedUser.jwt, (authenticatedUser.expires - (new Date()).getTime()) - LoginService.JWT_RENEW_MARGIN,
(): void => {
});
this.activityService.setRoles(authenticatedUser.roles);
localStorage.setItem('username', authenticatedUser.username);
callback(authenticatedUser.jwt, authenticatedUser.expires);
}

public refreshDataFormJwt(): void {
if (this.getJwtValue()) {
this.getUserRoles().subscribe((_roles: string[]): void => {
this.activityService.setRoles(UserRoles.getByKeys(_roles));
});
}
}

logout(): void {
this.cookies.delete("jwt");
this.cookies.delete("selectedLanguage");
this.cookies.delete("jwt_expires");
sessionStorage.clear();
localStorage.clear();
}

public setJwtValue(token: string, expires: number): void {
localStorage.setItem("jwt", token);
this.cookies.set("jwt", token);
this.cookies.set("jwt_expires", expires.toString());
localStorage.setItem("jwt_expires", expires.toString());
}

public getJwtValue(): string {
return this.cookies.get("jwt");
public getJwtValue(): string | null {
return localStorage.getItem("jwt");
}

getJwtExpirationValue(): number {
return Number(this.cookies.get("jwt_expires"));
return Number(localStorage.getItem("jwt_expires"));
}

public autoRenewToken(jwt: string, expiration: number, callback: (token: string, expiration: number) => void): void {
public autoRenewToken(jwt: string | null, expiration: number, callback: (token: string, expiration: number) => void): void {
if (this.interval != null) {
clearInterval(this.interval);
this.interval = null;
}
if (expiration > 0) {
if (expiration > 0 && jwt != null) {
this.setIntervalRenew(jwt, expiration, callback);
}
}
Expand Down Expand Up @@ -187,12 +173,12 @@ export class LoginService {
}, timeout);
}

getUserRoles(): Observable<String[]> {
getUserRoles(): Observable<string[]> {
const url: string = `${this.baseUrl}/roles`;
return this.http.get<String[]>(url)
return this.http.get<string[]>(url)
.pipe(
tap({
next: (_roles: String[]) => console.info(`Obtained '${_roles}' roles!`)
next: (_roles: string[]) => console.info(`Obtained '${_roles}' roles!`)
})
);
}
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/app/services/rbac/activity.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export class ActivityService {
this.activities = this.getActivities(roles);
}

public hasRoles(): boolean {
return this.activities.length > 0;
}

public isAllowed(activity: RbacActivity | undefined): boolean {
if (!activity || !this.activities) {
return false;
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/app/services/user-session.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class UserSessionService {
}
}

getSelectedParticipant() {
getSelectedParticipant(): string | null {
return sessionStorage.getItem("lastSelectedParticipant");
}

Expand Down Expand Up @@ -83,13 +83,13 @@ export class UserSessionService {

setNightMode(nightMode: boolean): void {
if (nightMode) {
sessionStorage.setItem("nightMode", nightMode.toString());
localStorage.setItem("nightMode", nightMode.toString());
} else {
sessionStorage.removeItem("nightMode");
localStorage.removeItem("nightMode");
}
}

getNightMode(): boolean {
return Boolean(sessionStorage.getItem("nightMode"));
return Boolean(localStorage.getItem("nightMode"));
}
}
8 changes: 3 additions & 5 deletions frontend/src/app/views/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,9 @@ export class LoginComponent {
login(): void {
this.loginService.login(this.loginForm.controls['username'].value, this.loginForm.controls['password'].value).subscribe({
next: (authenticatedUser: AuthenticatedUser): void => {
this.loginService.setJwtValue(authenticatedUser.jwt, authenticatedUser.expires);
this.loginService.autoRenewToken(authenticatedUser.jwt, (authenticatedUser.expires - (new Date()).getTime()) - LoginService.JWT_RENEW_MARGIN,
(jwt: string, expires: number): void => {
});
this.rbacService.setRoles(authenticatedUser.roles);
this.loginService.setAuthenticatedUser(authenticatedUser, (jwt: string, expires: number): void => {
});

const returnUrl = this.activatedRoute.snapshot.queryParams["returnUrl"];
this.router.navigate([returnUrl]);
this.messageService.infoMessage("userloggedInMessage");
Expand Down

0 comments on commit 468e0df

Please sign in to comment.