From 78701a4950a72f314acb38fe55b4902f2f89d1e3 Mon Sep 17 00:00:00 2001 From: florian Date: Fri, 6 Sep 2019 22:22:48 +0200 Subject: [PATCH] Add disconnection component. --- .../cerberus/controllers/UserController.java | 8 +++-- .../java/org/cerberus/entities/dto/View.java | 1 + .../cerberus/entities/persistence/User.java | 7 +++- .../org/cerberus/services/UserService.java | 4 ++- src/main/ts/src/app/app-routing.module.ts | 2 ++ src/main/ts/src/app/app.module.ts | 10 +++--- .../ts/src/app/core/services/auth.service.ts | 35 +++++++++++++++++++ .../ts/src/app/core/services/user.service.ts | 5 +-- .../disconnection/disconnection.component.ts | 29 +++++++++++++++ .../ts/src/app/header/header.component.html | 6 +++- .../ts/src/app/header/header.component.scss | 6 +++- .../ts/src/app/header/header.component.ts | 14 ++++---- src/main/ts/src/app/login/login.component.ts | 13 ++++--- 13 files changed, 111 insertions(+), 29 deletions(-) create mode 100644 src/main/ts/src/app/core/services/auth.service.ts create mode 100644 src/main/ts/src/app/disconnection/disconnection.component.ts diff --git a/src/main/java/org/cerberus/controllers/UserController.java b/src/main/java/org/cerberus/controllers/UserController.java index 08108d4..4282a19 100644 --- a/src/main/java/org/cerberus/controllers/UserController.java +++ b/src/main/java/org/cerberus/controllers/UserController.java @@ -1,6 +1,8 @@ package org.cerberus.controllers; +import com.fasterxml.jackson.annotation.JsonView; import org.cerberus.entities.dto.SignUpDTO; +import org.cerberus.entities.dto.View; import org.cerberus.entities.persistence.User; import org.cerberus.services.UserService; import org.springframework.security.core.Authentication; @@ -24,9 +26,9 @@ public class UserController { } @PostMapping("/login") - @ResponseStatus(NO_CONTENT) - public void login(@RequestBody User user) { - service.authenticate(user); + @JsonView({View.UserDTO.class}) + public User login(@RequestBody User user) { + return service.authenticate(user); } @GetMapping("/disconnection") diff --git a/src/main/java/org/cerberus/entities/dto/View.java b/src/main/java/org/cerberus/entities/dto/View.java index e50a9ce..b470d59 100644 --- a/src/main/java/org/cerberus/entities/dto/View.java +++ b/src/main/java/org/cerberus/entities/dto/View.java @@ -4,4 +4,5 @@ public final class View { private View() {} public interface ApplicationDTO {} public interface ConfigurationFileDTO {} + public interface UserDTO {} } diff --git a/src/main/java/org/cerberus/entities/persistence/User.java b/src/main/java/org/cerberus/entities/persistence/User.java index 39505d5..06645bc 100644 --- a/src/main/java/org/cerberus/entities/persistence/User.java +++ b/src/main/java/org/cerberus/entities/persistence/User.java @@ -1,5 +1,7 @@ package org.cerberus.entities.persistence; +import com.fasterxml.jackson.annotation.JsonView; +import org.cerberus.entities.dto.View; import org.hibernate.annotations.Generated; import org.hibernate.annotations.GenerationTime; import org.hibernate.annotations.Proxy; @@ -14,22 +16,25 @@ import java.util.UUID; @Proxy(lazy = false) public class User { @Id + @JsonView({View.UserDTO.class}) private UUID id; @Column(nullable = false) + @JsonView({View.UserDTO.class}) private String name; @Column(nullable = false) + @JsonView({View.UserDTO.class}) private String email; @Column(nullable = false) private String password; @Column(nullable = false) + @JsonView({View.UserDTO.class}) private Boolean isAdmin = false; @Column(nullable = false) - @Generated(GenerationTime.ALWAYS) private LocalDate inscriptionDate; @OneToMany(mappedBy = "user") diff --git a/src/main/java/org/cerberus/services/UserService.java b/src/main/java/org/cerberus/services/UserService.java index 04a957c..2b5c1b2 100644 --- a/src/main/java/org/cerberus/services/UserService.java +++ b/src/main/java/org/cerberus/services/UserService.java @@ -37,7 +37,7 @@ public class UserService { this.repository = repository; } - public void authenticate(User user) { + public User authenticate(User user) { User authenticatedUser = checkCredentials(user.getEmail(), user.getPassword()); authenticationProvider.authenticate(new UsernamePasswordAuthenticationToken( @@ -45,6 +45,8 @@ public class UserService { user.getPassword(), fetchGrantedAuthorities(authenticatedUser) )); + + return authenticatedUser; } User checkCredentials(String email, String password) { diff --git a/src/main/ts/src/app/app-routing.module.ts b/src/main/ts/src/app/app-routing.module.ts index f49aa1a..1e73bac 100644 --- a/src/main/ts/src/app/app-routing.module.ts +++ b/src/main/ts/src/app/app-routing.module.ts @@ -1,3 +1,4 @@ +import { DisconnectionComponent } from './disconnection/disconnection.component'; import { AppComponent } from './app.component'; import { ServiceUnavailableComponent } from './service-unavailable/service-unavailable.component'; import { NgModule } from '@angular/core'; @@ -5,6 +6,7 @@ import { Routes, RouterModule } from '@angular/router'; const routes: Routes = [ { path: 'serviceUnavailable', component: ServiceUnavailableComponent }, + { path: 'disconnection', component: DisconnectionComponent }, { path: '', component: AppComponent } ]; diff --git a/src/main/ts/src/app/app.module.ts b/src/main/ts/src/app/app.module.ts index d2dd112..481304e 100644 --- a/src/main/ts/src/app/app.module.ts +++ b/src/main/ts/src/app/app.module.ts @@ -15,6 +15,7 @@ import { NotificationElement } from './core/notifications/notification-element/n import { NotificationsComponent } from './core/notifications/notifications.component'; import { LoginComponent } from './login/login.component'; import { ServiceUnavailableComponent } from './service-unavailable/service-unavailable.component'; +import { DisconnectionComponent } from './disconnection/disconnection.component'; @NgModule({ declarations: [ @@ -24,7 +25,8 @@ import { ServiceUnavailableComponent } from './service-unavailable/service-unava LoginComponent, NotificationElement, NotificationsComponent, - ServiceUnavailableComponent + ServiceUnavailableComponent, + DisconnectionComponent ], imports: [ AppRoutingModule, @@ -35,11 +37,7 @@ import { ServiceUnavailableComponent } from './service-unavailable/service-unava ], providers: [ UserService, - { - provide: HTTP_INTERCEPTORS, - useClass: ServiceUnavailableInterceptor, - multi: true - } + { provide: HTTP_INTERCEPTORS, useClass: ServiceUnavailableInterceptor, multi: true } ], bootstrap: [ AppComponent diff --git a/src/main/ts/src/app/core/services/auth.service.ts b/src/main/ts/src/app/core/services/auth.service.ts new file mode 100644 index 0000000..7cbd643 --- /dev/null +++ b/src/main/ts/src/app/core/services/auth.service.ts @@ -0,0 +1,35 @@ +import { Injectable } from '@angular/core'; +import { User } from '../entities'; + +const PARAM_USER = 'user'; + +@Injectable({ + providedIn: 'root' +}) +export class AuthService { + constructor() {} + + public setAuthenticated(user: User): void { + this.setUser(user); + } + + public setAnonymous(): void { + localStorage.clear(); + } + + public isAuthenticated(): boolean { + return this.getUser() != null; + } + + public isAdmin(): boolean { + return false; + } + + private setUser(user: User): void { + localStorage.setItem(PARAM_USER, JSON.stringify(user)); + } + + public getUser(): User { + return JSON.parse(localStorage.getItem(PARAM_USER)); + } +} diff --git a/src/main/ts/src/app/core/services/user.service.ts b/src/main/ts/src/app/core/services/user.service.ts index 8afa7f1..0872bef 100644 --- a/src/main/ts/src/app/core/services/user.service.ts +++ b/src/main/ts/src/app/core/services/user.service.ts @@ -1,3 +1,4 @@ +import { AuthService } from './auth.service'; import { Observable } from 'rxjs'; import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; @@ -11,8 +12,8 @@ export class UserService { private httpClient: HttpClient ) {} - login(user: User): Observable { - return this.httpClient.post(`/api/users/login`, user); + login(user: User): Observable { + return this.httpClient.post(`/api/users/login`, user); } disconnection(): Observable { diff --git a/src/main/ts/src/app/disconnection/disconnection.component.ts b/src/main/ts/src/app/disconnection/disconnection.component.ts new file mode 100644 index 0000000..6635a62 --- /dev/null +++ b/src/main/ts/src/app/disconnection/disconnection.component.ts @@ -0,0 +1,29 @@ +import { Router } from '@angular/router'; +import { AuthService } from './../core/services/auth.service'; +import { UserService } from './../core/services/user.service'; +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-disconnection', + template: '' +}) +export class DisconnectionComponent implements OnInit { + content = 'Déconnexion...'; + + constructor( + private authService: AuthService, + private router: Router, + private userService: UserService + ) {} + + ngOnInit(): void { + this.userService.disconnection().subscribe(() => { + this.authService.setAnonymous(); + }, error => { + console.error('Error during disconnection: ', error); + this.content = 'Une erreur est survenue lors de la déconnexion.'; + }, () => { + this.router.navigate(['/']); + }); + } +} diff --git a/src/main/ts/src/app/header/header.component.html b/src/main/ts/src/app/header/header.component.html index 7b880c5..123504d 100644 --- a/src/main/ts/src/app/header/header.component.html +++ b/src/main/ts/src/app/header/header.component.html @@ -11,10 +11,14 @@ - + + + Déconnexion + diff --git a/src/main/ts/src/app/header/header.component.scss b/src/main/ts/src/app/header/header.component.scss index c4c0245..53aec11 100644 --- a/src/main/ts/src/app/header/header.component.scss +++ b/src/main/ts/src/app/header/header.component.scss @@ -35,10 +35,14 @@ header { top: 5px; right: 15px; - button { + .rounded-pill { padding-right: 1.14rem; padding-left: 1.14rem; } + + #disconnection-btn:hover { + background-color: #b71c1c; + } } } diff --git a/src/main/ts/src/app/header/header.component.ts b/src/main/ts/src/app/header/header.component.ts index 620e720..515a021 100644 --- a/src/main/ts/src/app/header/header.component.ts +++ b/src/main/ts/src/app/header/header.component.ts @@ -1,3 +1,4 @@ +import { AuthService } from './../core/services/auth.service'; import { NotificationsComponent } from './../core/notifications/notifications.component'; import { Component, OnInit, ViewChild } from '@angular/core'; import { LoginComponent } from '../login/login.component'; @@ -7,15 +8,14 @@ import { LoginComponent } from '../login/login.component'; templateUrl: './header.component.html', styleUrls: ['./header.component.scss'] }) -export class HeaderComponent implements OnInit { +export class HeaderComponent { @ViewChild('loginForm', {static: true}) loginForm: LoginComponent; - constructor() { } + constructor( + private authService: AuthService + ) {} - ngOnInit() { - } - - helloWorld() { - NotificationsComponent.info('Hello world!'); + isAuthenticated(): boolean { + return this.authService.isAuthenticated(); } } diff --git a/src/main/ts/src/app/login/login.component.ts b/src/main/ts/src/app/login/login.component.ts index f3d865c..a163921 100644 --- a/src/main/ts/src/app/login/login.component.ts +++ b/src/main/ts/src/app/login/login.component.ts @@ -1,3 +1,4 @@ +import { AuthService } from './../core/services/auth.service'; import { Component, OnInit, ViewChild } from '@angular/core'; import { User } from './../core/entities'; import { ModalDirective } from 'angular-bootstrap-md'; @@ -9,21 +10,19 @@ import { NotificationsComponent } from '../core/notifications/notifications.comp templateUrl: './login.component.html', styleUrls: ['./login.component.scss'] }) -export class LoginComponent implements OnInit { +export class LoginComponent { model: User = User.new(); @ViewChild('loginModal', {static: true}) loginModal: ModalDirective; constructor( - private userService: UserService + private userService: UserService, + private authService: AuthService ) {} - ngOnInit() { - - } - onSubmit(): void { - this.userService.login(this.model).subscribe(() => { + this.userService.login(this.model).subscribe(user => { NotificationsComponent.success('Connexion réussie.'); + this.authService.setAuthenticated(user); this.loginModal.hide(); }, ex => { console.error('Error during login attempt: ', ex);