Skip to content

Commit 57b96a0

Browse files
Implementing client flow, decopling the flow resolution.
1 parent 9f1fdf5 commit 57b96a0

20 files changed

+241
-64
lines changed

source/FlowResultBuilder.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { FlowResult } from "./Models/FlowResult";
2+
import { IFlowResultBuilder } from "./IFlowResultBuilder";
3+
import { ITokenService } from "./Services/ITokenService";
4+
import { Token } from "./Models/Persistents/Token";
5+
6+
/**
7+
* Represents the a builder to vuild flows results.
8+
*/
9+
export class FlowResultBuilder implements IFlowResultBuilder {
10+
11+
private _tokenService:ITokenService;
12+
13+
/**
14+
* Create a new instance of flow result builder.
15+
* @param tokenService Represents a token service used to generate tokens.
16+
*/
17+
constructor(tokenService:ITokenService) {
18+
19+
this._tokenService = tokenService;
20+
}
21+
22+
/**
23+
* Return a builder FlowResult.
24+
*/
25+
public async getResult():Promise<FlowResult> {
26+
27+
let token:Token = await this._tokenService.generateToken();
28+
let result:FlowResult = new FlowResult();
29+
30+
result.accessToken = token.value;
31+
result.expireIn = token.expireIn;
32+
result.refreshToken = token.refreshToken ? token.refreshToken.value : null;
33+
34+
return result;
35+
}
36+
}

source/Flows/BaseFlow.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { IFlow } from './IFlow'
22
import { IFlowHandler } from '../IFlowHandler'
3+
import { FlowError } from "../Models/FlowError";
4+
import { ICLientService } from "../Services/IClientService";
35

46
/**
57
* Represents a base class for the oAuth flows.
@@ -9,7 +11,7 @@ export abstract class BaseFlow implements IFlow {
911
* Construct a new base flow [BaseFP] with the given type.
1012
* @param type Represents the type of the flow processor.
1113
*/
12-
constructor(type:string) {
14+
constructor(type:string, clientService:ICLientService) {
1315
this._type = type;
1416
}
1517

@@ -26,8 +28,26 @@ export abstract class BaseFlow implements IFlow {
2628
public clientId: string;
2729

2830
/**
29-
* Execute the flow and handle it with the given handler.
30-
* @param handler Represents the handler for the flow.
31+
* Execute the flow resolution and handle it with the given handler.
32+
* @param handle Represents the handler.
3133
*/
32-
public abstract execute(handler:IFlowHandler):Promise<void>;
34+
public async resolve(handler:IFlowHandler):Promise<boolean> {
35+
36+
let error:FlowError = await this.validate();
37+
38+
if (error) {
39+
handler.notifyError(error);
40+
return true;
41+
}
42+
else
43+
return false;
44+
};
45+
46+
/**
47+
* Return a flow error instance when a error is founded in the evaluated flow.
48+
* If return null no error was found.
49+
*/
50+
private async validate():Promise<FlowError> {
51+
return null;
52+
};
3353
}

source/Flows/ClientCredetialFlow.ts

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,31 @@
11
import { BaseFlow } from './BaseFlow'
22
import { IFlowHandler } from '../IFlowHandler'
3+
import { IClientService } from "../Services/IClientService";
4+
import { FlowResult } from "../Models/FlowResult";
5+
import { Token } from "../Models/Persistents/Token";
6+
import { ITokenService } from "../Services/ITokenService";
7+
import { IFlowResultBuilder } from "../IFlowResultBuilder";
38

49
/**
510
* Represents a client credential flow.
611
*/
712
export class ClientCredetialFlow extends BaseFlow {
8-
constructor() {
9-
super('client_credential')
13+
14+
private _clientService:IClientService;
15+
private _flowResultBuilder:IFlowResultBuilder;
16+
17+
/**
18+
* Create ne instance of client credential flow.
19+
* @param clientService Represents a client service to authenticate and validate the client.
20+
* @param flowResultBuilder Represents a builder to build results.
21+
*/
22+
constructor(clientService:IClientService
23+
,flowResultBuilder:IFlowResultBuilder) {
24+
25+
super('client_credential', clientService);
26+
27+
this._clientService = clientService;
28+
this._flowResultBuilder = flowResultBuilder;
1029
}
1130

1231
/**
@@ -15,11 +34,14 @@ export class ClientCredetialFlow extends BaseFlow {
1534
public clientSecret:string;
1635

1736
/**
18-
* Execute the flow and handle it with the given handler.
19-
* @param handler Represents the handler for the flow.
37+
* Execute the flow resolution and handle it with the given handler.
38+
* @param handle Represents the handler.
2039
*/
21-
public execute(handler:IFlowHandler):void {
22-
23-
40+
public async resolve(handler:IFlowHandler):Promise<boolean> {
41+
if (!super.resolve(handler) && this._clientService.validateCredentials(this.clientId, this.clientSecret)) {
42+
handler.returnResult(await this._flowResultBuilder.getResult());
43+
}
44+
else
45+
return false;
2446
}
2547
}

source/Flows/IFlow.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { IFlowHandler } from '../IFlowHandler'
55
*/
66
export interface IFlow {
77
/**
8-
* Execute the flow and handle it with the given handler.
8+
* Execute the flow resolution and handle it with the given handler.
9+
* @param handle Represents the handler.
910
*/
10-
execute(handler:IFlowHandler):Promise<void>;
11+
resolve(handler:IFlowHandler):Promise<boolean>;
1112
}

source/Flows/PasswordFlow.ts

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,35 @@ import { IFlowHandler } from '../IFlowHandler'
44
import { Token } from "../Models/Persistents/Token";
55
import { ITokenService } from "../Services/ITokenService";
66
import { IUserService } from "../Services/IUserService";
7+
import { FlowError } from "../Models/FlowError";
8+
import { IFlowResultBuilder } from "../IFlowResultBuilder";
9+
import { IClientService } from "../Services/IClientService";
710

811

912
/**
1013
* Represents the password flow.
1114
*/
1215
export class PasswordFlow extends BaseFlow {
1316

14-
private _userService:IUserService;
15-
private _tokenService:ITokenService;
17+
private _userService:IUserService;
18+
private _clientService:IClientService;
19+
private _flowResultBuilder:IFlowResultBuilder;
20+
1621

1722
/**
1823
* Create a new instance of password flow class.
19-
* @param userService Represents a user service.
24+
* @param userService Represents a user service used to authenticate the user.
25+
* @param clientService Represents a client service to perform some basic flow validations.
26+
* @param flowResultBuilder Represents a builder to build results.
2027
*/
21-
constructor(userService:IUserService
22-
,tokenService:ITokenService) {
28+
constructor(userService:IUserService
29+
,clientService:IClientService
30+
,flowResultBuilder:IFlowResultBuilder) {
2331

24-
super('password');
32+
super('password', clientService);
2533

2634
this._userService = userService;
27-
this._tokenService = tokenService;
35+
this._clientService = clientService;
2836
}
2937

3038
/**
@@ -37,25 +45,16 @@ export class PasswordFlow extends BaseFlow {
3745
public password:string;
3846

3947
/**
40-
* Execute the flow and handle it with the given handler.
41-
* @param handler Represents the handler for the flow.
48+
* Execute the flow resolution and handle it with the given handler.
49+
* @param handle Represents the handler.
4250
*/
43-
public async execute(handler:IFlowHandler):Promise<void> {
44-
try
45-
{
46-
if (await this._userService.validateCredential(this.username, this.password)) {
47-
let token:Token = await this._tokenService.generateToken();
48-
let result:FlowResult = new FlowResult();
49-
50-
result.accessToken = token.value;
51-
result.expireIn = token.expireIn;
52-
result.refreshToken = token.refreshToken ? token.refreshToken.value : null;
53-
54-
handler.returnResult(result);
55-
}
56-
}
57-
catch(ex) {
58-
handler.notifyError('');
51+
public async resolve(handler:IFlowHandler):Promise<boolean> {
52+
53+
if (!super.resolve(handler) && await this._userService.validateCredentials(this.username, this.password)) {
54+
handler.returnResult(await this._flowResultBuilder.getResult());
5955
}
56+
else
57+
return false;
58+
6059
}
6160
}

source/IFlowHandler.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import { FlowResult } from './Models/FlowResult'
2+
import { FlowError } from "./Models/FlowError";
23

34
/**
4-
* Represent a handler for the flows.
5+
* Represents a handler for the flows.
56
*/
67
export interface IFlowHandler {
78
/**
89
* Redirect the request to another page, usually the authorization page.
10+
* @param url Represents the url to redirect.
911
*/
1012
redirectToURL(url:string):void
1113
/**
1214
* Return the flow result to the requester client.
15+
* @param result Represents the result to return.
1316
*/
1417
returnResult(result:FlowResult):void
1518
/**
1619
* Notify an error that may occur.
20+
* @param Represents the error that occur.
1721
*/
18-
notifyError(error:string):void
22+
notifyError(error:FlowError):void
1923
}

source/IFlowResultBuilder.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { FlowResult } from "./Models/FlowResult";
2+
3+
/**
4+
* Represents the a builder to vuild flows results.
5+
*/
6+
export interface IFlowResultBuilder {
7+
/**
8+
* Return a builder FlowResult.
9+
*/
10+
getResult():Promise<FlowResult>
11+
}

source/Models/FlowError.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Represents a error in a flow validation.
3+
*/
4+
export class FlowError {
5+
6+
private _code:string;
7+
private _message:string;
8+
9+
/**
10+
* Create a new flow error instance with the given code and message.
11+
* @param code
12+
* @param message
13+
*/
14+
constructor(code:string, message:string) {
15+
this._code = code;
16+
this._message = message;
17+
}
18+
19+
/**
20+
* Get the error code.
21+
*/
22+
public get code() { return this._code; }
23+
24+
/**
25+
* Get the error message.
26+
*/
27+
public get message() { return this._message };
28+
}

source/Models/Persistents/Client.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/**
2+
* Represents a client.
3+
*/
14
export class Client {
2-
5+
/**
6+
* Get or set the client id.
7+
*/
8+
public clientId:string;
9+
10+
/**
11+
* Get or set the client secret.
12+
*/
13+
public clientSecret:string;
14+
15+
/**
16+
* Get or set the redirect uri fro the client.
17+
*/
18+
public redirectURI:string;
319
}
Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
import { Client } from '../Models/Persistents/Client'
22

3+
/**
4+
* Represents a client repository to persists clients.
5+
*/
36
export interface IClientRepository {
4-
5-
getAll():Promise<Array<Client>>;
6-
7-
getList(name:string, limit:number, offset:number):Promise<Array<Client>>;
8-
9-
getById(id:string):Promise<Client>;
10-
11-
save(client:Client):Promise<void>;
12-
13-
authenticate(clientId:string, clientSecret:string):Promise<boolean>;
7+
/**
8+
* Return a client instance by the given client id.
9+
* @param clientId Represents the id of the client to look for.
10+
*/
11+
getById(clientId:string):Promise<Client>;
1412
}

source/Repositories/ITokenRepository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Token } from '../Models/Persistents/Token'
66
export interface ITokenRepository {
77

88
/**
9-
* Get a tokent instance by the given value.
9+
* Returns a tokent instance by the given value.
1010
* @param value Represents the value to look for.
1111
*/
1212
getByValue(value:string):Promise<Token>;

source/Repositories/IUserRepository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { User } from '../Models/Persistents/User'
66
export interface IUserRepository {
77

88
/**
9-
* Get an user instance by a given name.
9+
* Returns an user instance by a given name.
1010
* @param username Represent the user name to look for.
1111
*/
1212
getByName(username:string):Promise<User>;

0 commit comments

Comments
 (0)