def testIsServiceAccount(self): appspot = '*****@*****.**' developer = '@developer.gserviceaccount.com' bugdroid = '*****@*****.**' user = '******' self.assertTrue(framework_helpers.IsServiceAccount(appspot)) self.assertTrue(framework_helpers.IsServiceAccount(developer)) self.assertTrue(framework_helpers.IsServiceAccount(bugdroid)) self.assertFalse(framework_helpers.IsServiceAccount(user))
def __init__(self, logged_in_user_id, member_id, user_view, project, project_commitments, effective_ids=None, ac_exclusion=False, no_expand=False, is_group=False): """Initialize a MemberView with the given information. Args: logged_in_user_id: int user ID of the viewing user, or 0 for anon. member_id: int user ID of the project member being viewed. user_view: UserView object for this member. project: Project PB for the currently viewed project. project_commitments: ProjectCommitments PB for the currently viewed project, or None if commitments are not to be displayed. effective_ids: optional set of user IDs for this user, if supplied we show the highest role that they have via any group membership. ac_exclusion: True when this member should not be in autocomplete. no_expand: True for user groups that should not expand when generating autocomplete options. is_group: True if this user is actually a user group. """ self.viewing_self = ezt.boolean(logged_in_user_id == member_id) self.user = user_view member_qs_param = user_view.user_id self.detail_url = '/p/%s%s?u=%s' % ( project.project_name, urls.PEOPLE_DETAIL, member_qs_param) self.role = framework_helpers.GetRoleName(effective_ids or {member_id}, project) self.extra_perms = permissions.GetExtraPerms(project, member_id) self.notes = None if project_commitments is not None: for commitment in project_commitments.commitments: if commitment.member_id == member_id: self.notes = commitment.notes break # Attributes needed by table_view_helpers.py self.labels = [] self.derived_labels = [] self.ac_include = ezt.boolean(not ac_exclusion) self.ac_expand = ezt.boolean(not no_expand) self.is_group = ezt.boolean(is_group) self.is_service_account = ezt.boolean( framework_helpers.IsServiceAccount(self.user.email))
def GetVisibleMembers(mr, project, services): all_member_ids = framework_bizobj.AllProjectMembers(project) all_group_ids = services.usergroup.DetermineWhichUserIDsAreGroups( mr.cnxn, all_member_ids) (ac_exclusion_ids, no_expand_ids) = services.project.GetProjectAutocompleteExclusion( mr.cnxn, project.project_id) group_ids_to_expand = [ gid for gid in all_group_ids if gid not in no_expand_ids ] # TODO(jrobbins): Normally, users will be allowed view the members # of any user group if the project From: email address is listed # as a group member, as well as any group that they are personally # members of. member_ids, owner_ids = services.usergroup.LookupVisibleMembers( mr.cnxn, group_ids_to_expand, mr.perms, mr.auth.effective_ids, services) indirect_user_ids = set() for gids in member_ids.values(): indirect_user_ids.update(gids) for gids in owner_ids.values(): indirect_user_ids.update(gids) visible_member_ids = _FilterMemberData(mr, project.owner_ids, project.committer_ids, project.contributor_ids, indirect_user_ids, project) visible_member_ids = _MergeLinkedMembers(mr.cnxn, services.user, visible_member_ids) visible_member_views = framework_views.MakeAllUserViews( mr.cnxn, services.user, visible_member_ids, group_ids=all_group_ids) # Filter out service accounts service_acct_emails = set( client_config_svc.GetClientConfigSvc().GetClientIDEmails()[1]) visible_member_views = { m.user_id: m for m in visible_member_views.values() if not framework_helpers.IsServiceAccount( m.email, client_emails=service_acct_emails) and not m.user_id in ac_exclusion_ids } return visible_member_views
def increment_request_limit(self, request, client_id, client_email): """Check whether the requester has exceeded API quotas limit, and increment request count in DB and ts_mon. """ mar = self.mar_factory(request) # soft_limit == hard_limit for api_request, so this function either # returns False if under limit, or raise ExcessiveActivityException if not actionlimit.NeedCaptcha( mar.auth.user_pb, actionlimit.API_REQUEST, skip_lifetime_check=True): actionlimit.CountAction( mar.auth.user_pb, actionlimit.API_REQUEST, delta=1) self._services.user.UpdateUser( mar.cnxn, mar.auth.user_id, mar.auth.user_pb) # Avoid value explosision and protect PII info if not framework_helpers.IsServiceAccount(client_email): client_email = '*****@*****.**' self.api_requests.increment_by( 1, {'client_id': client_id, 'client_email': client_email})
def HandleRequest(self, mr): """Provide the UI with info used in auto-completion. Args: mr: common information parsed from the HTTP request. Returns: Results dictionary in JSON format """ # Issue options data can be cached separately in each user's browser. When # the project changes, a new cached_content_timestamp is set and it will # cause new requests to use a new URL. self.SetCacheHeaders(self.response) member_data = project_helpers.BuildProjectMembers( mr.cnxn, mr.project, self.services.user) owner_views = member_data['owners'] committer_views = member_data['committers'] contributor_views = member_data['contributors'] config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id) open_statuses = [] closed_statuses = [] for wks in config.well_known_statuses: if not wks.deprecated: item = dict(name=wks.status, doc=wks.status_docstring) if wks.means_open: open_statuses.append(item) else: closed_statuses.append(item) # TODO(jrobbins): restrictions on component definitions? components = [{'name': cd.path, 'doc': cd.docstring} for cd in config.component_defs if not cd.deprecated] labels = [] field_names = [ fd.field_name for fd in config.field_defs if not fd.is_deleted] non_masked_labels = tracker_helpers.LabelsNotMaskedByFields( config, field_names) for wkl in non_masked_labels: if not wkl.commented: item = dict(name=wkl.name, doc=wkl.docstring) labels.append(item) # TODO(jrobbins): omit fields that they don't have permission to view. field_def_views = [ tracker_views.FieldDefView(fd, config) for fd in config.field_defs if not fd.is_deleted] fields = [ dict(field_name=fdv.field_name, field_type=fdv.field_type, field_id=fdv.field_id, needs_perm=fdv.needs_perm, is_required=fdv.is_required, is_multivalued=fdv.is_multivalued, choices=[dict(name=c.name, doc=c.docstring) for c in fdv.choices], docstring=fdv.docstring) for fdv in field_def_views] frequent_restrictions = _FREQUENT_ISSUE_RESTRICTIONS[:] custom_permissions = permissions.GetCustomPermissions(mr.project) if not custom_permissions: frequent_restrictions.extend( _EXAMPLE_ISSUE_RESTRICTIONS) labels.extend(_BuildRestrictionChoices( mr.project, frequent_restrictions, permissions.STANDARD_ISSUE_PERMISSIONS)) group_ids = self.services.usergroup.DetermineWhichUserIDsAreGroups( mr.cnxn, [mem.user_id for mem in member_data['all_members']]) logging.info('group_ids is %r', group_ids) acexclusion_ids = self.services.project.GetProjectAutocompleteExclusion( mr.cnxn, mr.project_id) # TODO(jrobbins): Normally, users will be allowed view the members # of any user group if the project From: email address is listed # as a group member, as well as any group that they are personally # members of. member_ids, owner_ids = self.services.usergroup.LookupVisibleMembers( mr.cnxn, group_ids, mr.perms, mr.auth.effective_ids, self.services) indirect_ids = set() for gid in group_ids: indirect_ids.update(member_ids.get(gid, [])) indirect_ids.update(owner_ids.get(gid, [])) indirect_user_ids = list(indirect_ids) indirect_member_views = framework_views.MakeAllUserViews( mr.cnxn, self.services.user, indirect_user_ids).values() visible_member_views = _FilterMemberData( mr, owner_views, committer_views, contributor_views, indirect_member_views) # Filter out servbice accounts visible_member_views = [m for m in visible_member_views if not framework_helpers.IsServiceAccount(m.email) and not m.user_id in acexclusion_ids] visible_member_email_list = list({ uv.email for uv in visible_member_views}) user_indexes = {email: idx for idx, email in enumerate(visible_member_email_list)} visible_members_dict = {} for uv in visible_member_views: visible_members_dict[uv.email] = uv.user_id group_ids = self.services.usergroup.DetermineWhichUserIDsAreGroups( mr.cnxn, visible_members_dict.values()) for field_dict in fields: needed_perm = field_dict['needs_perm'] if needed_perm: qualified_user_indexes = [] for uv in visible_member_views: # TODO(jrobbins): Similar code occurs in field_helpers.py. user = self.services.user.GetUser(mr.cnxn, uv.user_id) auth = monorailrequest.AuthData.FromUserID( mr.cnxn, uv.user_id, self.services) user_perms = permissions.GetPermissions( user, auth.effective_ids, mr.project) has_perm = user_perms.CanUsePerm( needed_perm, auth.effective_ids, mr.project, []) if has_perm: qualified_user_indexes.append(user_indexes[uv.email]) field_dict['user_indexes'] = sorted(set(qualified_user_indexes)) excl_prefixes = [prefix.lower() for prefix in config.exclusive_label_prefixes] members_def_list = [dict(name=email, doc='') for email in visible_member_email_list] members_def_list = sorted( members_def_list, key=lambda md: md['name']) for md in members_def_list: md_id = visible_members_dict[md['name']] if md_id in group_ids: md['is_group'] = True return { 'open': open_statuses, 'closed': closed_statuses, 'statuses_offer_merge': config.statuses_offer_merge, 'components': components, 'labels': labels, 'fields': fields, 'excl_prefixes': excl_prefixes, 'strict': ezt.boolean(config.restrict_to_known), 'members': members_def_list, 'custom_permissions': custom_permissions, }