def test_ssh_success(self): """AUTHENTICATION (REST): SSH RSA public key exchange (correct credentials).""" try: add_account_identity(PUBLIC_KEY, IdentityType.SSH, 'root', email='*****@*****.**') except Duplicate: pass # might already exist, can skip options = [] headers = {'X-Rucio-Account': 'root'} result = TestApp(APP.wsgifunc(*options)).get('/ssh_challenge_token', headers=headers, expect_errors=True) assert_equal(result.status, 200) assert_in('challenge-', result.header('X-Rucio-SSH-Challenge-Token')) signature = ssh_sign(PRIVATE_KEY, result.header('X-Rucio-SSH-Challenge-Token')) headers = { 'X-Rucio-Account': 'root', 'X-Rucio-SSH-Signature': signature } result = TestApp(APP.wsgifunc(*options)).get('/ssh', headers=headers, expect_errors=True) assert_equal(result.status, 200) assert_greater(len(result.header('X-Rucio-Auth-Token')), 32) del_account_identity(PUBLIC_KEY, IdentityType.SSH, 'root')
def test_get_auth_token_ssh_success(self): """AUTHENTICATION (CORE): SSH RSA public key exchange (good signature).""" try: add_account_identity(PUBLIC_KEY, IdentityType.SSH, 'root', email='*****@*****.**') except Duplicate: pass # might already exist, can skip challenge_token = get_ssh_challenge_token(account='root', appid='test', ip='127.0.0.1').token signature = base64.b64decode(ssh_sign(PRIVATE_KEY, challenge_token)) result = get_auth_token_ssh(account='root', signature=signature, appid='test', ip='127.0.0.1') assert_is_not_none(result) del_account_identity(PUBLIC_KEY, IdentityType.SSH, 'root')
def test_ssh_fail(self): """AUTHENTICATION (REST): SSH RSA public key exchange (wrong credentials).""" root = InternalAccount('root', **self.vo) try: add_account_identity(PUBLIC_KEY, IdentityType.SSH, root, email='*****@*****.**') except Duplicate: pass # might already exist, can skip signature = ssh_sign(PRIVATE_KEY, 'sign_something_else') options = [] headers = { 'X-Rucio-Account': 'root', 'X-Rucio-SSH-Signature': signature } headers.update(self.vo_header) result = TestApp(APP.wsgifunc(*options)).get('/ssh', headers=headers, expect_errors=True) assert result.status == 401 del_account_identity(PUBLIC_KEY, IdentityType.SSH, root)
def import_identities(identities, account_name, old_identities, old_identity_account, account_email, session=None): for identity in identities: identity['type'] = IdentityType[identity['type'].upper()] missing_identities = [identity for identity in identities if (identity['identity'], identity['type']) not in old_identities] missing_identity_account = [identity for identity in identities if (identity['identity'], identity['type'], account_name) not in old_identity_account] to_be_removed_identity_account = [old_identity for old_identity in old_identity_account if (old_identity[0], old_identity[1], old_identity[2]) not in [(identity['identity'], identity['type'], account_name) for identity in identities] and old_identity[2] == account_name] # add missing identities for identity in missing_identities: identity_type = identity['type'] password = identity.get('password') identity = identity['identity'] if identity_type == IdentityType.USERPASS: identity_module.add_identity(identity=identity, password=password, email=account_email, type_=identity_type, session=session) elif identity_type == IdentityType.GSS or identity_type == IdentityType.SSH or identity_type == IdentityType.X509: identity_module.add_identity(identity=identity, email=account_email, type_=identity_type, session=session) # add missing identity-account association for identity in missing_identity_account: identity_module.add_account_identity(identity['identity'], identity['type'], account_name, email=account_email, session=session) # remove identities from account-identity association for identity in to_be_removed_identity_account: identity_module.del_account_identity(identity=identity[0], type_=identity[1], account=identity[2], session=session)
def test_invalid_padding(self): """AUTHENTICATION (CORE): SSH RSA public key exchange (public key with invalid padding).""" root = InternalAccount('root', **self.vo) try: add_account_identity(INVALID_PADDED_PUBLIC_KEY, IdentityType.SSH, root, email='*****@*****.**') except Duplicate: pass # might already exist, can skip challenge_token = get_ssh_challenge_token(account='root', appid='test', ip='127.0.0.1', **self.vo).get('token') ssh_sign_string = ssh_sign(PRIVATE_KEY, challenge_token) signature = base64.b64decode(ssh_sign_string) result = get_auth_token_ssh(account='root', signature=signature, appid='test', ip='127.0.0.1', **self.vo) assert result is not None del_account_identity(INVALID_PADDED_PUBLIC_KEY, IdentityType.SSH, root)
def test_ssh_success(vo, rest_client): """AUTHENTICATION (REST): SSH RSA public key exchange (correct credentials).""" root = InternalAccount('root', vo=vo) try: add_account_identity(PUBLIC_KEY, IdentityType.SSH, root, email='*****@*****.**') except Duplicate: pass # might already exist, can skip headers_dict = {'X-Rucio-Account': 'root'} response = rest_client.get('/auth/ssh_challenge_token', headers=headers(hdrdict(headers_dict), vohdr(vo))) assert response.status_code == 200 assert 'challenge-' in response.headers.get('X-Rucio-SSH-Challenge-Token') signature = ssh_sign(PRIVATE_KEY, response.headers.get('X-Rucio-SSH-Challenge-Token')) headers_dict = { 'X-Rucio-Account': 'root', 'X-Rucio-SSH-Signature': signature } response = rest_client.get('/auth/ssh', headers=headers(hdrdict(headers_dict), vohdr(vo))) assert response.status_code == 200 assert len(response.headers.get('X-Rucio-Auth-Token')) > 32 del_account_identity(PUBLIC_KEY, IdentityType.SSH, root)
def test_ssh(self): """ IDENTITY (CORE): Test adding and removing SSH public key authentication """ add_identity(self.account.external, IdentityType.SSH, email='*****@*****.**') add_account_identity('my_public_key', IdentityType.SSH, self.account, email='*****@*****.**') list_identities() del_account_identity('my_public_key', IdentityType.SSH, self.account) del_identity(self.account.external, IdentityType.SSH)
def test_get_auth_token_saml_fail(self): """AUTHENTICATION (CORE): SAML NameID (wrong credentials).""" root = InternalAccount('root', **self.vo) try: add_account_identity('ddmlab', IdentityType.SAML, root, email='*****@*****.**') except Duplicate: pass # might already exist, can skip with assert_raises(AccessDenied): get_auth_token_saml(account='root', saml_nameid='not_ddmlab', appid='test', ip='127.0.0.1', **self.vo) del_account_identity('ddmlab', IdentityType.SAML, root)
def test_get_auth_token_saml_success(self): """AUTHENTICATION (CORE): SAML NameID (correct credentials).""" root = InternalAccount('root', **self.vo) try: add_account_identity('ddmlab', IdentityType.SAML, root, email='*****@*****.**') except Duplicate: pass # might already exist, can skip try: result = get_auth_token_saml(account='root', saml_nameid='ddmlab', appid='test', ip='127.0.0.1', **self.vo) assert_is_not_none(result) except: # FIXME: The WebUI isn't linked to CERN SSO yet so this needs to be fixed once it is linked pass del_account_identity('ddmlab', IdentityType.SAML, root)
def test_get_auth_token_ssh_fail(self): """AUTHENTICATION (CORE): SSH RSA public key exchange (wrong signature).""" root = InternalAccount('root', **self.vo) try: add_account_identity(PUBLIC_KEY, IdentityType.SSH, root, email='*****@*****.**') except Duplicate: pass # might already exist, can skip signature = ssh_sign(PRIVATE_KEY, 'sign_something_else') result = get_auth_token_ssh(account='root', signature=signature, appid='test', ip='127.0.0.1', **self.vo) assert_is_none(result) del_account_identity(PUBLIC_KEY, IdentityType.SSH, root)
def del_account_identity(identity_key, id_type, account, issuer, vo='def', session=None): """ Removes a membership association between identity and account. :param identity_key: The identity key name. For example x509 DN, or a username. :param id_type: The type of the authentication (x509, gss, userpass, ssh, saml). :param account: The account name. :param issuer: The issuer account. :param vo: the VO to act on. :param session: The database session in use. """ kwargs = {'account': account} if not permission.has_permission(issuer=issuer, vo=vo, action='del_account_identity', kwargs=kwargs, session=session): raise exception.AccessDenied( 'Account %s can not delete account identity' % (issuer)) account = InternalAccount(account, vo=vo) return identity.del_account_identity(identity_key, IdentityType[id_type.upper()], account, session=session)
def del_account_identity(identity_key, type, account): """ Removes a membership association between identity and account. :param identity_key: The identity key name. For example x509 DN, or a username. :param type: The type of the authentication (x509, gss, userpass). :param account: The account name. """ return identity.del_account_identity(identity_key, IdentityType.from_sym(type), account)
def test_get_auth_token_saml_success(self): """AUTHENTICATION (CORE): SAML NameID (correct credentials).""" root = InternalAccount('root', **self.vo) try: add_account_identity('ddmlab', IdentityType.SAML, root, email='*****@*****.**') except Duplicate: pass # might already exist, can skip result = get_auth_token_saml(account='root', saml_nameid='ddmlab', appid='test', ip='127.0.0.1', **self.vo) assert result is not None del_account_identity('ddmlab', IdentityType.SAML, root)
def del_account_identity(identity_key, id_type, account): """ Removes a membership association between identity and account. :param identity_key: The identity key name. For example x509 DN, or a username. :param id_type: The type of the authentication (x509, gss, userpass). :param account: The account name. """ return identity.del_account_identity(identity_key, IdentityType.from_sym(id_type), account)
def test_ssh_fail(vo, rest_client): """AUTHENTICATION (REST): SSH RSA public key exchange (wrong credentials).""" root = InternalAccount('root', vo=vo) try: add_account_identity(PUBLIC_KEY, IdentityType.SSH, root, email='*****@*****.**') except Duplicate: pass # might already exist, can skip signature = ssh_sign(PRIVATE_KEY, 'sign_something_else') headers_dict = { 'X-Rucio-Account': 'root', 'X-Rucio-SSH-Signature': signature } response = rest_client.get('/auth/ssh', headers=headers(hdrdict(headers_dict), vohdr(vo))) assert response.status_code == 401 del_account_identity(PUBLIC_KEY, IdentityType.SSH, root)
def test_ssh_success(self): """AUTHENTICATION (REST): SSH RSA public key exchange (correct credentials).""" root = InternalAccount('root', **self.vo) try: add_account_identity(PUBLIC_KEY, IdentityType.SSH, root, email='*****@*****.**') except Duplicate: pass # might already exist, can skip options = [] headers = {'X-Rucio-Account': 'root'} headers.update(self.vo_header) result = TestApp(APP.wsgifunc(*options)).get('/ssh_challenge_token', headers=headers, expect_errors=True) assert result.status == 200 assert 'challenge-' in result.header('X-Rucio-SSH-Challenge-Token') signature = ssh_sign(PRIVATE_KEY, result.header('X-Rucio-SSH-Challenge-Token')) headers = { 'X-Rucio-Account': 'root', 'X-Rucio-SSH-Signature': signature } headers.update(self.vo_header) result = TestApp(APP.wsgifunc(*options)).get('/ssh', headers=headers, expect_errors=True) assert result.status == 200 assert len(result.header('X-Rucio-Auth-Token')) > 32 del_account_identity(PUBLIC_KEY, IdentityType.SSH, root)
def del_account_identity(identity_key, id_type, account, issuer): """ Removes a membership association between identity and account. :param identity_key: The identity key name. For example x509 DN, or a username. :param id_type: The type of the authentication (x509, gss, userpass, ssh, saml). :param account: The account name. :param issuer: The issuer account. """ kwargs = {'account': account} if not permission.has_permission(issuer=issuer, action='del_account_identity', kwargs=kwargs): raise exception.AccessDenied('Account %s can not delete account identity' % (issuer)) account = InternalAccount(account) return identity.del_account_identity(identity_key, IdentityType.from_sym(id_type), account)
def test_userpass(self): """ IDENTITY (CORE): Test adding and removing username/password authentication """ add_identity(self.account.external, IdentityType.USERPASS, email='*****@*****.**', password='******') add_account_identity('ddmlab_%s' % self.account, IdentityType.USERPASS, self.account, email='*****@*****.**', password='******') add_identity('/ch/cern/rucio/ddmlab_%s' % self.account, IdentityType.X509, email='*****@*****.**') add_account_identity('/ch/cern/rucio/ddmlab_%s' % self.account, IdentityType.X509, self.account, email='*****@*****.**') add_identity('ddmlab_%s' % self.account, IdentityType.GSS, email='*****@*****.**') add_account_identity('ddmlab_%s' % self.account, IdentityType.GSS, self.account, email='*****@*****.**') list_identities() del_account_identity('ddmlab_%s' % self.account, IdentityType.USERPASS, self.account) del_account_identity('/ch/cern/rucio/ddmlab_%s' % self.account, IdentityType.X509, self.account) del_account_identity('ddmlab_%s' % self.account, IdentityType.GSS, self.account) del_identity('ddmlab_%s' % self.account, IdentityType.USERPASS)
def test_userpass(self): """ IDENTITY (CORE): Test adding and removing username/password authentication """ add_identity(self.account, IdentityType.USERPASS, email="*****@*****.**", password="******") add_account_identity( "ddmlab_%s" % self.account, IdentityType.USERPASS, self.account, email="*****@*****.**" ) add_identity("/ch/cern/rucio/ddmlab_%s" % self.account, IdentityType.X509, email="*****@*****.**") add_account_identity( "/ch/cern/rucio/ddmlab_%s" % self.account, IdentityType.X509, self.account, email="*****@*****.**" ) add_identity("ddmlab_%s" % self.account, IdentityType.GSS, email="*****@*****.**") add_account_identity("ddmlab_%s" % self.account, IdentityType.GSS, self.account, email="*****@*****.**") list_identities() del_account_identity("ddmlab_%s" % self.account, IdentityType.USERPASS, self.account) del_account_identity("/ch/cern/rucio/ddmlab_%s" % self.account, IdentityType.X509, self.account) del_account_identity("ddmlab_%s" % self.account, IdentityType.GSS, self.account) del_identity("ddmlab_%s" % self.account, IdentityType.USERPASS)