From 3cc4c5bf37b4ae20a9809c329ad8aa1889aadbdd Mon Sep 17 00:00:00 2001 From: "k.kazak" Date: Fri, 19 Jul 2019 14:59:18 +0200 Subject: basic auth for so-monitoring Add basic auth for so-monitoring app Issue submitted in pentest report Change-Id: I8e826da9b9f66e893826fd9b40b3b26623b2ab8d Issue-ID: OJSI-169 Signed-off-by: k.kazak --- so-monitoring/readme.md | 35 +++++++ so-monitoring/so-monitoring-service/pom.xml | 4 + .../so/monitoring/rest/api/UserController.java | 35 +++++++ .../monitoring/rest/api/WebApplicationConfig.java | 9 +- .../monitoring/rest/api/WebSecurityConfigImpl.java | 39 ++++++++ .../src/main/resources/application.yaml | 7 ++ .../so-monitoring-ui/src/main/frontend/README.md | 9 ++ .../main/frontend/src/app/app-routing.module.ts | 12 ++- .../src/main/frontend/src/app/app.module.ts | 18 +++- .../src/main/frontend/src/app/auth.guard.ts | 46 +++++++++ .../frontend/src/app/authentication.service.ts | 50 ++++++++++ .../frontend/src/app/basic-auth.interceptor.ts | 43 ++++++++ .../src/main/frontend/src/app/data.service.ts | 2 +- .../src/main/frontend/src/app/error.interceptor.ts | 45 +++++++++ .../frontend/src/app/login/login.component.html | 43 ++++++++ .../frontend/src/app/login/login.component.spec.ts | 108 +++++++++++++++++++++ .../main/frontend/src/app/login/login.component.ts | 81 ++++++++++++++++ .../src/app/sidebar/sidebar.component.html | 63 ++++++------ .../main/frontend/src/environments/environment.ts | 5 +- 19 files changed, 614 insertions(+), 40 deletions(-) create mode 100644 so-monitoring/readme.md create mode 100644 so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/UserController.java create mode 100644 so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/WebSecurityConfigImpl.java create mode 100644 so-monitoring/so-monitoring-ui/src/main/frontend/src/app/auth.guard.ts create mode 100644 so-monitoring/so-monitoring-ui/src/main/frontend/src/app/authentication.service.ts create mode 100644 so-monitoring/so-monitoring-ui/src/main/frontend/src/app/basic-auth.interceptor.ts create mode 100644 so-monitoring/so-monitoring-ui/src/main/frontend/src/app/error.interceptor.ts create mode 100644 so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.html create mode 100644 so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.spec.ts create mode 100644 so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.ts (limited to 'so-monitoring') diff --git a/so-monitoring/readme.md b/so-monitoring/readme.md new file mode 100644 index 0000000000..d4b876c763 --- /dev/null +++ b/so-monitoring/readme.md @@ -0,0 +1,35 @@ +# SO Monitoring + +---- + +## Introduction + +SO Monitoring provides multiple useful features: +* Search/Filtering Menu +* A graphical user interface +* Workflow pathing +* Subflow navigation +* Access to the workflow variables + +## Compiling / Running + +Compiling is simple: `mvn clean install` +Compilation may fail if your code is not formatted properly. + +## Components + +### so-monitoring-handler + + +### so-monitoring-service + +Backend API for so-monitoring. Requires basic auth to access it. + +Default credentials: +- with role GUI-Client: gui/password1$ + +Note that these default users should be changed for production. + +### so-monitoring-ui + +UI for so-monitoring has a separate README.md - so-monitoring/so-monitoring-ui/src/main/frontend/README.md diff --git a/so-monitoring/so-monitoring-service/pom.xml b/so-monitoring/so-monitoring-service/pom.xml index ff70a77239..f5448aaf5c 100644 --- a/so-monitoring/so-monitoring-service/pom.xml +++ b/so-monitoring/so-monitoring-service/pom.xml @@ -64,6 +64,10 @@ spring-boot-configuration-processor compile + + org.springframework.boot + spring-boot-starter-security + diff --git a/so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/UserController.java b/so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/UserController.java new file mode 100644 index 0000000000..3959631f94 --- /dev/null +++ b/so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/UserController.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Samsung + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.monitoring.rest.api; + +import java.security.Principal; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class UserController { + + @RequestMapping("/user") + public Principal user(Principal user) { + return user; + } +} diff --git a/so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/WebApplicationConfig.java b/so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/WebApplicationConfig.java index cadd60b0d9..2b53ed8953 100644 --- a/so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/WebApplicationConfig.java +++ b/so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/WebApplicationConfig.java @@ -2,7 +2,9 @@ * ============LICENSE_START======================================================= * Copyright (C) 2018 Ericsson. All rights reserved. * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); + * Modifications Copyright (c) 2019 Samsung + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * @@ -21,16 +23,15 @@ package org.onap.so.monitoring.rest.api; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @author waqas.ikram@ericsson.com */ @Configuration -public class WebApplicationConfig extends WebMvcConfigurerAdapter { +public class WebApplicationConfig implements WebMvcConfigurer { @Override public void addViewControllers(final ViewControllerRegistry registry) { - super.addViewControllers(registry); registry.addViewController("/details/**").setViewName("forward:/"); } } diff --git a/so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/WebSecurityConfigImpl.java b/so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/WebSecurityConfigImpl.java new file mode 100644 index 0000000000..298f52bd35 --- /dev/null +++ b/so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/WebSecurityConfigImpl.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Samsung + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.monitoring.rest.api; + +import org.onap.so.security.WebSecurityConfig; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; + +@EnableWebSecurity +@Configuration("att-security-config") +@Order(2) +public class WebSecurityConfigImpl extends WebSecurityConfig { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests().antMatchers("/actuator", "/actuator/*", "/login", "/", "/index.html", "/*.js", + "/*.js.map", "/favicon.png").permitAll().anyRequest().authenticated().and().httpBasic(); + } +} diff --git a/so-monitoring/so-monitoring-service/src/main/resources/application.yaml b/so-monitoring/so-monitoring-service/src/main/resources/application.yaml index 8235c7480a..347845e422 100644 --- a/so-monitoring/so-monitoring-service/src/main/resources/application.yaml +++ b/so-monitoring/so-monitoring-service/src/main/resources/application.yaml @@ -16,3 +16,10 @@ mso: url: http://so-request-db-adapter.onap:8083/infraActiveRequests/ auth: Basic YnBlbDpwYXNzd29yZDEk +spring: + security: + usercredentials: + - + username: gui + password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke' + role: GUI-Client diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/README.md b/so-monitoring/so-monitoring-ui/src/main/frontend/README.md index 329de0f833..65731cdc5d 100644 --- a/so-monitoring/so-monitoring-ui/src/main/frontend/README.md +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/README.md @@ -6,6 +6,15 @@ This project was generated with [Angular CLI](https://github.com/angular/angular Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. +FYI: You may need to change environments.ts to hit to your backend: not so-monitoring:30224 but localhost:8088 + +### Logging in + +Backend API for so-monitoring. Requires basic auth to access it. + +Default credentials: +- with role GUI-Client: gui/password1$ + ## Code scaffolding Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/app-routing.module.ts b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/app-routing.module.ts index 428998dc62..03e77fc2d9 100644 --- a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/app-routing.module.ts +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/app-routing.module.ts @@ -1,6 +1,8 @@ /** ============LICENSE_START======================================================= Copyright (C) 2018 Ericsson. All rights reserved. +================================================================================ + Modifications Copyright (c) 2019 Samsung ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -24,17 +26,25 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { HomeComponent } from './home/home.component'; import { DetailsComponent } from './details/details.component'; +import {AuthGuard} from "./auth.guard"; +import {LoginComponent} from "./login/login.component"; const routes: Routes = [ { // Route to home page path: '', - component: HomeComponent + component: HomeComponent, + canActivate: [AuthGuard] }, { // Route to page to show individual process based on ID path: 'details/:id', component: DetailsComponent + }, + { + // Route to login page + path: 'login', + component: LoginComponent } ]; diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/app.module.ts b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/app.module.ts index 23308639b6..71294bfffe 100644 --- a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/app.module.ts +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/app.module.ts @@ -1,6 +1,8 @@ /** ============LICENSE_START======================================================= Copyright (C) 2018 Ericsson. All rights reserved. +================================================================================ + Modifications Copyright (c) 2019 Samsung ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -28,7 +30,7 @@ import { AppComponent } from './app.component'; import { SidebarComponent } from './sidebar/sidebar.component'; import { TopbarComponent } from './topbar/topbar.component'; import { HomeComponent } from './home/home.component'; -import { HttpClientModule } from '@angular/common/http'; +import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { DetailsComponent } from './details/details.component'; import { ToastrNotificationService } from './toastr-notification-service.service'; @@ -37,6 +39,9 @@ import { MatFormFieldModule, MatInputModule, MatTableModule, MatTabsModule, MatS import { NgxSpinnerModule } from 'ngx-spinner'; import { RouterModule, Routes } from '@angular/router'; import { APP_BASE_HREF } from '@angular/common'; +import { LoginComponent } from './login/login.component'; +import {BasicAuthInterceptor} from "./basic-auth.interceptor"; +import {ErrorInterceptor} from "./error.interceptor"; @NgModule({ declarations: [ @@ -44,7 +49,8 @@ import { APP_BASE_HREF } from '@angular/common'; SidebarComponent, TopbarComponent, HomeComponent, - DetailsComponent + DetailsComponent, + LoginComponent ], imports: [ BrowserModule, @@ -64,12 +70,16 @@ import { APP_BASE_HREF } from '@angular/common'; RouterModule, MatPaginatorModule, MatSortModule, - RouterModule.forRoot([]) + RouterModule.forRoot([]), + ReactiveFormsModule ], schemas: [ CUSTOM_ELEMENTS_SCHEMA ], - providers: [ToastrNotificationService], + providers: [ + { provide: HTTP_INTERCEPTORS, useClass: BasicAuthInterceptor, multi: true }, + { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }, + ToastrNotificationService], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/auth.guard.ts b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/auth.guard.ts new file mode 100644 index 0000000000..f437a21710 --- /dev/null +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/auth.guard.ts @@ -0,0 +1,46 @@ +/** + ============LICENSE_START======================================================= + Copyright (C) 2019 Samsung. All rights reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 + ============LICENSE_END========================================================= + + @authors: k.kazak@samsung.com + **/ + +import { Injectable } from '@angular/core'; +import {CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from '@angular/router'; +import { Observable } from 'rxjs'; + +@Injectable({ + providedIn: 'root' +}) +export class AuthGuard implements CanActivate { + + constructor(private router:Router) { } + + canActivate( + next: ActivatedRouteSnapshot, + state: RouterStateSnapshot): Observable | Promise | boolean { + if (localStorage.getItem('authdata')) { + // logged in + return true; + } + + // not logged in + this.router.navigate(['/login'], { queryParams: {returnUrl: state.url}}); + return false; + } +} diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/authentication.service.ts b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/authentication.service.ts new file mode 100644 index 0000000000..d7610eed0d --- /dev/null +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/authentication.service.ts @@ -0,0 +1,50 @@ +/** + ============LICENSE_START======================================================= + Copyright (C) 2019 Samsung. All rights reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 + ============LICENSE_END========================================================= + + @authors: k.kazak@samsung.com + **/ + +import {Injectable} from '@angular/core'; +import {HttpClient} from "@angular/common/http"; +import {environment} from "../environments/environment"; + +@Injectable({ + providedIn: 'root' +}) +export class AuthenticationService { + + constructor(private http: HttpClient) { + } + + login(username: string, password: string) { + // remove old data from storage + localStorage.removeItem('authdata'); + // add to local storage + var authdata = window.btoa(username + ':' + password); + localStorage.setItem('authdata', authdata); + + // make request + return this.http.get(environment.authBackendURL); + } + + logout() { + // remove from local storage + localStorage.removeItem('authdata'); + } +} diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/basic-auth.interceptor.ts b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/basic-auth.interceptor.ts new file mode 100644 index 0000000000..4990d05ecb --- /dev/null +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/basic-auth.interceptor.ts @@ -0,0 +1,43 @@ +/** + ============LICENSE_START======================================================= + Copyright (C) 2019 Samsung. All rights reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 + ============LICENSE_END========================================================= + + @authors: k.kazak@samsung.com + **/ + +import { Injectable } from '@angular/core'; +import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; +import { Observable } from 'rxjs'; + +@Injectable() +export class BasicAuthInterceptor implements HttpInterceptor { + intercept(request: HttpRequest, next: HttpHandler): Observable> { + //add authorization header with basic auth credentials if available + let auth = localStorage.getItem('authdata'); + if (auth) { + const authReq = request.clone({ + headers: request.headers.set('Authorization', 'Basic Z3VpOnBhc3N3b3JkMSQ=') + }); + + // send cloned request with header to the next handler. + return next.handle(authReq); + } + + return next.handle(request); + } +} diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/data.service.ts b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/data.service.ts index b391672728..8dfae3da1e 100644 --- a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/data.service.ts +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/data.service.ts @@ -21,7 +21,7 @@ SPDX-License-Identifier: Apache-2.0 */ import { Injectable } from '@angular/core'; -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; +import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http'; import { BpmnInfraRequest } from './model/bpmnInfraRequest.model'; import { catchError } from 'rxjs/operators'; import { Observable } from 'rxjs'; diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/error.interceptor.ts b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/error.interceptor.ts new file mode 100644 index 0000000000..afe792c80f --- /dev/null +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/error.interceptor.ts @@ -0,0 +1,45 @@ +/** + ============LICENSE_START======================================================= + Copyright (C) 2019 Samsung. All rights reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 + ============LICENSE_END========================================================= + + @authors: k.kazak@samsung.com + **/ + +import { Injectable } from '@angular/core'; +import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http'; +import { Observable, throwError } from 'rxjs'; +import { catchError } from 'rxjs/operators'; +import {AuthenticationService} from "./authentication.service"; + +@Injectable() +export class ErrorInterceptor implements HttpInterceptor { + constructor(private authenticationService: AuthenticationService) {} + + intercept(request: HttpRequest, next: HttpHandler): Observable> { + return next.handle(request).pipe(catchError(err => { + if (err.status === 401) { + // auto logout if 401 response returned from api + this.authenticationService.logout(); + location.reload(true); + } + + const error = err.error.message || err.statusText; + return throwError(error); + })) + } +} diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.html b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.html new file mode 100644 index 0000000000..107e1da04a --- /dev/null +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.html @@ -0,0 +1,43 @@ + +

Login

+
+
+ + +
+
Username is required
+
+
+
+ + +
+
Password is required
+
+
+
+ + +
+
{{error}}
+
diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.spec.ts b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.spec.ts new file mode 100644 index 0000000000..8cf379d04f --- /dev/null +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.spec.ts @@ -0,0 +1,108 @@ +/** + ============LICENSE_START======================================================= + Copyright (C) 2019 Samsung. All rights reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 + ============LICENSE_END========================================================= + + @authors: k.kazak@samsung.com + **/ + +import {async, ComponentFixture, inject, TestBed} from '@angular/core/testing'; + +import {LoginComponent} from './login.component'; +import {AuthenticationService} from "../authentication.service"; +import {CUSTOM_ELEMENTS_SCHEMA} from "@angular/core"; +import {FormsModule, ReactiveFormsModule} from '@angular/forms'; +import {RouterTestingModule} from "@angular/router/testing"; +import {ActivatedRoute, Router, RouterModule} from "@angular/router"; + +describe('LoginComponent', () => { + // Create SPY Object for Jasmine tests to mock DataService + let spyDataService: jasmine.SpyObj; + let component: LoginComponent; + let fixture: ComponentFixture; + let router: Router; + + beforeEach(async(() => { + spyDataService = jasmine.createSpyObj('AuthenticationService', ['login', 'logout']); + + TestBed.configureTestingModule({ + providers: [LoginComponent, + {provide: AuthenticationService, useValue: spyDataService}, + {provide: ActivatedRoute, useValue: { snapshot: {queryParams: { returnUrl: 'test'}}}} + ], + imports: [RouterTestingModule, ReactiveFormsModule, FormsModule, RouterModule.forRoot([])], + declarations: [LoginComponent], + schemas: [ + CUSTOM_ELEMENTS_SCHEMA + ] + }); + + fixture = TestBed.createComponent(LoginComponent); + component = fixture.componentInstance; + router = TestBed.get(Router); + })); + + + it('should create', inject([LoginComponent], + (component: LoginComponent) => { + expect(component).toBeTruthy(); + })); + + it('should logout and route to test directory', inject([LoginComponent], + (component: LoginComponent) => { + component.ngOnInit(); + expect(component.returnUrl).toBe('test'); + })); + + it('should logout and route to root directory', inject([LoginComponent], + (component: LoginComponent) => { + router.initialNavigation(); + component.ngOnInit(); + expect(component.returnUrl).toBe('test'); + })); + + it('should submit without success', inject([LoginComponent], + (component: LoginComponent) => { + component.ngOnInit(); + expect(component.loginForm.valid).toBe(false); + component.onSubmit(); + expect(component.submitted).toBe(true); + })); + + it('should submit without success', inject([LoginComponent], + (component: LoginComponent) => { + component.ngOnInit(); + expect(component.loginForm.valid).toBe(false); + spyDataService.login.and.returnValue(Promise.resolve()); + + let compiled = fixture.debugElement.nativeElement; + let username = compiled.querySelector('input[type="text"]'); + let password = compiled.querySelector('input[type="password"]'); + + fixture.detectChanges(); + + // Change value + username.value = 'test'; + password.value = 'password'; + + // dispatch input event + dispatchEvent(new Event('input')); + + component.onSubmit(); + expect(component.submitted).toBe(true); + })); +}); diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.ts b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.ts new file mode 100644 index 0000000000..4a3f4e6b0f --- /dev/null +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.ts @@ -0,0 +1,81 @@ +/** + ============LICENSE_START======================================================= + Copyright (C) 2019 Samsung. All rights reserved. + ================================================================================ + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + SPDX-License-Identifier: Apache-2.0 + ============LICENSE_END========================================================= + + @authors: k.kazak@samsung.com + **/ + +import { Component, OnInit } from '@angular/core'; +import {FormBuilder, FormGroup, Validators, ReactiveFormsModule} from "@angular/forms"; +import {ActivatedRoute, Router} from "@angular/router"; +import {AuthenticationService} from "../authentication.service"; +import {first} from "rxjs/internal/operators"; + +@Component({ + selector: 'app-login', + templateUrl: './login.component.html', + styleUrls: [] +}) +export class LoginComponent implements OnInit { + + loginForm: FormGroup; + loading = false; + submitted = false; + returnUrl: string; + error = ''; + + constructor(private formBuilder: FormBuilder, + private route: ActivatedRoute, + private router: Router, + private authenticationService: AuthenticationService) { } + + ngOnInit() { + this.loginForm = this.formBuilder.group({ + username: ['', Validators.required], + password: ['', Validators.required] + }); + + // logout + this.authenticationService.logout(); + + this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/'; + } + + // convenience getter for easy access to form fields + get f() { return this.loginForm.controls; } + + onSubmit() { + this.submitted = true; + + // stop here if form is invalid + if (this.loginForm.invalid) { + return; + } + + this.loading = true; + this.authenticationService.login(this.f.username.value, this.f.password.value) + .subscribe( + next => { + this.router.navigate([this.returnUrl]); + }, + error => { + this.error = error; + this.loading = false; + }); + } +} diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/sidebar/sidebar.component.html b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/sidebar/sidebar.component.html index e8b54d7ae3..1c623518c7 100644 --- a/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/sidebar/sidebar.component.html +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/src/app/sidebar/sidebar.component.html @@ -1,29 +1,34 @@ - - - + + + diff --git a/so-monitoring/so-monitoring-ui/src/main/frontend/src/environments/environment.ts b/so-monitoring/so-monitoring-ui/src/main/frontend/src/environments/environment.ts index f0c63fe582..484a156fa9 100644 --- a/so-monitoring/so-monitoring-ui/src/main/frontend/src/environments/environment.ts +++ b/so-monitoring/so-monitoring-ui/src/main/frontend/src/environments/environment.ts @@ -1,6 +1,8 @@ /** ============LICENSE_START======================================================= Copyright (C) 2018 Ericsson. All rights reserved. +================================================================================ + Modifications Copyright (c) 2019 Samsung ================================================================================ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -24,5 +26,6 @@ SPDX-License-Identifier: Apache-2.0 export const environment = { production: false, - soMonitoringBackendURL: 'http://so-monitoring:30224/so/monitoring/' + soMonitoringBackendURL: 'http://so-monitoring:30224/so/monitoring/', + authBackendURL: 'http://so-monitoring:30224/user' }; -- cgit 1.2.3-korg