def ensure_not_weakly_authenticated(signed_msg, context, error_template='not-signed.txt'): """Make sure that the current principal is not weakly authenticated. NB: While handling an email, the authentication state is stored partly in properties of the message object, and partly in the current security principal. As a consequence this function will only work correctly if the message has just been passed through authenticateEmail -- you can't give it an arbitrary message object. """ cur_principal = get_current_principal() # The security machinery doesn't know about # IWeaklyAuthenticatedPrincipal yet, so do a manual # check. Later we can rely on the security machinery to # cause Unauthorized errors. if IWeaklyAuthenticatedPrincipal.providedBy(cur_principal): if signed_msg.signature is None: error_message = get_error_message( NOT_SIGNED_TEMPLATE, None, context=context) else: import_url = canonical_url( getUtility(ILaunchBag).user) + '/+editpgpkeys' error_message = get_error_message( NO_KEY_TEMPLATE, None, import_url=import_url, context=context) raise IncomingEmailError(error_message)
def getLoggedInPerson(self): """Return the currently logged-in person. If no one is logged in, return None. If there is an anonymous user logged in, then return ANONYMOUS. Otherwise, return the logged-in `IPerson`. """ # I don't really know the canonical way of asking for "the logged-in # person", so instead I'm using all the ways I can find and making # sure they match each other. -- jml by_launchbag = getUtility(IOpenLaunchBag).user principal = get_current_principal() if principal is None: return None elif IUnauthenticatedPrincipal.providedBy(principal): if by_launchbag is None: return ANONYMOUS else: raise ValueError( "Unauthenticated principal, but launchbag thinks " "%r is logged in." % (by_launchbag,)) else: by_principal = principal.person self.assertEqual(by_launchbag, by_principal) return by_principal
def getLoggedInPerson(self): """Return the currently logged-in person. If no one is logged in, return None. If there is an anonymous user logged in, then return ANONYMOUS. Otherwise, return the logged-in `IPerson`. """ # I don't really know the canonical way of asking for "the logged-in # person", so instead I'm using all the ways I can find and making # sure they match each other. -- jml by_launchbag = getUtility(IOpenLaunchBag).user principal = get_current_principal() if principal is None: return None elif IUnauthenticatedPrincipal.providedBy(principal): if by_launchbag is None: return ANONYMOUS else: raise ValueError( "Unauthenticated principal, but launchbag thinks " "%r is logged in." % (by_launchbag, )) else: by_principal = principal.person self.assertEqual(by_launchbag, by_principal) return by_principal
def _setWeakPrincipal(self): # Get the current principal to provide IWeaklyAuthenticatedPrincipal # this is set when the message is unsigned or the signature doesn't # match a key that the person has. cur_principal = get_current_principal() directlyProvides(cur_principal, directlyProvidedBy(cur_principal), IWeaklyAuthenticatedPrincipal)
def _setWeakPrincipal(self): # Get the current principal to provide IWeaklyAuthenticatedPrincipal # this is set when the message is unsigned or the signature doesn't # match a key that the person has. cur_principal = get_current_principal() directlyProvides( cur_principal, directlyProvidedBy(cur_principal), IWeaklyAuthenticatedPrincipal)
def getNominationEditView(self, nomination, form): getUtility(ILaunchBag).add(nomination.bug.default_bugtask) view = create_initialized_view( nomination, name='+editstatus', current_request=True, principal=get_current_principal(), form=form) return view
def test_traverse(url): """Traverse the url in the same way normal publishing occurs. Returns a tuple of (object, view, request) where: object is the last model object in the traversal chain view is the defined view for the object at the specified url (if the url didn't directly specify a view, then the view is the default view for the object. request is the request object resulting from the traversal. This contains a populated traversed_objects list just as a browser request would from a normal call into the app servers. This call uses the currently logged in user, and does not start a new transaction. """ url_parts = urlsplit(url) server_url = '://'.join(url_parts[0:2]) path_info = url_parts[2] request, publication = get_request_and_publication( host=url_parts[1], extra_environment={ 'SERVER_URL': server_url, 'PATH_INFO': path_info}) request.setPublication(publication) # We avoid calling publication.beforePublication because this starts a new # transaction, which causes an abort of the existing transaction, and the # removal of any created and uncommitted objects. # Set the default layer. adapters = getGlobalSiteManager().adapters layer = adapters.lookup((providedBy(request),), IDefaultSkin, '') if layer is not None: layers.setAdditionalLayer(request, layer) principal = get_current_principal() if IUnauthenticatedPrincipal.providedBy(principal): login = None else: login = principal.person setupInteraction(principal, login, request) getUtility(IOpenLaunchBag).clear() app = publication.getApplication(request) view = request.traverse(app) # Find the object from the view instead on relying that it stays # in the traversed_objects stack. That doesn't apply to the web # service for example. try: obj = removeSecurityProxy(view).context except AttributeError: # But sometime the view didn't store the context... # Use the last traversed object in these cases. obj = request.traversed_objects[-2] restoreInteraction() return obj, view, request
def expose_user_administered_teams_to_js(request, user, context, absoluteURL=absoluteURL): """Make the list of teams the user administers available to JavaScript.""" # XXX: Robert Collins workaround multiple calls making this cause # timeouts: see bug 788510. objects = IJSONRequestCache(request).objects if 'administratedTeams' in objects: return info = [] api_request = IWebServiceClientRequest(request) is_distro = IDistribution.providedBy(context) if is_distro: # If the context is a distro AND a bug supervisor is set then we only # allow subscriptions from members of the bug supervisor team. bug_supervisor = context.bug_supervisor else: bug_supervisor = None if user is not None: administrated_teams = set(user.administrated_teams) if administrated_teams: # Get this only if we need to. membership = set(user.teams_participated_in) # Only consider teams the user is both in and administers: # If the user is not a member of the team itself, then # skip it, because structural subscriptions and their # filters can only be edited by the subscriber. # This can happen if the user is an owner but not a member. administers_and_in = membership.intersection(administrated_teams) list( getUtility(IPersonSet).getPrecachedPersonsFromIDs( [team.id for team in administers_and_in], need_preferred_email=True)) # If the requester is the user, they're at least an admin in # all of these teams. Precache launchpad.(Limited)View so we # can see the necessary attributes. current_user = IPerson(get_current_principal(), None) if current_user is not None and user == current_user: for perm in ('launchpad.View', 'launchpad.LimitedView'): precache_permission_for_objects(None, perm, administers_and_in) for team in sorted(administers_and_in, key=attrgetter('name')): if (bug_supervisor is not None and not team.inTeam(bug_supervisor)): continue info.append({ 'has_preferredemail': team.preferredemail is not None, 'link': absoluteURL(team, api_request), 'title': team.unique_displayname, 'url': canonical_url(team), }) objects['administratedTeams'] = info
def expose_user_administered_teams_to_js(request, user, context, absoluteURL=absoluteURL): """Make the list of teams the user administers available to JavaScript.""" # XXX: Robert Collins workaround multiple calls making this cause # timeouts: see bug 788510. objects = IJSONRequestCache(request).objects if 'administratedTeams' in objects: return info = [] api_request = IWebServiceClientRequest(request) is_distro = IDistribution.providedBy(context) if is_distro: # If the context is a distro AND a bug supervisor is set then we only # allow subscriptions from members of the bug supervisor team. bug_supervisor = context.bug_supervisor else: bug_supervisor = None if user is not None: administrated_teams = set(user.administrated_teams) if administrated_teams: # Get this only if we need to. membership = set(user.teams_participated_in) # Only consider teams the user is both in and administers: # If the user is not a member of the team itself, then # skip it, because structural subscriptions and their # filters can only be edited by the subscriber. # This can happen if the user is an owner but not a member. administers_and_in = membership.intersection(administrated_teams) list(getUtility(IPersonSet).getPrecachedPersonsFromIDs( [team.id for team in administers_and_in], need_preferred_email=True)) # If the requester is the user, they're at least an admin in # all of these teams. Precache launchpad.(Limited)View so we # can see the necessary attributes. current_user = IPerson(get_current_principal(), None) if current_user is not None and user == current_user: for perm in ('launchpad.View', 'launchpad.LimitedView'): precache_permission_for_objects( None, perm, administers_and_in) for team in administers_and_in: if (bug_supervisor is not None and not team.inTeam(bug_supervisor)): continue info.append({ 'has_preferredemail': team.preferredemail is not None, 'link': absoluteURL(team, api_request), 'title': team.title, 'url': canonical_url(team), }) objects['administratedTeams'] = info
def _zope_response(self): """Get the response.""" current_principal = None # End and save the current interaction, since HTTPCaller creates # its own interaction. if queryInteraction(): current_principal = get_current_principal() endInteraction() if self._response is None: self._response = self.caller(self._data_to_send) # Restore the interaction to what it was before. setupInteraction(current_principal) return self._response
def _render(self, form_values=None, method='GET'): self.request = self.request_class( method=method, form=form_values, PATH_INFO='/', environ=self.request_environ) if queryInteraction() is not None: self.request.setPrincipal(get_current_principal()) # Setup a new interaction using self.request, create the view, # initialize() it and then restore the original interaction. endInteraction() newInteraction(self.request) self.view = self.view_class(self.context, self.request) self.view.initialize() restoreInteraction()
def _render(self, form_values=None, method='GET'): self.request = self.request_class(method=method, form=form_values, PATH_INFO='/', environ=self.request_environ) if queryInteraction() is not None: self.request.setPrincipal(get_current_principal()) # Setup a new interaction using self.request, create the view, # initialize() it and then restore the original interaction. endInteraction() newInteraction(self.request) self.view = self.view_class(self.context, self.request) self.view.initialize() restoreInteraction()
def report_oops(file_alias_url=None, error_msg=None): """Record an OOPS for the current exception and return the OOPS ID.""" info = sys.exc_info() properties = [] if file_alias_url is not None: properties.append(('Sent message', file_alias_url)) if error_msg is not None: properties.append(('Error message', error_msg)) request = ScriptRequest(properties) request.principal = get_current_principal() errorUtility = ErrorReportingUtility() # Report all exceptions: the mail handling code doesn't expect any in # normal operation. errorUtility._ignored_exceptions = set() report = errorUtility.raising(info, request) # Note that this assert is arguably bogus: raising is permitted to filter # reports. assert report is not None, ('No OOPS generated.') return report['id']
def assertLoggedOut(self): """Assert that no one is currently logged in.""" self.assertIs(None, get_current_principal()) self.assertIs(None, getUtility(IOpenLaunchBag).user)
def account(self): return IAccount(get_current_principal(), None)
def test_traverse(url): """Traverse the url in the same way normal publishing occurs. Returns a tuple of (object, view, request) where: object is the last model object in the traversal chain view is the defined view for the object at the specified url (if the url didn't directly specify a view, then the view is the default view for the object. request is the request object resulting from the traversal. This contains a populated traversed_objects list just as a browser request would from a normal call into the app servers. This call uses the currently logged in user, and does not start a new transaction. """ url_parts = urlsplit(url) server_url = '://'.join(url_parts[0:2]) path_info = url_parts[2] request, publication = get_request_and_publication(host=url_parts[1], extra_environment={ 'SERVER_URL': server_url, 'PATH_INFO': path_info }) request.setPublication(publication) # We avoid calling publication.beforePublication because this starts a new # transaction, which causes an abort of the existing transaction, and the # removal of any created and uncommitted objects. # Set the default layer. adapters = getGlobalSiteManager().adapters layer = adapters.lookup((providedBy(request), ), IDefaultSkin, '') if layer is not None: layers.setAdditionalLayer(request, layer) principal = get_current_principal() if IUnauthenticatedPrincipal.providedBy(principal): login = None else: login = principal.person setupInteraction(principal, login, request) getUtility(IOpenLaunchBag).clear() app = publication.getApplication(request) view = request.traverse(app) # Find the object from the view instead on relying that it stays # in the traversed_objects stack. That doesn't apply to the web # service for example. try: obj = removeSecurityProxy(view).context except AttributeError: # But sometime the view didn't store the context... # Use the last traversed object in these cases. obj = request.traversed_objects[-2] restoreInteraction() return obj, view, request
def user(self): return IPerson(get_current_principal(), None)