You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ab...@apache.org on 2018/05/23 11:10:49 UTC

[ambari] branch trunk updated (8a5d252 -> abb5295)

This is an automated email from the ASF dual-hosted git repository.

ababiichuk pushed a change to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git.


    from 8a5d252  Update team page. (yusaku)
     new 9e07d74  [AMBARI-23897] Log Search UI: login with invalid password – no error message is displayed
     new abb5295  [AMBARI-23897] Log Search UI: login with invalid password – no error message is displayed

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../login-form/login-form.component.html           |  2 +-
 .../login-form/login-form.component.spec.ts        | 23 +++++----
 .../components/login-form/login-form.component.ts  | 58 +++++++++++++++-------
 .../src/app/services/auth.service.ts               | 27 ++++++++--
 .../src/app/services/http-client.service.ts        |  2 +-
 .../ambari-logsearch-web/src/assets/i18n/en.json   |  6 +--
 6 files changed, 83 insertions(+), 35 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
ababiichuk@apache.org.

[ambari] 02/02: [AMBARI-23897] Log Search UI: login with invalid password – no error message is displayed

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ababiichuk pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit abb5295f4ae0f1b0f98f4078dfb7bec9718986f6
Author: Tobias Istvan <to...@gmail.com>
AuthorDate: Wed May 23 09:31:46 2018 +0200

    [AMBARI-23897] Log Search UI: login with invalid password – no error message is displayed
---
 .../src/app/components/login-form/login-form.component.html       | 2 +-
 .../src/app/components/login-form/login-form.component.ts         | 5 +----
 .../ambari-logsearch-web/src/app/services/auth.service.ts         | 4 ++--
 .../ambari-logsearch-web/src/app/services/http-client.service.ts  | 2 +-
 ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json     | 8 +++-----
 5 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.html
index 9e8b2a5..3db75c6 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.html
@@ -16,7 +16,7 @@
 -->
 
 <div class="login-form well col-md-4 col-md-offset-4 col-sm-offset-4">
-  <div class="alert alert-danger" *ngIf="isLoginAlertDisplayed" [innerHTML]="errorMessage"></div>
+  <div class="alert alert-danger" *ngIf="isLoginAlertDisplayed">{{errorMessage}}</div>
   <form #loginForm="ngForm" (ngSubmit)="login()">
     <div class="form-group">
       <label for="username">{{'authorization.name' | translate}}</label>
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.ts
index eee0b1b..d38fe33 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.ts
@@ -76,10 +76,7 @@ export class LoginFormComponent implements OnInit, OnDestroy {
   }
 
   private onLoginError = (resp: Boolean): void => {
-    Observable.combineLatest(
-      this.translateService.get('login.error.title'),
-      this.translateService.get('login.error.message')
-    ).first().subscribe(([title, message]: [string, string]) => {
+    this.translateService.get('authorization.error.401').first().subscribe((message: string) => {
       this.errorMessage = message;
       this.isLoginAlertDisplayed = true;
     });
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/auth.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/auth.service.ts
index a3ed9b8..b78a88b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/auth.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/auth.service.ts
@@ -81,7 +81,7 @@ export class AuthService {
     const response$ = this.httpClient.postFormData('login', {
       username: username,
       password: password
-    }).share();
+    });
     response$.subscribe(
       (resp: Response) => this.onLoginResponse(resp),
       (resp: Response) => this.onLoginError(resp)
@@ -103,7 +103,7 @@ export class AuthService {
    * @returns {Observable<boolean | Error>}
    */
   logout(): Observable<Boolean> {
-    const response$ = this.httpClient.get('logout').share();
+    const response$ = this.httpClient.get('logout');
     response$.subscribe(
       (resp: Response) => this.onLogoutResponse(resp),
       (resp: Response) => this.onLogoutError(resp)
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/http-client.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/http-client.service.ts
index 19a12ab..c65278b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/http-client.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/http-client.service.ts
@@ -171,7 +171,7 @@ export class HttpClientService extends Http {
       }
       return handled;
     };
-    return super.request(this.generateUrl(url), options).first()
+    return super.request(this.generateUrl(url), options).first().share()
       .map(response => response)
       .catch((error: any) => {
         return handleResponseError(error) ? Observable.of(error) : Observable.throw(error);
diff --git a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
index fec6991..ad69e1b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
+++ b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
@@ -24,7 +24,9 @@
   "authorization.name": "Username",
   "authorization.password": "Password",
   "authorization.signIn": "Sign In",
-  "authorization.error": "<strong>Error!</strong> Invalid User credentials.<br>Please try again.",
+  "authorization.error.401": "Unable to sign in. Invalid username/password combination.",
+
+  "login.title": "Login",
 
   "topMenu.undo": "Undo",
   "topMenu.redo": "Redo",
@@ -218,10 +220,6 @@
   "logIndexFilter.update.success": "Log Index Filter for cluster <span class='cluster-name'>{{cluster}}</span> has been successfully updated.",
   "logIndexFilter.update.error": "Error at updating Log Index Filter for cluster <span class='cluster-name'>{{cluster}}</span>. {{message}}",
 
-  "login.title": "Login",
-  "login.error.title": "Login error",
-  "login.error.message": "Unable to sign in. Invalid username/password combination.",
-
   "shipperConfiguration.title": "All Configuration",
   "shipperConfiguration.add": "Add",
   "shipperConfiguration.edit": "Edit",

-- 
To stop receiving notification emails like this one, please contact
ababiichuk@apache.org.

[ambari] 01/02: [AMBARI-23897] Log Search UI: login with invalid password – no error message is displayed

Posted by ab...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ababiichuk pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git

commit 9e07d7460642b36b0d3dd195920ab6aa2a0dd608
Author: Tobias Istvan <to...@gmail.com>
AuthorDate: Mon May 21 15:36:53 2018 +0200

    [AMBARI-23897] Log Search UI: login with invalid password – no error message is displayed
---
 .../login-form/login-form.component.html           |  2 +-
 .../login-form/login-form.component.spec.ts        | 23 ++++----
 .../components/login-form/login-form.component.ts  | 61 ++++++++++++++++------
 .../src/app/services/auth.service.ts               | 31 ++++++++---
 .../ambari-logsearch-web/src/assets/i18n/en.json   |  2 +
 5 files changed, 86 insertions(+), 33 deletions(-)

diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.html b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.html
index 8b9c957..9e8b2a5 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.html
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.html
@@ -16,7 +16,7 @@
 -->
 
 <div class="login-form well col-md-4 col-md-offset-4 col-sm-offset-4">
-  <div class="alert alert-danger" *ngIf="isLoginAlertDisplayed" [innerHTML]="'authorization.error' | translate"></div>
+  <div class="alert alert-danger" *ngIf="isLoginAlertDisplayed" [innerHTML]="errorMessage"></div>
   <form #loginForm="ngForm" (ngSubmit)="login()">
     <div class="form-group">
       <label for="username">{{'authorization.name' | translate}}</label>
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.spec.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.spec.ts
index 7e2f7a7..3ec55fd 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.spec.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.spec.ts
@@ -26,20 +26,23 @@ import {AuthService} from '@app/services/auth.service';
 
 import {LoginFormComponent} from './login-form.component';
 import {RouterTestingModule} from '@angular/router/testing';
+import {NotificationsService} from 'angular2-notifications';
+import {NotificationService} from '@app/modules/shared/services/notification.service';
 
 describe('LoginFormComponent', () => {
   let component: LoginFormComponent;
   let fixture: ComponentFixture<LoginFormComponent>;
 
   const authMock = {
-    isError: false
+    isError: false,
+    isAuthorized: false
   };
-  const httpClient = {
-    isAuthorized: true,
-    postFormData: () => {
+
+  const AuthServiceMock = {
+    login: () => {
       return {
-        subscribe: (success: () => void, error: () => void) => {
-          authMock.isError ? error() : success();
+        subscribe: (observer: (resp) => void, error: (resp) => void) => {
+          authMock.isAuthorized ? observer(authMock.isAuthorized) : error(authMock.isAuthorized);
         }
       };
     }
@@ -59,10 +62,11 @@ describe('LoginFormComponent', () => {
       providers: [
         AppStateService,
         {
-          provide: HttpClientService,
-          useValue: httpClient
+          provide: AuthService,
+          useValue: AuthServiceMock
         },
-        AuthService
+        NotificationsService,
+        NotificationService
       ]
     })
     .compileComponents();
@@ -98,6 +102,7 @@ describe('LoginFormComponent', () => {
       describe(test.title, () => {
         beforeEach(() => {
           authMock.isError = test.isError;
+          authMock.isAuthorized = test.isAuthorized;
           component.login();
         });
 
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.ts b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.ts
index e3570c4..eee0b1b 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/components/login-form/login-form.component.ts
@@ -16,19 +16,23 @@
  * limitations under the License.
  */
 
-import {Component} from '@angular/core';
+import {Component, ViewChild, OnInit, OnDestroy} from '@angular/core';
 import {Response} from '@angular/http';
+import {Observable} from 'rxjs/Observable';
 import 'rxjs/add/operator/finally';
+import {Subscription} from 'rxjs/Subscription';
 import {AppStateService} from '@app/services/storage/app-state.service';
 import {AuthService} from '@app/services/auth.service';
-import {Observable} from 'rxjs/Observable';
+import {NotificationService, NotificationType} from '@modules/shared/services/notification.service';
+import {TranslateService} from '@ngx-translate/core';
+import {FormGroup} from '@angular/forms';
 
 @Component({
   selector: 'login-form',
   templateUrl: './login-form.component.html',
   styleUrls: ['./login-form.component.less']
 })
-export class LoginFormComponent {
+export class LoginFormComponent implements OnInit, OnDestroy {
 
   username: string;
 
@@ -38,24 +42,47 @@ export class LoginFormComponent {
 
   isLoginInProgress$: Observable<boolean> = this.appState.getParameter('isLoginInProgress');
 
-  constructor(private authService: AuthService, private appState: AppStateService) {}
+  errorMessage: string;
+
+  @ViewChild('loginForm')
+  loginForm: FormGroup;
+
+  subscriptions: Subscription[] = [];
+
+  constructor(
+    private authService: AuthService,
+    private appState: AppStateService,
+    private notificationService: NotificationService,
+    private translateService: TranslateService
+  ) {}
+
+  ngOnInit(): void {
+    this.subscriptions.push(
+      this.loginForm.valueChanges.subscribe(this.onLoginFormChange)
+    );
+  }
+
+  ngOnDestroy(): void {
+    this.subscriptions.forEach((subscription: Subscription) => subscription.unsubscribe());
+  }
 
-  /**
-   * Handling the response from the login action. Actually the goal only to show or hide the login error alert.
-   * When it gets error response it shows.
-   * @param {Response} resp
-   */
-  private onLoginError = (resp: Response): void => {
-    this.isLoginAlertDisplayed = true;
+  onLoginFormChange = (event) => {
+    this.isLoginAlertDisplayed = false;
   }
 
-  /**
-   * Handling the response from the login action. Actually the goal only to show or hide the login error alert.
-   * When it gets success response it hides.
-   * @param {Response} resp
-   */
-  private onLoginSuccess = (resp: Response): void => {
+  private onLoginSuccess = (result: Boolean): void => {
     this.isLoginAlertDisplayed = false;
+    this.errorMessage = '';
+  }
+
+  private onLoginError = (resp: Boolean): void => {
+    Observable.combineLatest(
+      this.translateService.get('login.error.title'),
+      this.translateService.get('login.error.message')
+    ).first().subscribe(([title, message]: [string, string]) => {
+      this.errorMessage = message;
+      this.isLoginAlertDisplayed = true;
+    });
   }
 
   login() {
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/services/auth.service.ts b/ambari-logsearch/ambari-logsearch-web/src/app/services/auth.service.ts
index 87cdb41..a3ed9b8 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/services/auth.service.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/services/auth.service.ts
@@ -25,6 +25,7 @@ import {HttpClientService} from '@app/services/http-client.service';
 import {AppStateService} from '@app/services/storage/app-state.service';
 import {Router} from '@angular/router';
 import {Subscription} from 'rxjs/Subscription';
+import { Observer } from 'rxjs/Observer';
 
 export const IS_AUTHORIZED_APP_STATE_KEY: string = 'isAuthorized';
 export const IS_LOGIN_IN_PROGRESS_APP_STATE_KEY: string = 'isLoginInProgress';
@@ -75,30 +76,48 @@ export class AuthService {
    * @param {string} password
    * @returns {Observable<Response>}
    */
-  login(username: string, password: string): Observable<Response> {
+  login(username: string, password: string): Observable<Boolean> {
     this.setLoginInProgressAppState(true);
     const response$ = this.httpClient.postFormData('login', {
       username: username,
       password: password
-    });
+    }).share();
     response$.subscribe(
       (resp: Response) => this.onLoginResponse(resp),
       (resp: Response) => this.onLoginError(resp)
     );
-    return response$;
+    return response$.switchMap((resp: Response) => {
+      return Observable.create((observer: Observer<boolean>) => {
+        if (resp.ok) {
+          observer.next(resp.ok);
+        } else {
+          observer.error(resp);
+        }
+        observer.complete();
+      });
+    });
   }
 
   /**
    * The single unique entry point to request a logout action
    * @returns {Observable<boolean | Error>}
    */
-  logout(): Observable<Response> {
-    const response$ = this.httpClient.get('logout');
+  logout(): Observable<Boolean> {
+    const response$ = this.httpClient.get('logout').share();
     response$.subscribe(
       (resp: Response) => this.onLogoutResponse(resp),
       (resp: Response) => this.onLogoutError(resp)
     );
-    return response$;
+    return response$.switchMap((resp: Response) => {
+      return Observable.create((observer) => {
+        if (resp.ok) {
+          observer.next(resp.ok);
+        } else {
+          observer.error(resp);
+        }
+        observer.complete();
+      });
+    });
   }
 
   /**
diff --git a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
index 00815f9..fec6991 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
+++ b/ambari-logsearch/ambari-logsearch-web/src/assets/i18n/en.json
@@ -219,6 +219,8 @@
   "logIndexFilter.update.error": "Error at updating Log Index Filter for cluster <span class='cluster-name'>{{cluster}}</span>. {{message}}",
 
   "login.title": "Login",
+  "login.error.title": "Login error",
+  "login.error.message": "Unable to sign in. Invalid username/password combination.",
 
   "shipperConfiguration.title": "All Configuration",
   "shipperConfiguration.add": "Add",

-- 
To stop receiving notification emails like this one, please contact
ababiichuk@apache.org.