Browse Source

Use account_id to identify the user's own account

This is necessary on systems where the username may not be present
(e.g., gerrit-review.googlesource.com).

Change-Id: Ia91b1e9b0fb0f98728dca46a488a92a97a301274
changes/52/679052/1
James E. Blair 2 weeks ago
parent
commit
73a6481835

+ 26
- 0
gertty/alembic/versions/a18731009699_add_server_table.py View File

@@ -0,0 +1,26 @@
1
+"""add_server_table
2
+
3
+Revision ID: a18731009699
4
+Revises: 399c4b3dcc9a
5
+Create Date: 2019-08-28 14:12:22.657691
6
+
7
+"""
8
+
9
+# revision identifiers, used by Alembic.
10
+revision = 'a18731009699'
11
+down_revision = '399c4b3dcc9a'
12
+
13
+from alembic import op
14
+import sqlalchemy as sa
15
+
16
+
17
+def upgrade():
18
+    op.create_table('server',
19
+    sa.Column('key', sa.Integer(), nullable=False),
20
+    sa.Column('own_account_key', sa.Integer(), sa.ForeignKey('own_account.key'), index=True),
21
+    sa.PrimaryKeyConstraint('key')
22
+    )
23
+
24
+
25
+def downgrade():
26
+    pass

+ 15
- 3
gertty/app.py View File

@@ -289,8 +289,15 @@ class App(object):
289 289
 
290 290
         self.fetch_missing_refs = fetch_missing_refs
291 291
         self.config.keymap.updateCommandMap()
292
-        self.search = search.SearchCompiler(self.config.username)
292
+        self.search = search.SearchCompiler(self.getOwnAccountId)
293 293
         self.db = db.Database(self, self.config.dburi, self.search)
294
+
295
+        self.own_account_id = None
296
+        with self.db.getSession() as session:
297
+            account = session.getOwnAccount()
298
+            if account:
299
+                self.own_account_id = account.id
300
+
294 301
         self.sync = sync.Sync(self, disable_background_sync)
295 302
 
296 303
         self.status = StatusHeader(self)
@@ -342,6 +349,12 @@ class App(object):
342 349
             self.sync.offline = True
343 350
             self.status.update(offline=True)
344 351
 
352
+    def getOwnAccountId(self):
353
+        return self.own_account_id
354
+
355
+    def isOwnAccount(self, account):
356
+        return account.id == self.own_account_id
357
+
345 358
     def run(self):
346 359
         try:
347 360
             self.loop.run()
@@ -801,8 +814,7 @@ class App(object):
801 814
     def saveReviews(self, revision_keys, approvals, message, upload, submit):
802 815
         message_keys = []
803 816
         with self.db.getSession() as session:
804
-            account = session.getAccountByUsername(self.config.username)
805
-            account = session.getAccountByID(self.sync.account_id)
817
+            account = session.getOwnAccount()
806 818
             for revision_key in revision_keys:
807 819
                 k = self._saveReview(session, account, revision_key,
808 820
                                      approvals, message, upload, submit)

+ 35
- 0
gertty/db.py View File

@@ -192,6 +192,11 @@ file_table = Table(
192 192
     Column('deleted', Integer),
193 193
     Column('status', String(1), nullable=False),
194 194
     )
195
+server_table = Table(
196
+    'server', metadata,
197
+    Column('key', Integer, primary_key=True),
198
+    Column('own_account_key', Integer, ForeignKey("account.key"), index=True),
199
+    )
195 200
 
196 201
 
197 202
 class Account(object):
@@ -644,6 +649,10 @@ class File(object):
644 649
         session.flush()
645 650
         return c
646 651
 
652
+class Server(object):
653
+    def __init__(self):
654
+        pass
655
+
647 656
 
648 657
 mapper(Account, account_table)
649 658
 mapper(Project, project_table, properties=dict(
@@ -750,6 +759,9 @@ mapper(Approval, approval_table, properties=dict(
750 759
 mapper(PendingCherryPick, pending_cherry_pick_table)
751 760
 mapper(SyncQuery, sync_query_table)
752 761
 mapper(Hashtag, hashtag_table)
762
+mapper(Server, server_table, properties=dict(
763
+    own_account=relationship(Account)
764
+    ))
753 765
 
754 766
 def match(expr, item):
755 767
     if item is None:
@@ -763,6 +775,7 @@ def add_sqlite_match(dbapi_connection, connection_record):
763 775
 class Database(object):
764 776
     def __init__(self, app, dburi, search):
765 777
         self.log = logging.getLogger('gertty.db')
778
+        self.own_account_key = None
766 779
         self.dburi = dburi
767 780
         self.search = search
768 781
         self.engine = create_engine(self.dburi)
@@ -1057,6 +1070,28 @@ class DatabaseSession(object):
1057 1070
     def getSystemAccount(self):
1058 1071
         return self.getAccountByID(0, 'Gerrit Code Review')
1059 1072
 
1073
+    def setOwnAccount(self, account):
1074
+        try:
1075
+            server = self.session().query(Server).one()
1076
+        except sqlalchemy.orm.exc.NoResultFound:
1077
+            server = Server()
1078
+            self.session().add(server)
1079
+            self.session().flush()
1080
+        server.own_account = account
1081
+        self.database.own_account_key = account.key
1082
+
1083
+    def getOwnAccount(self):
1084
+        if self.database.own_account_key is None:
1085
+            try:
1086
+                server = self.session().query(Server).one()
1087
+            except sqlalchemy.orm.exc.NoResultFound:
1088
+                return None
1089
+            self.database.own_account_key = server.own_account.key
1090
+        try:
1091
+            return self.session().query(Account).filter_by(key=self.database.own_account_key).one()
1092
+        except sqlalchemy.orm.exc.NoResultFound:
1093
+            return None
1094
+
1060 1095
     def createProject(self, *args, **kw):
1061 1096
         o = Project(*args, **kw)
1062 1097
         self.session().add(o)

+ 7
- 3
gertty/search/__init__.py View File

@@ -25,10 +25,11 @@ class SearchSyntaxError(Exception):
25 25
 
26 26
 
27 27
 class SearchCompiler(object):
28
-    def __init__(self, username):
29
-        self.username = username
28
+    def __init__(self, get_account_id):
29
+        self.get_account_id = get_account_id
30 30
         self.lexer = tokenizer.SearchTokenizer()
31 31
         self.parser = parser.SearchParser()
32
+        self.parser.account_id = None
32 33
 
33 34
     def findTables(self, expression):
34 35
         tables = set()
@@ -45,7 +46,10 @@ class SearchCompiler(object):
45 46
         return tables
46 47
 
47 48
     def parse(self, data):
48
-        self.parser.username = self.username
49
+        if self.parser.account_id is None:
50
+            self.parser.account_id = self.get_account_id()
51
+        if self.parser.account_id is None:
52
+            raise Exception("Own account is unknown")
49 53
         result = self.parser.parse(data, lexer=self.lexer)
50 54
         tables = self.findTables(result)
51 55
         if gertty.db.project_table in tables:

+ 8
- 8
gertty/search/parser.py View File

@@ -136,8 +136,8 @@ def SearchParser():
136 136
     def p_owner_term(p):
137 137
         '''owner_term : OP_OWNER string'''
138 138
         if p[2] == 'self':
139
-            username = p.parser.username
140
-            p[0] = gertty.db.account_table.c.username == username
139
+            account_id = p.parser.account_id
140
+            p[0] = gertty.db.account_table.c.id == account_id
141 141
         else:
142 142
             p[0] = or_(gertty.db.account_table.c.username == p[2],
143 143
                        gertty.db.account_table.c.email == p[2],
@@ -156,8 +156,8 @@ def SearchParser():
156 156
         if number is not None:
157 157
             filters.append(gertty.db.account_table.c.id == number)
158 158
         elif p[2] == 'self':
159
-            username = p.parser.username
160
-            filters.append(gertty.db.account_table.c.username == username)
159
+            account_id = p.parser.account_id
160
+            filters.append(gertty.db.account_table.c.id == account_id)
161 161
         else:
162 162
             filters.append(or_(gertty.db.account_table.c.username == p[2],
163 163
                                gertty.db.account_table.c.email == p[2],
@@ -234,7 +234,7 @@ def SearchParser():
234 234
         if user is not None:
235 235
             filters.append(gertty.db.approval_table.c.account_key == gertty.db.account_table.c.key)
236 236
             if user == 'self':
237
-                filters.append(gertty.db.account_table.c.username == p.parser.username)
237
+                filters.append(gertty.db.account_table.c.id == p.parser.account_id)
238 238
             else:
239 239
                 filters.append(
240 240
                     or_(gertty.db.account_table.c.username == user,
@@ -281,7 +281,7 @@ def SearchParser():
281 281
     def p_is_term(p):
282 282
         '''is_term : OP_IS string'''
283 283
         #TODO: implement draft
284
-        username = p.parser.username
284
+        account_id = p.parser.account_id
285 285
         if p[2] == 'reviewed':
286 286
             filters = []
287 287
             filters.append(gertty.db.approval_table.c.change_key == gertty.db.change_table.c.key)
@@ -299,7 +299,7 @@ def SearchParser():
299 299
         elif p[2] == 'abandoned':
300 300
             p[0] = gertty.db.change_table.c.status == 'ABANDONED'
301 301
         elif p[2] == 'owner':
302
-            p[0] = gertty.db.account_table.c.username == username
302
+            p[0] = gertty.db.account_table.c.id == account_id
303 303
         elif p[2] == 'starred':
304 304
             p[0] = gertty.db.change_table.c.starred == True
305 305
         elif p[2] == 'held':
@@ -309,7 +309,7 @@ def SearchParser():
309 309
             filters = []
310 310
             filters.append(gertty.db.approval_table.c.change_key == gertty.db.change_table.c.key)
311 311
             filters.append(gertty.db.approval_table.c.account_key == gertty.db.account_table.c.key)
312
-            filters.append(gertty.db.account_table.c.username == username)
312
+            filters.append(gertty.db.account_table.c.id == account_id)
313 313
             s = select([gertty.db.change_table.c.key], correlate=False).where(and_(*filters))
314 314
             p[0] = gertty.db.change_table.c.key.in_(s)
315 315
         elif p[2] == 'watched':

+ 6
- 4
gertty/sync.py View File

@@ -199,10 +199,12 @@ class SyncOwnAccountTask(Task):
199 199
         remote = sync.get('accounts/self')
200 200
         sync.account_id = remote['_account_id']
201 201
         with app.db.getSession() as session:
202
-            session.getAccountByID(remote['_account_id'],
203
-                                   remote.get('name'),
204
-                                   remote.get('username'),
205
-                                   remote.get('email'))
202
+            account = session.getAccountByID(remote['_account_id'],
203
+                                             remote.get('name'),
204
+                                             remote.get('username'),
205
+                                             remote.get('email'))
206
+            session.setOwnAccount(account)
207
+        app.own_account_id = remote['_account_id']
206 208
 
207 209
 class GetVersionTask(Task):
208 210
     def __repr__(self):

+ 3
- 3
gertty/view/change.py View File

@@ -172,7 +172,7 @@ class ReviewDialog(urwid.WidgetWrap, mywid.LineBoxTitlePropertyMixin):
172 172
                 draft_approvals = {}
173 173
                 prior_approvals = {}
174 174
                 for approval in change.approvals:
175
-                    if approval.reviewer.username == self.app.config.username:
175
+                    if self.app.isOwnAccount(approval.reviewer):
176 176
                         if approval.draft:
177 177
                             draft_approvals[approval.category] = approval
178 178
                         else:
@@ -440,7 +440,7 @@ class ChangeMessageBox(mywid.HyperText):
440 440
         if message.draft:
441 441
             lines.insert(0, '')
442 442
             lines.insert(0, 'Patch Set %s:' % (message.revision.number,))
443
-        if message.author.username == self.app.config.username:
443
+        if self.app.isOwnAccount(message.author):
444 444
             name_style = 'change-message-own-name'
445 445
             header_style = 'change-message-own-header'
446 446
             reviewer_string = message.author_name
@@ -748,7 +748,7 @@ class ChangeView(urwid.WidgetWrap):
748 748
                 if not approvals:
749 749
                     approvals = {}
750 750
                     row = []
751
-                    if approval.reviewer.username == self.app.config.username:
751
+                    if self.app.isOwnAccount(approval.reviewer):
752 752
                         style = 'reviewer-own-name'
753 753
                     else:
754 754
                         style = 'reviewer-name'

+ 1
- 1
gertty/view/diff.py View File

@@ -530,7 +530,7 @@ class BaseDiffView(urwid.WidgetWrap, mywid.Searchable):
530 530
             raise Exception("Comment is not associated with a file")
531 531
         with self.app.db.getSession() as session:
532 532
             fileobj = session.getFile(file_key)
533
-            account = session.getAccountByUsername(self.app.config.username)
533
+            account = session.getOwnAccount()
534 534
             comment = fileobj.createComment(None, account, None,
535 535
                                             datetime.datetime.utcnow(),
536 536
                                             parent,

Loading…
Cancel
Save