def permits(self, context, principals, permission): # The Pyramid API doesn't let us access the request here, so we have to pull it # out of the thread local instead. # TODO: Work with Pyramid devs to figure out if there is a better way to support # the worklow we are using here or not. request = get_current_request() # Our request could possibly be a None, if there isn't an active request, in # that case we're going to always deny, because without a request, we can't # determine if this request is authorized or not. if request is None: return Denied("There was no active request.") # Re-extract our Macaroon from the request, it sucks to have to do this work # twice, but I believe it is inevitable unless we pass the Macaroon back as # a principal-- which doesn't seem to be the right fit for it. macaroon = _extract_http_macaroon(request) # This logic will only happen on requests that are being authenticated with # Macaroons. Any other request will just fall back to the standard Authorization # policy. if macaroon is not None: macaroon_service = request.find_service(IMacaroonService, context=None) try: macaroon_service.verify(macaroon, context, principals, permission) except InvalidMacaroon as exc: return Denied(f"The supplied token was invalid: {str(exc)!r}") # If our Macaroon is verified, then we'll pass this request to our underlying # Authorization policy, so it can handle its own authorization logic on # the prinicpal. return self.policy.permits(context, principals, permission)
def test_denies_valid_macaroon_for_incorrect_permission( self, monkeypatch, invalid_permission): macaroon_service = pretend.stub( verify=pretend.call_recorder(lambda *a: pretend.stub())) request = pretend.stub(find_service=pretend.call_recorder( lambda interface, **kw: macaroon_service)) get_current_request = pretend.call_recorder(lambda: request) monkeypatch.setattr(auth_policy, "get_current_request", get_current_request) _extract_http_macaroon = pretend.call_recorder( lambda r: b"not a real macaroon") monkeypatch.setattr(auth_policy, "_extract_http_macaroon", _extract_http_macaroon) permits = pretend.stub() backing_policy = pretend.stub( permits=pretend.call_recorder(lambda *a, **kw: permits)) policy = auth_policy.MacaroonAuthorizationPolicy(policy=backing_policy) result = policy.permits(pretend.stub(), pretend.stub(), invalid_permission) assert result == Denied("") assert result.s == ( f"API tokens are not valid for permission: {invalid_permission}!")
def permits(context: ILocation, principals: List[str], permission: str) \ -> PermitsResult: if permission in principals: return Allowed("ALLOWED: permission {} present in principals " "{}".format(permission, principals)) return Denied("DENIED: permission {} not in principals " "{}".format(permission, principals))
def test_permits_no_active_request(self, monkeypatch): get_current_request = pretend.call_recorder(lambda: None) monkeypatch.setattr(auth_policy, "get_current_request", get_current_request) backing_policy = pretend.stub( permits=pretend.call_recorder(lambda *a, **kw: pretend.stub()) ) policy = auth_policy.MacaroonAuthorizationPolicy(policy=backing_policy) result = policy.permits(pretend.stub(), pretend.stub(), pretend.stub()) assert result == Denied("There was no active request.")
def permits(self, context, principals, permission): log.info('AuthorizationPolicy::permits()') if principals is not None: for p in principals: if (p != Everyone): try: result = self._provider.user_has_permission(p, permission) # result = self._provider.query( # 'user.has_permission', # (p, permission) # ) (allowed, ) = result['result'][0] if (allowed): return Allowed('Allowed') else: log.debug('User %s is missing permission %s' % (p, permission)) return Denied('Denied') except Exception as e: log.error(e) return Denied('Denied')
def test_permits_nonuser_denied(self): subpolicies = pretend.stub() authz = pretend.stub( permits=pretend.call_recorder(lambda *a: pretend.stub())) policy = security_policy.MultiSecurityPolicy(subpolicies, authz) # Anything that doesn't pass an isinstance check for User fakeuser = pretend.stub() request = pretend.stub(identity=fakeuser) context = pretend.stub() permission = pretend.stub() assert policy.permits(request, context, permission) == Denied("unimplemented") assert authz.permits.calls == []
def test_permits_if_context_is_not_permitted_by_backing_policy( self, monkeypatch): request = pretend.stub() get_current_request = pretend.call_recorder(lambda: request) monkeypatch.setattr(security_policy, "get_current_request", get_current_request) permits_result = Denied("Because") backing_policy = pretend.stub( permits=pretend.call_recorder(lambda *a, **kw: permits_result)) policy = security_policy.TwoFactorAuthorizationPolicy( policy=backing_policy) result = policy.permits(pretend.stub(), pretend.stub(), pretend.stub()) assert result == permits_result
def permits(self, request, context, permission): """Return an instance of :class:`pyramid.security.Allowed` if a user of the given identity is allowed the ``permission`` in the current ``context``, else return an instance of :class:`pyramid.security.Denied`. """ if isinstance(context, str): # We assume that context is the name of a package if request.access.has_permission(context, permission): return Allowed("Allowed by ACL") return Denied("Permission not granted") else: userid = self.authenticated_userid(request) principals = request.access.user_principals(userid) return self.acl_policy.permits(context, principals, permission)
def test_resuls_cantrun(self, has_permission): from pyramid.security import Denied has_permission.return_value = Denied('Faked denied') request = testing.DummyRequest() job = self.fake_job() views = InCompleteJobViews(job, request) response = views.results() exp_response = dict( jobid='foo', run='bla', maxmslevel=3, canRun=False, job=job, ) self.assertDictEqual(response, exp_response) has_permission.assert_called_with('run', job, request)
def permits(self, request, context, permission): identity = request.identity principals = [] if identity is not None: principals.append(Authenticated) if isinstance(identity, User): principals.append(f"user:{identity.id}") principals.extend(_principals_for_authenticated_user(identity)) else: return Denied("unimplemented") # NOTE: Observe that the parameters passed into the underlying AuthZ # policy here are not the same (or in the same order) as the ones # passed into `permits` above. This is because the underlying AuthZ # policy is a "legacy" Pyramid 1.0 style one that implements the # `IAuthorizationPolicy` interface rather than `ISecurityPolicy`. return self._authz.permits(context, principals, permission)
def test_permits_invalid_macaroon(self, monkeypatch): macaroon_service = pretend.stub(verify=pretend.raiser(InvalidMacaroon("foo"))) request = pretend.stub( find_service=pretend.call_recorder(lambda interface, **kw: macaroon_service) ) get_current_request = pretend.call_recorder(lambda: request) monkeypatch.setattr(auth_policy, "get_current_request", get_current_request) _extract_http_macaroon = pretend.call_recorder(lambda r: b"not a real macaroon") monkeypatch.setattr( auth_policy, "_extract_http_macaroon", _extract_http_macaroon ) permits = pretend.stub() backing_policy = pretend.stub( permits=pretend.call_recorder(lambda *a, **kw: permits) ) policy = auth_policy.MacaroonAuthorizationPolicy(policy=backing_policy) result = policy.permits(pretend.stub(), pretend.stub(), pretend.stub()) assert result == Denied("The supplied token was invalid: foo")
def permits(self, request, context, permission): userid = self.authenticated_userid(request) if userid and permission == 'foo': return Allowed('') else: return Denied('')
def permits(self, context, principals, permission): if 'bob' in principals and permission == 'foo': return Allowed('') else: return Denied('')
def permits(self, request, context, identity, permission): if identity and permission == 'foo': return Allowed('') else: return Denied('')