VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/testmanager/core/useraccount.py@ 60308

Last change on this file since 60308 was 56295, checked in by vboxsync, 10 years ago

ValidationKit: Updated (C) year.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1# -*- coding: utf-8 -*-
2# $Id: useraccount.py 56295 2015-06-09 14:29:55Z vboxsync $
3
4"""
5Test Manager - User DB records management.
6"""
7
8__copyright__ = \
9"""
10Copyright (C) 2012-2015 Oracle Corporation
11
12This file is part of VirtualBox Open Source Edition (OSE), as
13available from http://www.virtualbox.org. This file is free software;
14you can redistribute it and/or modify it under the terms of the GNU
15General Public License (GPL) as published by the Free Software
16Foundation, in version 2 as it comes in the "COPYING" file of the
17VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19
20The contents of this file may alternatively be used under the terms
21of the Common Development and Distribution License Version 1.0
22(CDDL) only, as it comes in the "COPYING.CDDL" file of the
23VirtualBox OSE distribution, in which case the provisions of the
24CDDL are applicable instead of those of the GPL.
25
26You may elect to license modified versions of this file under the
27terms and conditions of either the GPL or the CDDL or both.
28"""
29__version__ = "$Revision: 56295 $"
30
31
32# Standard python imports.
33import unittest;
34
35# Validation Kit imports.
36from testmanager import config;
37from testmanager.core.base import ModelDataBase, ModelLogicBase, ModelDataBaseTestCase, TMExceptionBase;
38
39
40class UserAccountData(ModelDataBase):
41 """
42 User account data
43 """
44
45 ksIdAttr = 'uid';
46
47 ksParam_uid = 'UserAccount_uid'
48 ksParam_tsExpire = 'UserAccount_tsExpire'
49 ksParam_tsEffective = 'UserAccount_tsEffective'
50 ksParam_uidAuthor = 'UserAccount_uidAuthor'
51 ksParam_sLoginName = 'UserAccount_sLoginName'
52 ksParam_sUsername = 'UserAccount_sUsername'
53 ksParam_sEmail = 'UserAccount_sEmail'
54 ksParam_sFullName = 'UserAccount_sFullName'
55
56 kasAllowNullAttributes = ['uid', 'tsEffective', 'tsExpire', 'uidAuthor'];
57
58
59 def __init__(self):
60 """Init parameters"""
61 ModelDataBase.__init__(self);
62 self.uid = None;
63 self.tsEffective = None;
64 self.tsExpire = None;
65 self.uidAuthor = None;
66 self.sUsername = None;
67 self.sEmail = None;
68 self.sFullName = None;
69 self.sLoginName = None;
70
71 def initFromDbRow(self, aoRow):
72 """
73 Init from database table row
74 Returns self. Raises exception of the row is None.
75 """
76 if aoRow is None:
77 raise TMExceptionBase('User not found.');
78
79 self.uid = aoRow[0];
80 self.tsEffective = aoRow[1];
81 self.tsExpire = aoRow[2];
82 self.uidAuthor = aoRow[3];
83 self.sUsername = aoRow[4];
84 self.sEmail = aoRow[5];
85 self.sFullName = aoRow[6];
86 self.sLoginName = aoRow[7];
87 return self;
88
89 def initFromDbWithId(self, oDb, uid, tsNow = None, sPeriodBack = None):
90 """
91 Initialize the object from the database.
92 """
93 oDb.execute(self.formatSimpleNowAndPeriodQuery(oDb,
94 'SELECT *\n'
95 'FROM Users\n'
96 'WHERE uid = %s\n'
97 , ( uid, ), tsNow, sPeriodBack));
98 aoRow = oDb.fetchOne()
99 if aoRow is None:
100 raise TMExceptionBase('uid=%s not found (tsNow=%s sPeriodBack=%s)' % (uid, tsNow, sPeriodBack,));
101 return self.initFromDbRow(aoRow);
102
103 def _validateAndConvertAttribute(self, sAttr, sParam, oValue, aoNilValues, fAllowNull, oDb):
104 # Custom handling of the email field.
105 if sAttr == 'sEmail':
106 return ModelDataBase.validateEmail(oValue, aoNilValues = aoNilValues, fAllowNull = fAllowNull);
107
108 # Automatically lowercase the login name if we're supposed to do case
109 # insensitive matching. (The feature assumes lower case in DB.)
110 if sAttr == 'sLoginName' and oValue is not None and config.g_kfLoginNameCaseInsensitive:
111 oValue = oValue.lower();
112
113 return ModelDataBase._validateAndConvertAttribute(self, sAttr, sParam, oValue, aoNilValues, fAllowNull, oDb);
114
115
116class UserAccountLogic(ModelLogicBase):
117 """
118 SystemLog logic.
119 """
120
121 def fetchForListing(self, iStart, cMaxRows, tsNow):
122 """
123 Fetches user accounts.
124
125 Returns an array (list) of UserAccountData items, empty list if none.
126 Raises exception on error.
127 """
128 if tsNow is None:
129 self._oDb.execute('SELECT *\n'
130 'FROM Users\n'
131 'WHERE tsExpire = \'infinity\'::TIMESTAMP\n'
132 'ORDER BY sUsername DESC\n'
133 'LIMIT %s OFFSET %s\n'
134 , (cMaxRows, iStart,));
135 else:
136 self._oDb.execute('SELECT *\n'
137 'FROM Users\n'
138 'WHERE tsExpire > %s\n'
139 ' AND tsEffective <= %s\n'
140 'ORDER BY sUsername DESC\n'
141 'LIMIT %s OFFSET %s\n'
142 , (tsNow, tsNow, cMaxRows, iStart,));
143
144 aoRows = [];
145 for _ in range(self._oDb.getRowCount()):
146 aoRows.append(UserAccountData().initFromDbRow(self._oDb.fetchOne()));
147 return aoRows;
148
149 def addEntry(self, oData, uidAuthor, fCommit = False):
150 """
151 Add user account entry to the DB.
152 """
153 self._oDb.callProc('UserAccountLogic_addEntry',
154 (uidAuthor, oData.sUsername, oData.sEmail, oData.sFullName, oData.sLoginName,));
155 self._oDb.maybeCommit(fCommit);
156 return True;
157
158 def editEntry(self, oData, uidAuthor, fCommit = False):
159 """
160 Modify user account.
161 """
162 self._oDb.callProc('UserAccountLogic_editEntry',
163 (uidAuthor, oData.uid, oData.sUsername, oData.sEmail, oData.sFullName, oData.sLoginName,));
164 self._oDb.maybeCommit(fCommit);
165 return True;
166
167 def removeEntry(self, uidAuthor, uid, fCascade = False, fCommit = False):
168 """
169 Delete user account
170 """
171 self._oDb.callProc('UserAccountLogic_delEntry', (uidAuthor, uid));
172 self._oDb.maybeCommit(fCommit);
173 _ = fCascade;
174 return True;
175
176 def _getByField(self, sField, sValue):
177 """
178 Get user account record by its field value
179 """
180 self._oDb.execute('SELECT *\n'
181 'FROM Users\n'
182 'WHERE tsExpire = \'infinity\'::TIMESTAMP\n'
183 ' AND ' + sField + ' = %s'
184 , (sValue,))
185
186 aRows = self._oDb.fetchAll()
187 if len(aRows) not in (0, 1):
188 raise TMExceptionBase('Found more than one user account with the same credentials. Database structure is corrupted.')
189
190 try:
191 return aRows[0]
192 except IndexError:
193 return []
194
195 def getById(self, idUserId):
196 """
197 Get user account information by ID.
198 """
199 return self._getByField('uid', idUserId)
200
201 def tryFetchAccountByLoginName(self, sLoginName):
202 """
203 Try get user account information by login name.
204
205 Returns UserAccountData if found, None if not.
206 Raises exception on DB error.
207 """
208 if config.g_kfLoginNameCaseInsensitive:
209 sLoginName = sLoginName.lower();
210
211 self._oDb.execute('SELECT *\n'
212 'FROM Users\n'
213 'WHERE sLoginName = %s\n'
214 ' AND tsExpire = \'infinity\'::TIMESTAMP\n'
215 , (sLoginName, ));
216 if self._oDb.getRowCount() != 1:
217 if self._oDb.getRowCount() != 0:
218 raise self._oDb.integrityException('%u rows in Users with sLoginName="%s"'
219 % (self._oDb.getRowCount(), sLoginName));
220 return None;
221 return UserAccountData().initFromDbRow(self._oDb.fetchOne());
222
223 def resolveChangeLogAuthors(self, aoEntries):
224 """
225 Given an array of ChangeLogEntry instances, set sAuthor to whatever
226 uidAuthor resolves to.
227
228 Returns aoEntries.
229 Raises exception on DB error.
230 """
231 ahCache = dict();
232 for oEntry in aoEntries:
233 oEntry.sAuthor = ahCache.get(oEntry.uidAuthor, None);
234 if oEntry.sAuthor is None and oEntry.uidAuthor is not None:
235 try:
236 oUser = UserAccountData().initFromDbWithId(self._oDb, oEntry.uidAuthor, oEntry.tsEffective);
237 except:
238 pass;
239 else:
240 ahCache[oEntry.uidAuthor] = oUser.sUsername;
241 oEntry.sAuthor = oUser.sUsername;
242 return aoEntries;
243
244
245#
246# Unit testing.
247#
248
249# pylint: disable=C0111
250class UserAccountDataTestCase(ModelDataBaseTestCase):
251 def setUp(self):
252 self.aoSamples = [UserAccountData(),];
253
254if __name__ == '__main__':
255 unittest.main();
256 # not reached.
257
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette