source: trunk/Packages/CoolWeb/Modules/WebUser.pas

Last change on this file was 151, checked in by chronos, 5 months ago
File size: 7.8 KB
Line 
1unit WebUser;
2
3interface
4
5uses
6 Classes, SysUtils, synacode, SqlDatabase, Common, HTTPServer, Generics;
7
8const
9 AnonymousUserId = 1;
10
11type
12 EDuplicateItem = class(Exception);
13 ENotFound = class(Exception);
14
15 { TWebUser }
16
17 TWebUser = class
18 Id: Integer;
19 Name: string;
20 FullName: string;
21 Email: string;
22 Database: TSqlDatabase;
23 HandlerData: THTTPHandlerData;
24 procedure Save;
25 procedure Delete(Id: Integer);
26 procedure Add(Name, Password, Email: string);
27 function GetIdByName(Name: string): Integer;
28 function GetIdByNamePassword(Name: string; PassWord: string): Integer;
29 procedure Load;
30 function CheckPermission(Module, Operation: string; ItemType: string = '';
31 ItemId: Integer = 0): Boolean;
32 function CheckGroupPermission(Group, Operation: Integer): Boolean;
33 end;
34
35 { TWebOnlineUser }
36
37 TWebOnlineUser = class
38 Database: TSqlDatabase;
39 HandlerData: THTTPHandlerData;
40 Id: Integer;
41 User: Integer;
42 procedure Update;
43 procedure Login(User: Integer);
44 procedure Logout;
45 end;
46
47
48implementation
49
50resourcestring
51 SDuplicateUserItem = 'User name "%s" already used.';
52 SEmptyUserParameters = 'Missing user parameters';
53 SUserNotFound = 'User "%s" not found';
54
55{ TOnlineUser }
56
57procedure TWebOnlineUser.Update;
58var
59 DbRows: TDbRows;
60 Id: Integer;
61 Value: string;
62begin
63 try
64 DbRows := TDbRows.Create;
65 if HandlerData.Request.Cookies.TryGetValue('SessionId', Value) then begin
66 Database.Query(DbRows, 'SELECT * FROM `UserOnline` WHERE `SessionId`="' +
67 Value + '"');
68 if DbRows.Count > 0 then begin
69 // Update exited
70 Id := StrToInt(DbRows[0].Items['Id']);
71 User := StrToInt(DbRows[0].Items['User']);
72 Database.Query(DbRows, 'UPDATE `UserOnline` SET `ActivityTime` = NOW() WHERE `Id`=' + IntToStr(Id));
73 end else begin
74 // Create new record
75 Database.Query(DbRows, 'INSERT INTO `UserOnline` (`User`, `ActivityTime`, `SessionId`, `ScriptName`) ' +
76 'VALUES (1, NOW(), "' + Value + '", "")');
77 Id := Database.LastInsertId;
78 User := 1;
79 end;
80
81 end;
82 finally
83 DbRows.Free;
84 end;
85end;
86
87procedure TWebOnlineUser.Login(User: Integer);
88var
89 DbRows: TDbRows;
90 SessionId: string;
91begin
92 Logout;
93 if HandlerData.Request.Cookies.TryGetValue('SessionId', SessionId) then
94 try
95 DbRows := TDbRows.Create;
96 Database.Query(DbRows, 'UPDATE `UserOnline` SET `User` = ' + IntToStr(User) + ', `LoginTime` = NOW() WHERE `SessionId`="' +
97 SessionId + '"');
98 finally
99 DbRows.Free;
100 end;
101 Self.User := User;
102end;
103
104procedure TWebOnlineUser.Logout;
105var
106 DbRows: TDbRows;
107 SessionId: string;
108begin
109 if Id = AnonymousUserId then Update;
110 if (User <> AnonymousUserId) and
111 HandlerData.Request.Cookies.TryGetValue('SessionId', SessionId) then begin
112 try
113 DbRows := TDbRows.Create;
114 Database.Query(DbRows, 'UPDATE `UserOnline` SET `User` = ' + IntToStr(AnonymousUserId) + ' WHERE `SessionId`="' +
115 SessionId + '"');
116 finally
117 DbRows.Free;
118 end;
119 User := AnonymousUserId;
120 end;
121end;
122
123{ TUser }
124
125procedure TWebUser.Save;
126var
127 DbRows: TDbRows;
128 Data: TDictionaryStringString;
129begin
130 try
131 DbRows := TDbRows.Create;
132 Data := TDictionaryStringString.Create;
133 Data.Add('FullName', FullName);
134 Data.Add('Email', Email);
135 Data.Add('Name', Name);
136 //Data.Add('Password', 'SHA1(CONCAT("' + Password + '", "' + Salt + '"))');
137 Database.Update('User', Data, '`Id`=' + IntToStr(Id));
138 finally
139 Data.Free;
140 DbRows.Free;
141 end;
142end;
143
144procedure TWebUser.Delete(Id: Integer);
145var
146 DbRows: TDbRows;
147begin
148 try
149 DbRows := TDbRows.Create;
150 Database.Query(DbRows, 'DELETE FROM `User` WHERE `Id`=' + IntToStr(Id));
151 finally
152 DbRows.Free;
153 end;
154end;
155
156procedure TWebUser.Add(Name, Password, Email: string);
157var
158 Salt: string;
159 DbRows: TDbRows;
160begin
161 if (Name = '') or (Password = '') or (Email = '') then
162 raise Exception.Create(SEmptyUserParameters);
163 try
164 DbRows := TDbRows.Create;
165 Database.Query(DbRows, 'SELECT `Id` FROM `User` WHERE `Name`="' + Name + '"');
166 if DbRows.Count = 0 then begin
167 Salt := EncodeBase64(Copy(BinToHexString(SHA1(FloatToStr(Now))), 1, 8));
168 Database.Query(DbRows, 'INSERT INTO `User` (`Name`, `Password`, `Salt`, `Email`, `RegistrationTime`, `FullName`) VALUES ("' +
169 Name + '", SHA1(CONCAT("' + Password + '", "' + Salt + '")), "' + Salt +
170 '", "' + Email + '", NOW(), "")');
171 end else raise EDuplicateItem.Create(Format(SDuplicateUserItem, [Name]));
172 finally
173 DbRows.Free;
174 end;
175end;
176
177function TWebUser.GetIdByName(Name: string): Integer;
178var
179 DbRows: TDbRows;
180begin
181 try
182 DbRows := TDbRows.Create;
183 Database.Query(DbRows, 'SELECT `Id` FROM `User` WHERE `Name`="' + Name + '"');
184 if DbRows.Count = 1 then Result := StrToInt(DbRows[0].Items['Id'])
185 else Result := -1;
186 finally
187 DBRows.Free;
188 end;
189end;
190
191function TWebUser.GetIdByNamePassword(Name: string; PassWord: string): Integer;
192var
193 DbRows: TDbRows;
194begin
195 try
196 DbRows := TDbRows.Create;
197 Database.Query(DbRows, 'SELECT `Id` FROM `User` WHERE `Name`="' + Name + '" AND ' +
198 '`Password` = SHA1(CONCAT("' + Password + '", Salt))');
199 if DbRows.Count = 1 then Result := StrToInt(DbRows[0].Items['Id'])
200 else Result := -1;
201 finally
202 DBRows.Free;
203 end;
204end;
205
206procedure TWebUser.Load;
207var
208 DbRows: TDbRows;
209begin
210 try
211 DbRows := TDbRows.Create;
212 Database.Query(DbRows, 'SELECT * FROM `User` WHERE `Id`="' + IntToStr(Id) + '"');
213 if DbRows.Count = 1 then begin
214 Name := DbRows[0].Items['Name'];
215 FullName := DbRows[0].Items['FullName'];
216 Email := DbRows[0].Items['Email'];
217 end; // else raise ENotFound.Create(Format(SUserNotFound, [IntToStr(Id)]));
218 finally
219 DBRows.Free;
220 end;
221end;
222
223function TWebUser.CheckPermission(Module, Operation: string;
224 ItemType: string = ''; ItemId: Integer = 0): Boolean;
225var
226 DbRows: TDbRows;
227 DbRows2: TDbRows;
228 OperationId: Integer;
229begin
230 Result := False;
231 try
232 DbRows := TDbRows.Create;
233 Database.Query(DbRows, 'SELECT `Id` FROM `PermissionOperation` WHERE `Module`="' + Module + '"' +
234 ' AND `Operation` = "' + Operation + '" AND `Item` = "' + ItemType + '"' +
235 ' AND `ItemId` = ' + IntToStr(ItemId));
236 if DbRows.Count > 0 then
237 try
238 DbRows2 := TDbRows.Create;
239 OperationId := StrToInt(DbRows[0].Items['Id']);
240
241 // Check user-operation relation
242 Database.Select(DbRows2, 'PermissionUserAssignment', 'Id',
243 '`User` = ' + IntToStr(Id) + ' AND `AssignedOperation` = ' + IntToStr(OperationId));
244 if DbRows2.Count > 0 then begin
245 Result := True;
246 Exit;
247 end;
248
249 // Check user-group relation
250 Database.Select(DbRows2, 'PermissionUserAssignment', 'AssignedGroup',
251 '`User` = ' + IntToStr(Id) + ' AND `AssignedGroup` IS NOT NULL');
252 if DbRows2.Count > 0 then begin
253 if CheckGroupPermission(StrToInt(DbRows2[0].Items['AssignedGroup']), OperationId) then begin
254 Result := True;
255 Exit;
256 end;
257 end;
258 finally
259 DbRows2.Free;
260 end;
261 finally
262 DBRows.Free;
263 end;
264end;
265
266function TWebUser.CheckGroupPermission(Group, Operation: Integer): Boolean;
267var
268 DbRows2: TDbRows;
269begin
270 Result := False;
271 try
272 DbRows2 := TDbRows.Create;
273
274 // Check group-operation relation
275 Database.Select(DbRows2, 'PermissionGroupAssignment', 'Id',
276 '`User` = ' + IntToStr(Id) + ' AND `AssignedOperation` = ' + IntToStr(Operation));
277 if DbRows2.Count > 0 then begin
278 Result := True;
279 Exit;
280 end;
281
282 // Check group-group relation
283 Database.Select(DbRows2, 'PermissionGroupAssignment', 'AssignedGroup',
284 '`User` = ' + IntToStr(Id) + ' AND `AssignedGroup` IS NOT NULL');
285 if DbRows2.Count > 0 then begin
286 if CheckGroupPermission(StrToInt(DbRows2[0].Items['AssignedGroup']), Operation) then begin
287 Result := True;
288 Exit;
289 end;
290 end;
291 finally
292 DbRows2.Free;
293 end;
294end;
295
296end.
297
Note: See TracBrowser for help on using the repository browser.