1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
| ///////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2015 by Charta Software B.V. //
// All rights reserved //
// //
// Version: 1.7.0.83525 //
// Web site: https://pascal.chartasoftware.com/ //
// //
// This code and information are provided "as is" without warranty of //
// any kind. Dissemination of this information or reproduction of //
// this material is strictly forbidden unless prior written permission //
// is obtained from Charta Software B.V.. //
// //
///////////////////////////////////////////////////////////////////////////
unit Http.Authorization;
interface
uses
Text,
Uuid;
type
THttpAuthorization = class(TObject)
public
function ToText(): TText; virtual; abstract;
public
class function FromText(Value: TText): THttpAuthorization;
end;
THttpBearerAuthorization = class(THttpAuthorization)
private
FToken: TText;
public
constructor Create(const Token: TText); virtual;
function ToText(): TText; override;
property Token: TText read FToken;
end;
THttpBasicAuthorization = class(THttpAuthorization)
public
UserName: TText;
Password: TText;
function ToText(): TText; override;
end;
// TODO: THttpTokenAuthorization is a self invented very simple authorization scheme which we might want to replace
// by a standard token based authorization scheme like OAuth
THttpTokenAuthorization = class(THttpAuthorization)
public
Token: TUuid;
function ToText(): TText; override;
end;
implementation
uses
Base64,
Byte.Block,
Byte.Block.Format.Text,
Character.Encoding,
Exception,
Text.Collation;
{ THttpAuthorization }
class function THttpAuthorization.FromText(Value: TText): THttpAuthorization;
var
Method: TText;
DecodedAuthorization: TByteBlock;
Authorization: TText;
Basic: THttpBasicAuthorization;
Token: THttpTokenAuthorization;
begin
Method := Value.Parse(' ');
if TTextCollation.DefaultCaseInsensitive.Equal(Method, 'Basic') then
begin
DecodedAuthorization := TByteBlockTextFormat.Base64.Parse(Value);
Authorization := TText.New(TCharacterEncoding.Windows1252, DecodedAuthorization.ToByteArray()); // TODO: Verify character encoding
DecodedAuthorization.Free();
Basic := THttpBasicAuthorization.Create();
Basic.UserName := Authorization.Parse(':');
Basic.Password := Authorization;
Result := Basic;
end
else if TTextCollation.DefaultCaseInsensitive.Equal(Method, 'Bearer') then
Result := THttpBearerAuthorization.Create(Value)
else if TTextCollation.DefaultCaseInsensitive.Equal(Method, 'Token') then
begin
Token := THttpTokenAuthorization.Create();
Token.Token := TUuid.FromText(Value);
Result := Token;
end
else
raise EException.Create('Unknown authorization method: ' + Method);
end;
{ THttpBasicAuthorization }
function THttpBasicAuthorization.ToText(): TText;
var
UserPassword: TText;
begin
UserPassword := UserName + ':' + Password;
Result := 'BASIC ' + Base64EncodeText(UserPassword);
end;
{ THttpTokenAuthorization }
function THttpTokenAuthorization.ToText(): TText;
begin
Result := 'TOKEN ' + Token.ToText();
end;
{ THttpBearerAuthorization }
constructor THttpBearerAuthorization.Create(const Token: TText);
begin
inherited Create();
FToken := Token;
end;
function THttpBearerAuthorization.ToText(): TText;
begin
Result := 'Bearer ' + Token;
end;
end.
|