source: trunk/Modules/User/User.pas

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