Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2631)

Unified Diff: appengine/monorail/framework/framework_views.py

Issue 1868553004: Open Source Monorail (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: Rebase Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « appengine/monorail/framework/framework_helpers.py ('k') | appengine/monorail/framework/gcs_helpers.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: appengine/monorail/framework/framework_views.py
diff --git a/appengine/monorail/framework/framework_views.py b/appengine/monorail/framework/framework_views.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b9453c44aee977f4ce19ad51b69e9af344998a3
--- /dev/null
+++ b/appengine/monorail/framework/framework_views.py
@@ -0,0 +1,214 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is govered by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""View classes to make it easy to display framework objects in EZT."""
+
+from third_party import ezt
+
+from framework import framework_bizobj
+from framework import framework_constants
+from framework import permissions
+from framework import template_helpers
+from services import client_config_svc
+import settings
+
+
+_LABEL_DISPLAY_CHARS = 30
+_LABEL_PART_DISPLAY_CHARS = 15
+
+
+class LabelView(object):
+ """Wrapper class that makes it easier to display a label via EZT."""
+
+ def __init__(self, label, config):
+ """Make several values related to this label available as attrs.
+
+ Args:
+ label: artifact label string. E.g., 'Priority-High' or 'Frontend'.
+ config: PB with a well_known_labels list, or None.
+ """
+ self.name = label
+ self.tooltip = label
+ self.is_restrict = ezt.boolean(permissions.IsRestrictLabel(label))
+
+ self.docstring = ''
+ if config:
+ for wkl in config.well_known_labels:
+ if label.lower() == wkl.label.lower():
+ self.docstring = wkl.label_docstring
+
+ if '-' in label:
+ self.prefix, self.value = label.split('-', 1)
+ else:
+ self.prefix, self.value = '', label
+
+
+class StatusView(object):
+ """Wrapper class that makes it easier to display a status via EZT."""
+
+ def __init__(self, status, config):
+ """Make several values related to this status available as attrs.
+
+ Args:
+ status: artifact status string. E.g., 'New' or 'Accepted'.
+ config: PB with a well_known_statuses list, or None.
+ """
+
+ self.name = status
+ self.tooltip = status
+
+ self.docstring = ''
+ self.means_open = ezt.boolean(True)
+ if config:
+ for wks in config.well_known_statuses:
+ if status.lower() == wks.status.lower():
+ self.docstring = wks.status_docstring
+ self.means_open = ezt.boolean(wks.means_open)
+
+
+class UserView(object):
+ """Wrapper class to easily display basic user information in a template."""
+
+ def __init__(self, user_id, email, obscure_email):
+ email = email or ''
+ self.user_id = user_id
+ self.email = email
+ self.profile_url = '/u/%s/' % user_id
+ self.obscure_email = obscure_email
+ self.banned = ''
+
+ (self.username, self.domain,
+ self.obscured_username) = ParseAndObscureAddress(email)
+ # No need to obfuscate or reveal client email.
+ # Instead display a human-readable username.
+ if not self.email:
+ self.display_name = 'a deleted user'
+ self.obscure_email = ''
+ self.profile_url = ''
+ elif self.email in client_config_svc.GetServiceAccountMap():
+ self.display_name = client_config_svc.GetServiceAccountMap()[self.email]
+ elif not self.obscure_email:
+ self.display_name = email
+ else:
+ self.display_name = '%s...@%s' % (self.obscured_username, self.domain)
+
+ def RevealEmail(self):
+ if not self.email:
+ return
+ if self.email not in client_config_svc.GetServiceAccountMap():
+ self.obscure_email = False
+ self.display_name = self.email
+ self.profile_url = '/u/%s/' % self.email
+
+
+def MakeAllUserViews(cnxn, user_service, *list_of_user_id_lists):
+ """Make a dict {user_id: user_view, ...} for all user IDs given."""
+ distinct_user_ids = set()
+ distinct_user_ids.update(*list_of_user_id_lists)
+ user_dict = user_service.GetUsersByIDs(cnxn, distinct_user_ids)
+ return {user_id: UserView(user_id, user_pb.email, user_pb.obscure_email)
+ for user_id, user_pb in user_dict.iteritems()}
+
+
+def MakeUserView(cnxn, user_service, user_id):
+ """Make a UserView for the given user ID."""
+ user = user_service.GetUser(cnxn, user_id)
+ return UserView(user_id, user.email, user.obscure_email)
+
+
+def ParseAndObscureAddress(email):
+ """Break the given email into username and domain, and obscure.
+
+ Args:
+ email: string email address to process
+
+ Returns:
+ A 3-tuple (username, domain, obscured_username).
+ The obscured_username is trucated the same way that Google Groups does it.
+ """
+ if '@' in email:
+ username, user_domain = email.split('@', 1)
+ else: # don't fail if User table has unexpected email address format.
+ username, user_domain = email, ''
+
+ base_username = username.split('+')[0]
+ cutoff_point = min(8, max(1, len(base_username) - 3))
+ obscured_username = base_username[:cutoff_point]
+
+ return username, user_domain, obscured_username
+
+
+def _ShouldRevealEmail(auth, project, viewed_email):
+ """Decide whether to publish a user's email address.
+
+ Args:
+ auth: The AuthData of the user viewing the email addresses.
+ project: The project to which the viewed users belong.
+ viewed_email: The email of the viewed user.
+
+ Returns:
+ True if email addresses should be published to the logged-in user.
+ """
+ # Case 1: Anon users don't see anything revealed.
+ if auth.user_pb is None:
+ return False
+
+ # Case 2: site admins always see unobscured email addresses.
+ if auth.user_pb.is_site_admin:
+ return True
+
+ # Case 3: Domain users in same-org-only projects always see unobscured addrs.
+ # TODO(jrobbins): re-implement same_org
+
+ # Case 4: Project members see the unobscured email of everyone in a project.
+ if project and framework_bizobj.UserIsInProject(project, auth.effective_ids):
+ return True
+
+ # Case 5: Emails that end in priviledged user domains see unobscured email
+ # addresses.
+ if framework_bizobj.IsPriviledgedDomainUser(auth.user_pb.email):
+ return True
+
+ # Case 6: Do not obscure your own email.
+ if viewed_email and auth.user_pb.email == viewed_email:
+ return True
+
+ return False
+
+
+def RevealAllEmailsToMembers(mr, users_by_id):
+ """Allow project members to see unobscured email addresses in that project.
+
+ Non project member addresses will be obscured.
+ Site admins can see all email addresses unobscured.
+
+ Args:
+ mr: common info parsed from the user's request.
+ users_by_id: dictionary of UserView's that will be displayed.
+
+ Returns:
+ Nothing, but the UserViews in users_by_id may be modified to
+ publish email address.
+ """
+ for user_view in users_by_id.itervalues():
+ if _ShouldRevealEmail(mr.auth, mr.project, user_view.email):
+ user_view.RevealEmail()
+
+
+def RevealAllEmails(users_by_id):
+ """Allow anyone to see unobscured email addresses of project members.
+
+ The modified view objects should only be used to generate views for other
+ project members.
+
+ Args:
+ users_by_id: dictionary of UserViews that will be displayed.
+
+ Returns:
+ Nothing, but the UserViews in users_by_id may be modified to
+ publish email address.
+ """
+ for user_view in users_by_id.itervalues():
+ user_view.RevealEmail()
« no previous file with comments | « appengine/monorail/framework/framework_helpers.py ('k') | appengine/monorail/framework/gcs_helpers.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698