Add disconnection component.
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
package org.cerberus.controllers;
|
package org.cerberus.controllers;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonView;
|
||||||
import org.cerberus.entities.dto.SignUpDTO;
|
import org.cerberus.entities.dto.SignUpDTO;
|
||||||
|
import org.cerberus.entities.dto.View;
|
||||||
import org.cerberus.entities.persistence.User;
|
import org.cerberus.entities.persistence.User;
|
||||||
import org.cerberus.services.UserService;
|
import org.cerberus.services.UserService;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
@@ -24,9 +26,9 @@ public class UserController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
@ResponseStatus(NO_CONTENT)
|
@JsonView({View.UserDTO.class})
|
||||||
public void login(@RequestBody User user) {
|
public User login(@RequestBody User user) {
|
||||||
service.authenticate(user);
|
return service.authenticate(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/disconnection")
|
@GetMapping("/disconnection")
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ public final class View {
|
|||||||
private View() {}
|
private View() {}
|
||||||
public interface ApplicationDTO {}
|
public interface ApplicationDTO {}
|
||||||
public interface ConfigurationFileDTO {}
|
public interface ConfigurationFileDTO {}
|
||||||
|
public interface UserDTO {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.cerberus.entities.persistence;
|
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.Generated;
|
||||||
import org.hibernate.annotations.GenerationTime;
|
import org.hibernate.annotations.GenerationTime;
|
||||||
import org.hibernate.annotations.Proxy;
|
import org.hibernate.annotations.Proxy;
|
||||||
@@ -14,22 +16,25 @@ import java.util.UUID;
|
|||||||
@Proxy(lazy = false)
|
@Proxy(lazy = false)
|
||||||
public class User {
|
public class User {
|
||||||
@Id
|
@Id
|
||||||
|
@JsonView({View.UserDTO.class})
|
||||||
private UUID id;
|
private UUID id;
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
|
@JsonView({View.UserDTO.class})
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
|
@JsonView({View.UserDTO.class})
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
|
@JsonView({View.UserDTO.class})
|
||||||
private Boolean isAdmin = false;
|
private Boolean isAdmin = false;
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
@Generated(GenerationTime.ALWAYS)
|
|
||||||
private LocalDate inscriptionDate;
|
private LocalDate inscriptionDate;
|
||||||
|
|
||||||
@OneToMany(mappedBy = "user")
|
@OneToMany(mappedBy = "user")
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class UserService {
|
|||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void authenticate(User user) {
|
public User authenticate(User user) {
|
||||||
User authenticatedUser = checkCredentials(user.getEmail(), user.getPassword());
|
User authenticatedUser = checkCredentials(user.getEmail(), user.getPassword());
|
||||||
|
|
||||||
authenticationProvider.authenticate(new UsernamePasswordAuthenticationToken(
|
authenticationProvider.authenticate(new UsernamePasswordAuthenticationToken(
|
||||||
@@ -45,6 +45,8 @@ public class UserService {
|
|||||||
user.getPassword(),
|
user.getPassword(),
|
||||||
fetchGrantedAuthorities(authenticatedUser)
|
fetchGrantedAuthorities(authenticatedUser)
|
||||||
));
|
));
|
||||||
|
|
||||||
|
return authenticatedUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
User checkCredentials(String email, String password) {
|
User checkCredentials(String email, String password) {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { DisconnectionComponent } from './disconnection/disconnection.component';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { ServiceUnavailableComponent } from './service-unavailable/service-unavailable.component';
|
import { ServiceUnavailableComponent } from './service-unavailable/service-unavailable.component';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
@@ -5,6 +6,7 @@ import { Routes, RouterModule } from '@angular/router';
|
|||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: 'serviceUnavailable', component: ServiceUnavailableComponent },
|
{ path: 'serviceUnavailable', component: ServiceUnavailableComponent },
|
||||||
|
{ path: 'disconnection', component: DisconnectionComponent },
|
||||||
{ path: '', component: AppComponent }
|
{ path: '', component: AppComponent }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { NotificationElement } from './core/notifications/notification-element/n
|
|||||||
import { NotificationsComponent } from './core/notifications/notifications.component';
|
import { NotificationsComponent } from './core/notifications/notifications.component';
|
||||||
import { LoginComponent } from './login/login.component';
|
import { LoginComponent } from './login/login.component';
|
||||||
import { ServiceUnavailableComponent } from './service-unavailable/service-unavailable.component';
|
import { ServiceUnavailableComponent } from './service-unavailable/service-unavailable.component';
|
||||||
|
import { DisconnectionComponent } from './disconnection/disconnection.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@@ -24,7 +25,8 @@ import { ServiceUnavailableComponent } from './service-unavailable/service-unava
|
|||||||
LoginComponent,
|
LoginComponent,
|
||||||
NotificationElement,
|
NotificationElement,
|
||||||
NotificationsComponent,
|
NotificationsComponent,
|
||||||
ServiceUnavailableComponent
|
ServiceUnavailableComponent,
|
||||||
|
DisconnectionComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
@@ -35,11 +37,7 @@ import { ServiceUnavailableComponent } from './service-unavailable/service-unava
|
|||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
UserService,
|
UserService,
|
||||||
{
|
{ provide: HTTP_INTERCEPTORS, useClass: ServiceUnavailableInterceptor, multi: true }
|
||||||
provide: HTTP_INTERCEPTORS,
|
|
||||||
useClass: ServiceUnavailableInterceptor,
|
|
||||||
multi: true
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
bootstrap: [
|
bootstrap: [
|
||||||
AppComponent
|
AppComponent
|
||||||
|
|||||||
35
src/main/ts/src/app/core/services/auth.service.ts
Normal file
35
src/main/ts/src/app/core/services/auth.service.ts
Normal file
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { AuthService } from './auth.service';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
@@ -11,8 +12,8 @@ export class UserService {
|
|||||||
private httpClient: HttpClient
|
private httpClient: HttpClient
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
login(user: User): Observable<void> {
|
login(user: User): Observable<User> {
|
||||||
return this.httpClient.post<void>(`/api/users/login`, user);
|
return this.httpClient.post<User>(`/api/users/login`, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnection(): Observable<void> {
|
disconnection(): Observable<void> {
|
||||||
|
|||||||
29
src/main/ts/src/app/disconnection/disconnection.component.ts
Normal file
29
src/main/ts/src/app/disconnection/disconnection.component.ts
Normal file
@@ -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(['/']);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,10 +11,14 @@
|
|||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<span id="right-area">
|
<span id="right-area">
|
||||||
<button mdbBtn class="flat rounded-pill" (click)="loginForm.show()" mdbWavesEffect>
|
<button mdbBtn class="flat rounded-pill" (click)="loginForm.show()" *ngIf="!isAuthenticated()" mdbWavesEffect>
|
||||||
<i class="fa fa-sign-in-alt"></i>
|
<i class="fa fa-sign-in-alt"></i>
|
||||||
Connexion
|
Connexion
|
||||||
</button>
|
</button>
|
||||||
|
<a [routerLink]="['/disconnection']" mdbBtn id="disconnection-btn" class="flat rounded-pill" *ngIf="isAuthenticated()" mdbWavesEffect>
|
||||||
|
<i class="fa fa-sign-out-alt"></i>
|
||||||
|
Déconnexion
|
||||||
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</header>
|
</header>
|
||||||
<app-login #loginForm></app-login>
|
<app-login #loginForm></app-login>
|
||||||
|
|||||||
@@ -35,10 +35,14 @@ header {
|
|||||||
top: 5px;
|
top: 5px;
|
||||||
right: 15px;
|
right: 15px;
|
||||||
|
|
||||||
button {
|
.rounded-pill {
|
||||||
padding-right: 1.14rem;
|
padding-right: 1.14rem;
|
||||||
padding-left: 1.14rem;
|
padding-left: 1.14rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#disconnection-btn:hover {
|
||||||
|
background-color: #b71c1c;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { AuthService } from './../core/services/auth.service';
|
||||||
import { NotificationsComponent } from './../core/notifications/notifications.component';
|
import { NotificationsComponent } from './../core/notifications/notifications.component';
|
||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
import { LoginComponent } from '../login/login.component';
|
import { LoginComponent } from '../login/login.component';
|
||||||
@@ -7,15 +8,14 @@ import { LoginComponent } from '../login/login.component';
|
|||||||
templateUrl: './header.component.html',
|
templateUrl: './header.component.html',
|
||||||
styleUrls: ['./header.component.scss']
|
styleUrls: ['./header.component.scss']
|
||||||
})
|
})
|
||||||
export class HeaderComponent implements OnInit {
|
export class HeaderComponent {
|
||||||
@ViewChild('loginForm', {static: true}) loginForm: LoginComponent;
|
@ViewChild('loginForm', {static: true}) loginForm: LoginComponent;
|
||||||
|
|
||||||
constructor() { }
|
constructor(
|
||||||
|
private authService: AuthService
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
isAuthenticated(): boolean {
|
||||||
}
|
return this.authService.isAuthenticated();
|
||||||
|
|
||||||
helloWorld() {
|
|
||||||
NotificationsComponent.info('Hello world!');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { AuthService } from './../core/services/auth.service';
|
||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||||
import { User } from './../core/entities';
|
import { User } from './../core/entities';
|
||||||
import { ModalDirective } from 'angular-bootstrap-md';
|
import { ModalDirective } from 'angular-bootstrap-md';
|
||||||
@@ -9,21 +10,19 @@ import { NotificationsComponent } from '../core/notifications/notifications.comp
|
|||||||
templateUrl: './login.component.html',
|
templateUrl: './login.component.html',
|
||||||
styleUrls: ['./login.component.scss']
|
styleUrls: ['./login.component.scss']
|
||||||
})
|
})
|
||||||
export class LoginComponent implements OnInit {
|
export class LoginComponent {
|
||||||
model: User = User.new();
|
model: User = User.new();
|
||||||
@ViewChild('loginModal', {static: true}) loginModal: ModalDirective;
|
@ViewChild('loginModal', {static: true}) loginModal: ModalDirective;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private userService: UserService
|
private userService: UserService,
|
||||||
|
private authService: AuthService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit(): void {
|
onSubmit(): void {
|
||||||
this.userService.login(this.model).subscribe(() => {
|
this.userService.login(this.model).subscribe(user => {
|
||||||
NotificationsComponent.success('Connexion réussie.');
|
NotificationsComponent.success('Connexion réussie.');
|
||||||
|
this.authService.setAuthenticated(user);
|
||||||
this.loginModal.hide();
|
this.loginModal.hide();
|
||||||
}, ex => {
|
}, ex => {
|
||||||
console.error('Error during login attempt: ', ex);
|
console.error('Error during login attempt: ', ex);
|
||||||
|
|||||||
Reference in New Issue
Block a user