core and login component

This commit is contained in:
Eugenio Romano
2016-08-16 14:41:47 +01:00
parent 5f84bff7e1
commit 1e8440c0a0
10 changed files with 226 additions and 832 deletions

View File

@@ -15,9 +15,9 @@
* limitations under the License.
*/
import { Component } from '@angular/core';
import { AlfrescoLoginComponent } from 'ng2-alfresco-login';
import { ROUTER_DIRECTIVES, Router } from '@angular/router';
import {Component} from '@angular/core';
import {AlfrescoLoginComponent} from 'ng2-alfresco-login';
import {ROUTER_DIRECTIVES, Router} from '@angular/router';
declare let __moduleName: string;
@@ -30,7 +30,7 @@ declare let __moduleName: string;
})
export class LoginDemoComponent {
providers: string [] = ['ECM'];
providers: string = 'ECM';
constructor(public router: Router) {
}
@@ -45,28 +45,22 @@ export class LoginDemoComponent {
}
toggleECM(checked) {
if (checked) {
this.providers.push('ECM');
if (checked && this.providers === 'BPM') {
this.providers = 'ALL';
} else if (checked) {
this.providers = 'ECM';
} else {
this.removeElement('ECM');
this.providers = undefined;
}
}
toggleBPM(checked) {
if (checked) {
this.providers.push('BPM');
if (checked && this.providers === 'ECM') {
this.providers = 'ALL';
} else if (checked) {
this.providers = 'BPM';
} else {
this.removeElement('BPM');
this.providers = undefined;
}
}
removeElement(el: string) {
for (let i = 0; i < this.providers.length; i++) {
if (this.providers[i] === el) {
this.providers.splice(i, 1);
return false;
}
}
}
}

View File

@@ -1,37 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* 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.
*/
import { AbstractAuthentication } from '../interface/authentication.interface';
import { AlfrescoAuthenticationBPM } from '../services/AlfrescoAuthenticationBPM.service';
import { AlfrescoAuthenticationECM } from '../services/AlfrescoAuthenticationECM.service';
import { Http } from '@angular/http';
import { AlfrescoSettingsService } from '../services/AlfrescoSettingsService.service';
export class AuthenticationFactory {
public static createAuth(alfrescoSettingsService: AlfrescoSettingsService,
http: Http,
type: string): AbstractAuthentication {
if (type === 'ECM') {
return new AlfrescoAuthenticationECM(alfrescoSettingsService, http);
} else if (type === 'BPM') {
return new AlfrescoAuthenticationBPM(alfrescoSettingsService, http);
}
return null;
}
}

View File

@@ -1,116 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* 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.
*/
import { AbstractAuthentication } from '../interface/authentication.interface';
import { Http, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { AlfrescoAuthenticationBase } from './AlfrescoAuthenticationBase.service';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
export class AlfrescoAuthenticationBPM extends AlfrescoAuthenticationBase implements AbstractAuthentication {
TYPE: string = 'BPM';
constructor(alfrescoSetting: AlfrescoSettingsService,
http: Http) {
super(alfrescoSetting, http);
}
getHost(): string {
return this.alfrescoSetting.bpmHost;
}
/**
* Perform a login on behalf of the user and store the ticket returned
*
* @param username
* @param password
* @returns {Observable<R>|Observable<T>}
*/
login(username: string, password: string): Observable<any> {
return Observable.fromPromise(this.apiActivitiLogin(username, password))
.map((response: any) => {
return {
type: this.TYPE,
ticket: 'Basic ' + btoa(`${username}:${password}`)
};
})
.catch(this.handleError);
}
/**
* Delete the current login ticket from the server
*
* @returns {Observable<R>|Observable<T>}
*/
logout() {
return Observable.fromPromise(this.apiActivitiLogout())
.map(res => <any> res)
.do(response => {
this.removeTicket(this.TYPE);
})
.catch(this.handleError);
}
/**
* The method return true if the user is logged in
* @returns {boolean}
*/
isLoggedIn(): boolean {
return !!this.getTicket();
}
private apiActivitiLogin(username: string, password: string) {
let url = this.alfrescoSetting.getBPMApiBaseUrl() + '/app/authentication';
let headers = new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
});
let options = new RequestOptions({headers: headers});
let data = 'j_username='
+ encodeURIComponent(username)
+ '&j_password='
+ encodeURIComponent(password)
+ '&_spring_security_remember_me=true&submit=Login';
return this.http
.post(url, data, options).toPromise();
}
private apiActivitiLogout() {
let url = this.alfrescoSetting.getBPMApiBaseUrl() + '/app/logout';
return this.http.get(url).toPromise();
}
/**
* The method return the ticket stored in the localStorage
* @returns ticket
*/
public getTicket(): string {
return localStorage.getItem(`ticket-${this.TYPE}`);
}
/**
* The method save the ticket in the localStorage
* @param ticket
*/
public saveTicket(ticket: string): void {
if (ticket) {
super.saveTicket(this.TYPE, ticket);
}
}
}

View File

@@ -1,64 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* 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.
*/
import { Http, Response } from '@angular/http';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
import { Observable } from 'rxjs/Rx';
declare let AlfrescoApi: any;
export class AlfrescoAuthenticationBase {
alfrescoApi: any;
/**
* Constructor
* @param alfrescoSettingsService
*/
constructor(public alfrescoSetting: AlfrescoSettingsService,
public http: Http) {
}
/**
* The method save the toke in the localStorage
* @param ticket
*/
public saveTicket(provider: string, ticket: string): void {
if (ticket) {
localStorage.setItem(`ticket-${provider}`, ticket);
}
}
/**
* Remove the login ticket from localStorage
*/
public removeTicket(provider: string): void {
localStorage.removeItem(`ticket-${provider}`);
}
/**
* The method write the error in the console browser
* @param error
* @returns {ErrorObservable}
*/
public handleError(error: Response): Observable<any> {
console.error('Error when logging in', error);
return Observable.throw(error || 'Server error');
}
}

View File

@@ -1,137 +0,0 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* 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.
*/
import { AbstractAuthentication } from '../interface/authentication.interface';
import { Observable } from 'rxjs/Rx';
import { Http } from '@angular/http';
import { AlfrescoAuthenticationBase } from './AlfrescoAuthenticationBase.service';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
declare let AlfrescoApi: any;
export class AlfrescoAuthenticationECM extends AlfrescoAuthenticationBase implements AbstractAuthentication {
TYPE: string = 'ECM';
alfrescoApi: any;
/**
* Constructor
* @param alfrescoSetting
* @param http
*/
constructor(alfrescoSetting: AlfrescoSettingsService,
http: Http) {
super(alfrescoSetting, http);
if (!this.isLoggedIn()) {
this.alfrescoApi = new AlfrescoApi({
host: this.getHost()
});
} else {
this.alfrescoApi = new AlfrescoApi({
ticket: this.getTicket(),
host: this.getHost()
});
}
}
getHost(): string {
return this.alfrescoSetting.ecmHost;
}
/**
* The method return tru if the user is logged in
* @returns {boolean}
*/
isLoggedIn(): boolean {
return !!this.getTicket();
}
/**
* Method to delegate to POST login
* @param username
* @param password
* @returns {Observable<R>|Observable<T>}
*/
login(username: string, password: string) {
return Observable.fromPromise(this.callApiLogin(username, password))
.map((response: any) => {
return {type: this.TYPE, ticket: response};
})
.catch(this.handleError);
}
/**
* Initialize the alfresco Api with user and password end call the login method
* @param username
* @param password
* @returns {*|Observable<any>}
*/
private callApiLogin(username: string, password: string) {
this.alfrescoApi = new AlfrescoApi({
username: username,
password: password,
host: this.getHost()
});
return this.alfrescoApi.login();
}
/**
* The method remove the ticket from the local storage
*
* @returns {Observable<R>|Observable<T>}
*/
public logout() {
return Observable.fromPromise(this.callApiLogout())
.map(res => <any> res)
.do(response => {
this.removeTicket(this.TYPE);
return response;
})
.catch(this.handleError);
}
/**
*
* @returns {*|Observable<string>|Observable<any>|Promise<T>}
*/
private callApiLogout(): Promise<any> {
return this.alfrescoApi.logout();
}
/**
* The method return the ticket stored in the localStorage
* @returns ticket
*/
public getTicket(): string {
return localStorage.getItem(`ticket-${this.TYPE}`);
}
/**
* The method save the ticket in the localStorage
* @param ticket
*/
public saveTicket(ticket): void {
if (ticket) {
super.saveTicket(this.TYPE, ticket);
}
}
}

View File

@@ -15,22 +15,17 @@
* limitations under the License.
*/
import { it, describe } from '@angular/core/testing';
import { ReflectiveInjector, provide } from '@angular/core';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
import { AlfrescoAuthenticationService } from './AlfrescoAuthenticationService.service';
import { AlfrescoAuthenticationECM } from './AlfrescoAuthenticationECM.service';
import { AlfrescoAuthenticationBPM } from './AlfrescoAuthenticationBPM.service';
import { XHRBackend, HTTP_PROVIDERS } from '@angular/http';
import { MockBackend } from '@angular/http/testing';
import {it, describe} from '@angular/core/testing';
import {ReflectiveInjector, provide} from '@angular/core';
import {AlfrescoSettingsService} from './AlfrescoSettingsService.service';
import {AlfrescoAuthenticationService} from './AlfrescoAuthenticationService.service';
import {XHRBackend, HTTP_PROVIDERS} from '@angular/http';
import {MockBackend} from '@angular/http/testing';
declare var AlfrescoApi: any;
describe('AlfrescoAuthentication', () => {
let injector,
fakePromiseECM,
fakePromiseBPM,
service;
let injector, fakePromiseECM, fakePromiseBPM, service, fakePromiseBPMECM;
fakePromiseECM = new Promise(function (resolve, reject) {
resolve(
@@ -44,9 +39,18 @@ describe('AlfrescoAuthentication', () => {
});
fakePromiseBPM = new Promise(function (resolve, reject) {
resolve({
status: 'fake-post-ticket-BPM'
resolve(
'fake-post-ticket-BPM'
);
reject({
response: {
error: 'fake-error'
}
});
});
fakePromiseBPMECM = new Promise(function (resolve, reject) {
resolve(['fake-post-ticket-ECM', 'fake-post-ticket-BPM']);
reject({
response: {
error: 'fake-error'
@@ -81,380 +85,176 @@ describe('AlfrescoAuthentication', () => {
return keys[i] || null;
});
// service = injector.get(AlfrescoAuthenticationService);
});
describe('when the setting is ECM', () => {
it('should create an AlfrescoAuthenticationECM instance', (done) => {
let providers = ['ECM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
beforeEach(() => {
this.providers = 'ECM';
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin').and.returnValue(fakePromiseECM);
service.login('fake-username', 'fake-password', providers)
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(true);
expect(service.providersInstance).toBeDefined();
expect(service.providersInstance.length).toBe(1);
expect(service.providersInstance[0].TYPE).toEqual(providers[0]);
done();
}
);
});
it('should return an ECM ticket after the login done', (done) => {
let providers = ['ECM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogin').and.returnValue(fakePromiseECM);
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin').and.returnValue(fakePromiseECM);
service.login('fake-username', 'fake-password', providers)
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(true);
expect(service.getTicket(providers[0])).toEqual('fake-post-ticket-ECM');
done();
}
);
service.login('fake-username', 'fake-password', this.providers).subscribe(() => {
expect(service.isLoggedIn()).toBe(true);
expect(service.getTicket()).toEqual('fake-post-ticket-ECM');
done();
});
});
it('should return ticket undefined when the credentials are wrong', (done) => {
let providers = ['ECM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin')
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogin')
.and.returnValue(Promise.reject('fake invalid credentials'));
service.login('fake-wrong-username', 'fake-wrong-password', providers)
.subscribe(
service.login('fake-wrong-username', 'fake-wrong-password', this.providers).subscribe(
(res) => {
done();
},
(err: any) => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
expect(service.isLoggedIn()).toBe(false);
expect(service.getTicket()).toBeUndefined();
done();
}
);
});
});
it('should return an error if no provider are defined calling the login', (done) => {
let providers = [];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
it('should login in the ECM if no provider are defined calling the login', (done) => {
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogin').and.returnValue(fakePromiseECM);
service = injector.get(AlfrescoAuthenticationService);
service.login('fake-username', 'fake-password', providers)
.subscribe(
(res) => {
done();
},
(err: any) => {
expect(err).toBeDefined();
expect(err).toEqual('No providers defined');
done();
}
);
});
it('should return an error if an empty provider are defined calling the login', (done) => {
let providers = [''];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
service.login('fake-username', 'fake-password', providers)
.subscribe(
(res) => {
done();
},
(err: any) => {
expect(err).toBeDefined();
expect(err.message).toEqual('Wrong provider defined');
done();
}
);
service.login('fake-username', 'fake-password').subscribe(() => {
service.TYPE = 'ECM';
done();
});
});
it('should return a ticket undefined after logout', (done) => {
let providers = ['ECM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
localStorage.setItem('ticket-ECM', 'fake-post-ticket-ECM');
service.createProviderInstance(providers);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogout').and.returnValue(fakePromiseECM);
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogout').and.returnValue(fakePromiseECM);
service.logout()
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
expect(localStorage.getItem('ticket-ECM')).toBeUndefined();
done();
}
);
service.logout().subscribe(() => {
expect(service.isLoggedIn()).toBe(false);
expect(service.getTicket()).toBeUndefined();
expect(localStorage.getItem('ticket-ECM')).toBeUndefined();
done();
});
});
it('should logout only for if the provider is loggedin', (done) => {
let providers = ['BPM', 'ECM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
it('should logout only if the provider is already logged in', (done) => {
localStorage.setItem('ticket-ECM', 'fake-post-ticket-ECM');
service.createProviderInstance(providers);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogout').and.returnValue(fakePromiseECM);
service.performeSaveTicket('ECM', 'fake-ticket-ECM');
service.logout()
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
expect(localStorage.getItem('ticket-ECM')).toBeUndefined();
done();
}
);
});
it('should return an error if no provider are defined calling the logout', (done) => {
let providers = [];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
service.logout()
.subscribe(
(res) => {
done();
},
(err: any) => {
expect(err).toBeDefined();
expect(err).toEqual('No providers defined');
done();
}
);
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogout').and.returnValue(fakePromiseECM);
service.saveTicket('fake-ticket-ECM');
service.logout().subscribe(() => {
expect(service.isLoggedIn()).toBe(false);
expect(service.getTicket()).toBeUndefined();
expect(localStorage.getItem('ticket-ECM')).toBeUndefined();
done();
});
});
it('should return false if the user is not logged in', () => {
let providers = ['ECM'];
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.isLoggedIn()).toBe(false);
});
});
describe('when the setting is BPM', () => {
it('should create an AlfrescoAuthenticationBPM instance', (done) => {
let providers = ['BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
beforeEach(() => {
this.providers = 'BPM';
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(fakePromiseBPM);
service.login('fake-username', 'fake-password', providers)
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(true);
expect(service.providersInstance).toBeDefined();
expect(service.providersInstance.length).toBe(1);
expect(service.providersInstance[0].TYPE).toEqual(providers[0]);
done();
}
);
});
it('should return an BPM ticket after the login done', (done) => {
let providers = ['BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogin').and.returnValue(fakePromiseBPM);
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(fakePromiseBPM);
let username = 'fake-username';
let password = 'fake-password';
let token = 'Basic ' + btoa(`${username}:${password}`);
service.login(username, password, providers)
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(true);
expect(service.getTicket(providers[0])).toEqual(token);
done();
}
);
service.login('fake-username', 'fake-password', this.providers).subscribe(() => {
expect(service.isLoggedIn()).toBe(true);
expect(service.getTicket()).toEqual('fake-post-ticket-BPM');
done();
});
});
it('should return ticket undefined when the credentials are wrong', (done) => {
let providers = ['BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogin').and.returnValue(Promise.reject('fake invalid credentials'));
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(Promise.reject('fake invalid credentials'));
service.login('fake-wrong-username', 'fake-wrong-password', providers)
.subscribe(
service.login('fake-wrong-username', 'fake-wrong-password', this.providers).subscribe(
(res) => {
done();
},
(err: any) => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
expect(service.isLoggedIn()).toBe(false);
expect(service.getTicket()).toBeUndefined();
done();
}
);
});
});
it('should return a ticket undefined after logout', (done) => {
let providers = ['BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogin').and.returnValue(fakePromiseBPM);
service = injector.get(AlfrescoAuthenticationService);
localStorage.setItem('ticket-BPM', 'fake-post-ticket-BPM');
service.createProviderInstance(providers);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogout').and.returnValue(fakePromiseBPM);
service.login('fake-username', 'fake-password', this.providers).subscribe(() => {
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogout').and.returnValue(fakePromiseBPM);
service.logout()
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
service.logout().subscribe(() => {
expect(service.isLoggedIn()).toBe(false);
expect(service.getTicket()).toBeUndefined();
expect(localStorage.getItem('ticket-BPM')).toBeUndefined();
done();
}
);
});
});
});
it('should throw an error when the logout return error', (done) => {
let providers = ['BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
it('should return an error when the logout return error', (done) => {
localStorage.setItem('ticket-BPM', 'fake-post-ticket-BPM');
service.createProviderInstance(providers);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogout').and.returnValue(Promise.reject('fake logout error'));
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogout').and.returnValue(Promise.reject('fake logout error'));
service.logout()
.subscribe(
service.logout().subscribe(
(res) => {
done();
},
(err: any) => {
expect(err).toBeDefined();
expect(err.message).toEqual('fake logout error');
expect(localStorage.getItem('ticket-BPM')).toEqual('fake-post-ticket-BPM');
done();
}
);
});
});
});
describe('when the setting is both ECM and BPM ', () => {
it('should create both instances', (done) => {
let providers = ['ECM', 'BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
beforeEach(() => {
this.providers = 'ALL';
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin').and.returnValue(fakePromiseECM);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(fakePromiseBPM);
});
service.login('fake-username', 'fake-password', providers)
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(true);
expect(service.isLoggedIn(providers[1])).toBe(true);
expect(service.providersInstance).toBeDefined();
expect(service.providersInstance.length).toBe(2);
expect(service.providersInstance[0].TYPE).toEqual(providers[0]);
expect(service.providersInstance[1].TYPE).toEqual(providers[1]);
done();
}
);
it('should create both instances', (done) => {
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogin').and.returnValue(fakePromiseBPMECM);
service.login('fake-username', 'fake-password', this.providers).subscribe(() => {
expect(service.isLoggedIn()).toBe(true);
expect(service.TYPE).toEqual(this.providers);
done();
});
});
it('should return both ECM and BPM tickets after the login done', (done) => {
let providers = ['ECM', 'BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogin').and.returnValue(fakePromiseBPMECM);
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin').and.returnValue(fakePromiseECM);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(fakePromiseBPM);
let username = 'fake-username';
let password = 'fake-password';
let bpmToken = 'Basic ' + btoa(`${username}:${password}`);
service.login(username, password, providers)
.subscribe(() => {
expect(service.isLoggedIn(providers[0])).toBe(true);
expect(service.isLoggedIn(providers[1])).toBe(true);
expect(service.getTicket(providers[0])).toEqual('fake-post-ticket-ECM');
expect(service.getTicket(providers[1])).toEqual(bpmToken);
done();
}
);
service.login('fake-username', 'fake-password', this.providers).subscribe(() => {
expect(service.isLoggedIn()).toBe(true);
expect(service.getTicket()).toEqual('fake-post-ticket-ECM,fake-post-ticket-BPM');
done();
});
});
it('should return ticket undefined when the credentials are correct for the ECM login but wrong for the BPM login', (done) => {
let providers = ['ECM', 'BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
it('should return ticket undefined when the credentials are wrong', (done) => {
spyOn(AlfrescoAuthenticationService.prototype, 'callApiLogin').and.returnValue(Promise.reject('fake invalid credentials'));
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin').and.returnValue(fakePromiseECM);
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(Promise.reject('fake invalid credentials'));
service.login('fake-username', 'fake-password', providers)
.subscribe(
service.login('fake-username', 'fake-password', this.providers).subscribe(
(res) => {
done();
},
(err: any) => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
expect(service.isLoggedIn(providers[1])).toBe(false);
expect(service.getTicket(providers[1])).toBeUndefined();
expect(service.isLoggedIn()).toBe(false);
expect(service.getTicket()).toBeUndefined();
done();
}
);
});
it('should return ticket undefined when the credentials are correct for the BPM login but wrong for the ECM login', (done) => {
let providers = ['ECM', 'BPM'];
let alfSetting = injector.get(AlfrescoSettingsService);
alfSetting.providers = providers;
service = injector.get(AlfrescoAuthenticationService);
spyOn(AlfrescoAuthenticationECM.prototype, 'callApiLogin')
.and.returnValue(Promise.reject('fake invalid credentials'));
spyOn(AlfrescoAuthenticationBPM.prototype, 'apiActivitiLogin').and.returnValue(fakePromiseBPM);
service.login('fake-username', 'fake-password', providers)
.subscribe(
(res) => {
done();
},
(err: any) => {
expect(service.isLoggedIn(providers[0])).toBe(false);
expect(service.getTicket(providers[0])).toBeUndefined();
expect(service.isLoggedIn(providers[1])).toBe(false);
expect(service.getTicket(providers[1])).toBeUndefined();
done();
}
);
});
});
});
});

View File

@@ -15,13 +15,9 @@
* limitations under the License.
*/
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';
import { Http } from '@angular/http';
import { AlfrescoSettingsService } from './AlfrescoSettingsService.service';
import { AuthenticationFactory } from '../factory/AuthenticationFactory';
import { AbstractAuthentication } from '../interface/authentication.interface';
import { AlfrescoAuthenticationBase } from './AlfrescoAuthenticationBase.service';
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Rx';
import {AlfrescoSettingsService} from './AlfrescoSettingsService.service';
declare let AlfrescoApi: any;
@@ -29,177 +25,136 @@ declare let AlfrescoApi: any;
* The AlfrescoAuthenticationService provide the login service and store the ticket in the localStorage
*/
@Injectable()
export class AlfrescoAuthenticationService extends AlfrescoAuthenticationBase {
export class AlfrescoAuthenticationService {
private providersInstance: AbstractAuthentication[] = [];
alfrescoApi: any;
TYPE: string = 'ECM';
/**A
* Constructor
* @param alfrescoSetting
*/
constructor(public alfrescoSetting: AlfrescoSettingsService) {
if (!this.isLoggedIn()) {
this.alfrescoApi = new AlfrescoApi({
host: alfrescoSetting.ecmHost,
hostActiviti: alfrescoSetting.bpmHost
});
} else {
this.alfrescoApi = new AlfrescoApi({
ticket: this.getTicket(),
host: alfrescoSetting.ecmHost,
hostActiviti: alfrescoSetting.bpmHost
});
}
}
/**
* Constructor
* @param settingsService
* @param http
* The method return tru if the user is logged in
* @returns {boolean}
*/
constructor(settingsService: AlfrescoSettingsService,
http: Http) {
super(settingsService, http);
if (settingsService) {
this.createProviderInstance(settingsService.getProviders());
}
isLoggedIn(): boolean {
return !!this.getTicket();
}
/**
* Method to delegate to POST login
* @param username
* @param password
* @param providers
* @param provider
* @returns {Observable<R>|Observable<T>}
*/
login(username: string, password: string, providers: string []): Observable<string> {
localStorage.clear();
if (providers.length === 0) {
return Observable.throw('No providers defined');
} else {
return this.performeLogin(username, password, providers);
}
login(username: string, password: string, provider: string) {
this.TYPE = provider || this.TYPE;
return Observable.fromPromise(this.callApiLogin(username, password, provider))
.map((response: any) => {
this.saveTicket(response);
return {type: provider, ticket: response};
})
.catch(this.handleError);
}
/**
* Perform a login on behalf of the user for the different provider instance
*
* Initialize the alfresco Api with user and password end call the login method
* @param username
* @param password
* @param providers
* @returns {Observable<R>|Observable<T>}
* @param provider
* @returns {*|Observable<any>}
*/
private performeLogin(username: string, password: string, providers: string []): Observable<any> {
let observableBatch = [];
providers.forEach((provider) => {
let auth: AbstractAuthentication = this.findProviderInstance(provider);
if (auth) {
observableBatch.push(auth.login(username, password));
} else {
observableBatch.push(Observable.throw('Wrong provider defined'));
}
private callApiLogin(username: string, password: string, provider: string) {
this.alfrescoApi = new AlfrescoApi({
username: username,
password: password,
host: this.alfrescoSetting.ecmHost,
hostActiviti: this.alfrescoSetting.bpmHost
});
return Observable.create(observer => {
Observable.forkJoin(observableBatch).subscribe(
(response: any[]) => {
response.forEach((res) => {
this.performeSaveTicket(res.type, res.ticket);
});
observer.next(response);
},
(err: any) => {
observer.error(new Error(err));
});
});
}
/**
* The method return true if the user is logged in
* @returns {boolean}
*/
isLoggedIn(type: string = 'ECM'): boolean {
let auth: AbstractAuthentication = this.findProviderInstance(type);
if (auth) {
return auth.isLoggedIn();
}
return false;
}
getAlfrescoApi(): any {
return this.findProviderInstance('ECM').alfrescoApi;
}
/**
* Return the ticket stored in the localStorage of the specific provider type
* @param type
*/
public getTicket(type: string = 'ECM'): string {
let auth: AbstractAuthentication = this.findProviderInstance(type);
if (auth) {
return auth.getTicket();
}
return '';
}
/**
* Save the token calling the method of the specific provider type
* @param type - providerName
* @param ticket
*/
private performeSaveTicket(type: string, ticket: string) {
let auth: AbstractAuthentication = this.findProviderInstance(type);
if (auth) {
auth.saveTicket(ticket);
}
return this.alfrescoApi.login();
}
/**
* The method remove the ticket from the local storage
* @returns {Observable<T>}
*/
public logout(): Observable<string> {
if (this.providersInstance.length === 0) {
return Observable.throw('No providers defined');
} else {
return this.performLogout();
}
}
/**
* Perform a logout on behalf of the user for the different provider instance
*
* @returns {Observable<R>|Observable<T>}
*/
private performLogout(): Observable<any> {
let observableBatch = [];
this.providersInstance.forEach((authInstance) => {
if (authInstance.isLoggedIn()) {
observableBatch.push(authInstance.logout());
}
});
return Observable.create(observer => {
Observable.forkJoin(observableBatch).subscribe(
(response: any[]) => {
observer.next(response);
},
(err: any) => {
observer.error(new Error(err));
});
});
public logout() {
return Observable.fromPromise(this.callApiLogout())
.map(res => <any> res)
.do(response => {
this.removeTicket();
return response;
})
.catch(this.handleError);
}
/**
* Create the provider instance using a Factory
* @param providers - list of the providers like ECM BPM
* Remove the login ticket from localStorage
*/
public createProviderInstance(providers: string []): void {
if (this.providersInstance.length === 0) {
providers.forEach((provider) => {
let authInstance: AbstractAuthentication = AuthenticationFactory.createAuth(
this.alfrescoSetting, this.http, provider);
if (authInstance) {
this.providersInstance.push(authInstance);
}
});
public removeTicket(): void {
localStorage.removeItem(`ticket-${this.TYPE}`);
}
/**
*
* @returns {*|Observable<string>|Observable<any>|Promise<T>}
*/
private callApiLogout(): Promise<any> {
return this.alfrescoApi.logout();
}
/**
* The method return the ticket stored in the localStorage
* @returns ticket
*/
public getTicket(): string {
return localStorage.getItem(`ticket-${this.TYPE}`);
}
/**
* The method save the ticket in the localStorage
* @param ticket
*/
public saveTicket(ticket): void {
if (ticket) {
localStorage.setItem(`ticket-${this.TYPE}`, ticket);
}
}
/**
* Find the provider by type and return it
* @param type
* @returns {AbstractAuthentication}
* The method write the error in the console browser
* @param error
* @returns {ErrorObservable}
*/
private findProviderInstance(type: string): AbstractAuthentication {
let auth: AbstractAuthentication = null;
if (this.providersInstance && this.providersInstance.length !== 0) {
this.providersInstance.forEach((provider) => {
if (provider.TYPE === type.toUpperCase()) {
auth = provider;
}
});
}
return auth;
public handleError(error: any): Observable<any> {
console.error('Error when logging in', error);
return Observable.throw(error || 'Server error');
}
getAlfrescoApi(): any {
return this.alfrescoApi;
}
}

View File

@@ -83,7 +83,7 @@ Also make sure you include these dependencies in your .html page:
## Basic usage
```html
<alfresco-login [providers]="['ECM','BPM']"></alfresco-login>
<alfresco-login [providers]="'ALL'"></alfresco-login>
```
Example of an App that use Alfresco login component :
@@ -105,7 +105,7 @@ import {
selector: 'my-app',
template: '
<alfresco-login
providers=['ECM']
providers="'ALL'"
(onSuccess)="mySuccessMethod($event)"
(onError)="myErrorMethod($event)">
</alfresco-login>',
@@ -141,18 +141,17 @@ bootstrap(AppComponent, [
| onSuccess | The event is emitted when the login is done |
| onError | The event is emitted when the login fails |
Attribute | Description |
--- | --- |
`onSuccess` | The event is emitted when the login is done |
`onError` | The event is emitted when the login fails |
#### Options
**providers**: { string[] } optional) default ECM.
Attribute | Options | Default | Description | Mandatory
--- | --- | --- | --- | ---
`providers` | *string* | ECM | Possible valid value are ECM, BPM or ALL. The default behaviour of this component will logged in only in the ECM . If you want log in in both system the correct value to use is ALL |
Using the providers attribute, you can specify in which system
(ECM or BPM) you want to be logged in.
By selecting one of the options only the relative components will be
accesible. For instance if you activate the ECM login then only the
ECM component will be visible,same behaviour for BPM selection.
You can also specify ECM and BPM, in this case both system components
are accessible.<br />
## Custom logo and background

View File

@@ -11,7 +11,7 @@
* 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
* See the License for the speific language governing permissions and
* limitations under the License.
*/

View File

@@ -48,7 +48,7 @@ export class AlfrescoLoginComponent {
backgroundImageUrl: string;
@Input()
providers: string [] ;
providers: string ;
@Output()
onSuccess = new EventEmitter();