basic auth for so-monitoring 94/90794/5
authork.kazak <k.kazak@samsung.com>
Fri, 19 Jul 2019 12:59:18 +0000 (14:59 +0200)
committerk.kazak <k.kazak@samsung.com>
Fri, 19 Jul 2019 12:59:18 +0000 (14:59 +0200)
Add basic auth for so-monitoring app
Issue submitted in pentest report

Change-Id: I8e826da9b9f66e893826fd9b40b3b26623b2ab8d
Issue-ID: OJSI-169
Signed-off-by: k.kazak <k.kazak@samsung.com>
19 files changed:
so-monitoring/readme.md [new file with mode: 0644]
so-monitoring/so-monitoring-service/pom.xml
so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/UserController.java [new file with mode: 0644]
so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/WebApplicationConfig.java
so-monitoring/so-monitoring-service/src/main/java/org/onap/so/monitoring/rest/api/WebSecurityConfigImpl.java [new file with mode: 0644]
so-monitoring/so-monitoring-service/src/main/resources/application.yaml
so-monitoring/so-monitoring-ui/src/main/frontend/README.md
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/app-routing.module.ts
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/app.module.ts
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/auth.guard.ts [new file with mode: 0644]
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/authentication.service.ts [new file with mode: 0644]
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/basic-auth.interceptor.ts [new file with mode: 0644]
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/data.service.ts
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/error.interceptor.ts [new file with mode: 0644]
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.html [new file with mode: 0644]
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.spec.ts [new file with mode: 0644]
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/login/login.component.ts [new file with mode: 0644]
so-monitoring/so-monitoring-ui/src/main/frontend/src/app/sidebar/sidebar.component.html
so-monitoring/so-monitoring-ui/src/main/frontend/src/environments/environment.ts

diff --git a/so-monitoring/readme.md b/so-monitoring/readme.md
new file mode 100644 (file)
index 0000000..d4b876c
--- /dev/null
@@ -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
index ff70a77..f5448aa 100644 (file)
       <artifactId>spring-boot-configuration-processor</artifactId>
       <scope>compile</scope>
     </dependency>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-security</artifactId>
+    </dependency>
   </dependencies>
 
   <build>
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 (file)
index 0000000..3959631
--- /dev/null
@@ -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;
+    }
+}
index cadd60b..2b53ed8 100644 (file)
@@ -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 (file)
index 0000000..298f52b
--- /dev/null
@@ -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();
+    }
+}
index 8235c74..347845e 100644 (file)
@@ -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
index 329de0f..65731cd 100644 (file)
@@ -6,6 +6,15 @@ This project was generated with [Angular CLI](https://github.com/angular/angular
 \r
 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.\r
 \r
+FYI: You may need to change environments.ts to hit to your backend: not so-monitoring:30224 but localhost:8088  \r
+\r
+### Logging in\r
+\r
+Backend API for so-monitoring. Requires basic auth to access it.\r
+\r
+Default credentials:\r
+- with role GUI-Client: gui/password1$\r
+\r
 ## Code scaffolding\r
 \r
 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`.\r
index 428998d..03e77fc 100644 (file)
@@ -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
   }
 ];
 
index 2330863..71294bf 100644 (file)
@@ -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 (file)
index 0000000..f437a21
--- /dev/null
@@ -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<boolean> | Promise<boolean> | 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 (file)
index 0000000..d7610ee
--- /dev/null
@@ -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 (file)
index 0000000..4990d05
--- /dev/null
@@ -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<any>, next: HttpHandler): Observable<HttpEvent<any>> {
+    //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);
+  }
+}
index b391672..8dfae3d 100644 (file)
@@ -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 (file)
index 0000000..afe792c
--- /dev/null
@@ -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<any>, next: HttpHandler): Observable<HttpEvent<any>> {
+    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 (file)
index 0000000..107e1da
--- /dev/null
@@ -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
+-->
+<h2>Login</h2>
+<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
+  <div class="form-group">
+    <label for="username">Username</label>
+    <input type="text" formControlName="username" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.username.errors }" />
+    <div *ngIf="submitted && f.username.errors" class="invalid-feedback">
+      <div *ngIf="f.username.errors.required">Username is required</div>
+    </div>
+  </div>
+  <div class="form-group">
+    <label for="password">Password</label>
+    <input type="password" formControlName="password" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.password.errors }" />
+    <div *ngIf="submitted && f.password.errors" class="invalid-feedback">
+      <div *ngIf="f.password.errors.required">Password is required</div>
+    </div>
+  </div>
+  <div class="form-group">
+    <button [disabled]="loading" class="btn btn-primary">Login</button>
+    <img *ngIf="loading" src="data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==" />
+  </div>
+  <div *ngIf="error" class="alert alert-danger">{{error}}</div>
+</form>
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 (file)
index 0000000..8cf379d
--- /dev/null
@@ -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<AuthenticationService>;
+  let component: LoginComponent;
+  let fixture: ComponentFixture<LoginComponent>;
+  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 (file)
index 0000000..4a3f4e6
--- /dev/null
@@ -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;
+         });
+  }
+}
index e8b54d7..1c62351 100644 (file)
@@ -1,29 +1,34 @@
-<!--\r
-============LICENSE_START=======================================================\r
- Copyright (C) 2018 Ericsson. All rights reserved.\r
-================================================================================\r
-Licensed under the Apache License, Version 2.0 (the "License");\r
-you may not use this file except in compliance with the License.\r
-You may obtain a copy of the License at\r
-\r
-    http://www.apache.org/licenses/LICENSE-2.0\r
-\r
-Unless required by applicable law or agreed to in writing, software\r
-distributed under the License is distributed on an "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
-See the License for the specific language governing permissions and\r
- limitations under the License.\r
-\r
-SPDX-License-Identifier: Apache-2.0\r
-============LICENSE_END=========================================================\r
-\r
-@authors: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com\r
--->\r
-\r
-<nav>\r
-  <ul>\r
-    <li>\r
-      <a routerLink="/">Home</a>\r
-    </li>\r
-  </ul>\r
-</nav>\r
+<!--
+============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.
+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: ronan.kenny@ericsson.com, waqas.ikram@ericsson.com
+-->
+
+<nav>
+  <ul>
+    <li>
+      <a routerLink="/">Home</a>
+    </li>
+    <li>
+      <a routerLink="/login">Logout</a>
+    </li>
+  </ul>
+</nav>
index f0c63fe..484a156 100644 (file)
@@ -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'
 };