Feature 10941: User Management Enhancements
[osm/NG-UI.git] / src / services / AuthenticationService.ts
1 /*
2  Copyright 2020 TATA ELXSI
3
4  Licensed under the Apache License, Version 2.0 (the 'License');
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7
8     http://www.apache.org/licenses/LICENSE-2.0
9
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15
16  Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
17  */
18 /**
19  * @file Auth service
20  */
21 import { isNullOrUndefined } from 'util';
22 import { HttpHeaders } from '@angular/common/http';
23 import { Injectable, Injector } from '@angular/core';
24 import { Router } from '@angular/router';
25 import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
26 import { Idle } from '@ng-idle/core';
27 import { APIURLHEADER, ERRORDATA } from 'CommonModel';
28 import { environment } from 'environment';
29 import { BehaviorSubject, Observable } from 'rxjs';
30 import { map } from 'rxjs/operators';
31 import { SharedService } from 'SharedService';
32 import { ProjectModel } from '../models/VNFDModel';
33 import { RestService } from './RestService';
34
35 /**
36  * An Injectable is a class adorned with the @Injectable decorator function.
37  * @Injectable takes a metadata object that tells Angular how to compile and run module code
38  */
39 @Injectable()
40 export class AuthenticationService {
41     /** To inject services @public */
42     public injector: Injector;
43
44     /** Instance for modal service @public */
45     public modalService: NgbModal;
46
47     /** Handle 401 response for multiple API calls */
48     public handle401: boolean = true;
49
50     /** contains return URL link @public */
51     public returnUrl: string;
52
53     /** Holds the username in condition of type BehaviorSubject<string> @public */
54     public userName: BehaviorSubject<string> = new BehaviorSubject<string>('');
55
56     /** Holds the projectname in condition of type BehaviorSubject<string> @public */
57     public projectName$: BehaviorSubject<string> = new BehaviorSubject<string>('');
58
59     /** Holds the instance of router class @private */
60     private router: Router;
61
62     /** Holds the logged in condition of type BehaviorSubject<boolean> @private */
63     private loggedIn: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
64
65     /** Holds the change password in condition of type BehaviorSubject<boolean> @private */
66     private changePassword: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
67
68     /** Hold Rest Service Objects */
69     private restService: RestService;
70
71     /** Holds auth payloads @private */
72     private payLoad: {};
73
74     /** Holds header options for auth service @private */
75     private httpOptions: HttpHeaders;
76
77     /** handle idle time out service @private */
78     private idle: Idle;
79
80     /** Contains all methods related to shared @private */
81     private sharedService: SharedService;
82
83     /** create the instance of the component */
84     constructor(injector: Injector) {
85         this.injector = injector;
86         this.router = this.injector.get(Router);
87         this.restService = this.injector.get(RestService);
88         this.modalService = this.injector.get(NgbModal);
89         this.idle = this.injector.get(Idle);
90         this.sharedService = this.injector.get(SharedService);
91         if (localStorage.getItem('username') !== null) {
92             this.loggedIn.next(true);
93             this.changePassword.next(false);
94         } else if (localStorage.getItem('firstLogin') !== null) {
95             this.changePassword.next(true);
96             this.loggedIn.next(false);
97         } else {
98             this.loggedIn.next(false);
99         }
100         this.userName.next(localStorage.getItem('username'));
101         this.redirectToPage();
102     }
103
104     /**
105      * Get method for  Observable loggedIn
106      */
107     get isLoggedIn(): Observable<boolean> {
108         return this.loggedIn.asObservable();
109     }
110
111     /**
112      * Get method for  Observable changepassword
113      */
114     get isChangePassword(): Observable<boolean> {
115         return this.changePassword.asObservable();
116     }
117
118     /**
119      * Get method for Observable Username
120      */
121     get username(): Observable<string> {
122         return this.userName.asObservable();
123     }
124
125     /** Get method for project name */
126     get ProjectName(): Observable<string> {
127         return this.projectName$.asObservable();
128     }
129
130     /**
131      * Send request and authenticate the user
132      * @param user of type User
133      */
134     public login(username: string, password: string): Observable<{}> {
135         this.setHeader();
136         this.setPayLoad(username, password);
137         const apiURLHeader: APIURLHEADER = {
138             url: environment.GENERATETOKEN_URL,
139             httpOptions: { headers: this.httpOptions }
140         };
141         return this.restService.postResource(apiURLHeader, this.payLoad)
142             .pipe(map((data: ProjectModel): BehaviorSubject<boolean> => {
143                 if (data.message === 'change_password') {
144                     localStorage.setItem('firstLogin', 'true');
145                     localStorage.setItem('id_token', data.id);
146                     localStorage.setItem('user_id', data.user_id);
147                     this.idle.watch(true);
148                     this.changePassword.next(true);
149                     this.loggedIn.next(false);
150                     return this.changePassword;
151                 } else {
152                     this.setLocalStorage(data);
153                     this.idle.watch(true);
154                     this.loggedIn.next(true);
155                     this.handle401 = true;
156                     this.userName.next(data.username);
157                     return this.loggedIn;
158                 }
159             }, (error: ERRORDATA): void => { this.restService.handleError(error, 'post'); }
160             ));
161     }
162
163     /** Set headers for auth session @public */
164     public setHeader(): void {
165         this.httpOptions = new HttpHeaders({
166             'Content-Type': 'application/json; charset=UTF-8',
167             Accept: 'application/json',
168             'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
169         });
170     }
171
172     /** Set payloads for auth session @public  */
173     public setPayLoad(username: string, password: string): void {
174         this.payLoad = JSON.stringify({
175             username,
176             password
177         });
178     }
179
180     /** set local storage on auth process @public */
181     public setLocalStorage(data: ProjectModel): void {
182         localStorage.setItem('id_token', data.id);
183         localStorage.setItem('expires', data.expires.toString());
184         localStorage.setItem('username', data.username);
185         localStorage.setItem('isAdmin', (data.admin) ? 'true' : 'false');
186         localStorage.setItem('project_id', data.project_id);
187         localStorage.setItem('project', data.project_name);
188         localStorage.setItem('token_state', data.id);
189         localStorage.setItem('user_id', data.user_id);
190         localStorage.setItem('user_show', String(data.user_show));
191         localStorage.setItem('admin_show', String(data.admin_show));
192         localStorage.setItem('last_login', this.sharedService.convertEpochTime(!isNullOrUndefined(data.last_login) ? data.last_login : null));
193         localStorage.setItem('failed_count', data.login_count);
194         this.projectName$.next(data.project_name);
195     }
196     /** Destory tokens API response handling @public */
197     public logoutResponse(): void {
198         this.loggedIn.next(false);
199         this.changePassword.next(false);
200         const langCode: string = localStorage.getItem('languageCode');
201         const redirecturl: string = isNullOrUndefined(localStorage.getItem('returnUrl')) ? '/' : localStorage.getItem('returnUrl');
202         const osmVersion: string = isNullOrUndefined(localStorage.getItem('osmVersion')) ? '' : localStorage.getItem('osmVersion');
203         localStorage.clear();
204         localStorage.setItem('languageCode', langCode);
205         localStorage.setItem('returnUrl', redirecturl);
206         localStorage.setItem('token_state', null);
207         localStorage.setItem('osmVersion', osmVersion);
208         this.idle.stop();
209         this.router.navigate(['login']).catch((): void => {
210             // Catch Navigation Error
211         });
212     }
213     /**
214      * Logout the user & clearing the token.
215      */
216     public logout(): void {
217         this.returnUrl = this.router.url;
218         localStorage.setItem('returnUrl', this.returnUrl);
219         this.modalService.dismissAll();
220         this.destoryToken();
221     }
222     /** Destory tokens on logout @public */
223     public destoryToken(): void {
224         const tokenID: string = localStorage.getItem('id_token');
225         if (tokenID !== null) {
226             const deletingURl: string = environment.GENERATETOKEN_URL + '/' + tokenID;
227             this.restService.deleteResource(deletingURl).subscribe((res: {}): void => {
228                 this.logoutResponse();
229             }, (error: ERRORDATA): void => {
230                 this.restService.handleError(error, 'delete');
231             });
232         }
233     }
234
235     /** Return to previous page deny access to changepassword */
236     public redirectToPage(): void {
237         if (window.location.pathname === '/changepassword' && localStorage.getItem('username') !== null) {
238             window.history.back();
239         } else if (window.location.pathname === '/' && localStorage.getItem('firstLogin') === 'true') {
240             this.router.navigate(['/login']).catch((): void => {
241                 // Catch Navigation Error
242             });
243         }
244     }
245 }