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:50 UTC
[ambari] 01/02: [AMBARI-23897] Log Search UI: login with invalid password – no error message is displayed
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.