def remove_groups(self, resolvables): """Remove this Account from the specified Groups. :param resolvables: A list of either: - A :class:`stormpath.resources.group.Group` object. - A Group href, ex: 'https://api.stormpath.com/v1/groups/3wzkqr03K8WxRp8NQuYSs3' - A Group name, ex: 'admins'. - A search query, ex: {'name': '*_admins'}. :raises: :class:`stormpath.error.StormpathError` if the Groups specified do not contain this Account. .. note:: Passing in a :class:`stormpath.resources.group.Group` object will always be the quickest way to check a Group's membership, since it doesn't require any additional API calls. """ memberships = [membership for membership in self.group_memberships] for g in [self._resolve_group(group) for group in resolvables]: done = False for membership in memberships: if membership.group.href == g.href: membership.delete() done = True if not done: raise StormpathError({ 'developerMessage': 'This user is not part of Group %s.' % g.name, })
def remove_group(self, resolvable): """Remove this Account from the specified Group. :param resolvable: This could be any one of the following: - A :class:`stormpath.resources.group.Group` object. - A Group href, ex: 'https://api.stormpath.com/v1/groups/3wzkqr03K8WxRp8NQuYSs3' - A Group name, ex: 'admins'. - A search query, ex: {'name': '*_admins'}. :raises: :class:`stormpath.error.StormpathError` if the Group specified does not contain this Account. .. note:: Passing in a :class:`stormpath.resources.group.Group` object will always be the quickest way to check a Group's membership, since it doesn't require any additional API calls. """ group = self._resolve_group(resolvable) for membership in self.group_memberships: if membership.group.href == group.href: membership.delete() return raise StormpathError({ 'developerMessage': 'This user is not part of Group %s.' % group.name, })
def remove_accounts(self, resolvables): """Remove Accounts from the specified Group. :param resolvables: A list of either: - An :class:`stormpath.resources.account.Account` object. - An Account href, ex: 'https://api.stormpath.com/v1/accounts/3wzkqr03K8WxRp8NQuYSs3' - An account username, ex: 'rdegges'. - An account email, ex: '*****@*****.**'. - A search query, ex: {'username': '******'}. :raises: :class:`stormpath.error.StormpathError` if the Accounts specified are not part of this Group. .. note:: Passing in a :class:`stormpath.resources.group.Account` object will always be the quickest way to remove an Account, since it doesn't require any additional API calls. """ memberships = [membership for membership in self.account_memberships] for a in [self._resolve_account(account) for account in resolvables]: done = False for membership in memberships: if membership.account.href == a.href: membership.delete() done = True if not done: raise StormpathError({ 'developerMessage': 'This user is not part of Group %s.' % self.name, })
def remove_account(self, resolvable): """Remove this Account from the specified Group. :param resolvable: This could be any one of the following: - An :class:`stormpath.resources.account.Account` object. - An Account href, ex: 'https://api.stormpath.com/v1/accounts/3wzkqr03K8WxRp8NQuYSs3' - An account username, ex: 'rdegges'. - An account email, ex: '*****@*****.**'. - A search query, ex: {'username': '******'}. :raises: :class:`stormpath.error.StormpathError` if the Account specified is not part of this Group. .. note:: Passing in a :class:`stormpath.resources.group.Account` object will always be the quickest way to remove an Account, since it doesn't require any additional API calls. """ account = self._resolve_account(resolvable) for membership in self.account_memberships: if membership.account.href == account.href: membership.delete() return raise StormpathError({ 'developerMessage': 'This user is not part of Group %s.' % self.name, })
def test_valid_bearer_token_but_disabled_api_key(self): app = MagicMock() app._client.auth.secret = 'fakeApiKeyProperties.secret' app.href = 'HREF' api_keys = MagicMock() api_keys.get_key = lambda k, s=None: MagicMock( id=FAKE_CLIENT_ID, secret=FAKE_CLIENT_SECRET, status=StatusMixin.STATUS_ENABLED) app.api_keys = api_keys api_keys.get_key = lambda k, s=None: MagicMock( id=FAKE_CLIENT_ID, secret=FAKE_CLIENT_SECRET, status=StatusMixin.STATUS_ENABLED) app.api_keys = api_keys ds = MagicMock() ds.get_resource.side_effect = StormpathError( {'developerMessage': 'No username on account.'}) client = MagicMock(data_store=ds) app.accounts.get.return_value = Account(client=client, href='account') basic_auth = base64.b64encode("{}:{}".format(FAKE_CLIENT_ID, FAKE_CLIENT_SECRET).encode('utf-8')) uri = 'https://example.com/get' http_method = 'GET' body = {'grant_type': 'client_credentials', 'scope': 'test1'} headers = { 'Authorization': b'Basic ' + basic_auth } allowed_scopes = ['test1'] result = authenticate(app, allowed_scopes, http_method, uri, body, headers) self.assertIsNotNone(result) self.assertIsNotNone(result.token) token = result.token body = {} headers = { 'Authorization': b'Bearer ' + token.token.encode('utf-8') } disabled_api_key = MagicMock( id=FAKE_CLIENT_ID, secret=FAKE_CLIENT_SECRET, status=StatusMixin.STATUS_DISABLED) disabled_api_key.is_enabled.return_value = False api_keys.get_key = lambda k, s=None: disabled_api_key result = authenticate(app, allowed_scopes, http_method, uri, body, headers) self.assertIsNone(result)
def my_handle_id_site_callback(self, url_response): try: from urlparse import urlparse except ImportError: from urllib.parse import urlparse import jwt try: jwt_response = urlparse(url_response).query.split('=')[1] except Exception: # because we wan't to catch everything return None api_key_secret = self._client.auth.secret # validate signature try: decoded_data = jwt.decode(jwt_response, api_key_secret, audience=self._client.auth.id, algorithms=['HS256']) except (jwt.DecodeError, jwt.ExpiredSignature): return None except jwt.MissingRequiredClaimError as missing_claim_error: if missing_claim_error.claim != 'aud': return None decoded_data = jwt.decode(jwt_response, api_key_secret, algorithms=['HS256']) if 'err' in decoded_data: raise StormpathError(decoded_data.get('err')) else: raise missing_claim_error nonce = Nonce(decoded_data['irt']) # check if nonce is in cache already # if it is throw an Exception if self._store._cache_get(nonce.href): raise ValueError('JWT has already been used.') # store nonce in cache store self._store._cache_put(href=nonce.href, data={'value': nonce.value}) # issuer = decoded_data['iss'] account_href = decoded_data['sub'] is_new_account = decoded_data['isNewSub'] state = decoded_data.get('state') status = decoded_data.get('status') if account_href: account = self.accounts.get(account_href) if self.has_account(account): # We modify the internal parameter sp_http_status which indicates if an account # is new (ie. just created). This is so we can take advantage of the account.is_new_account # property account.sp_http_status # NOTE: this forces account retrieval and building of the actual Account object account.__dict__['sp_http_status'] = 201 if is_new_account else 200 else: account = None else: account = None return IdSiteCallbackResult(account=account, state=state, status=status)