def handle_adfs_oauth(provdier, oauth_token): # Assumes allatclaims with given_name and email configured # Optional group grant as well for administrative purposes from aleph.model import Role # URL of public key of AD FS server key = requests.get(settings.OAUTH_CERT_URL).data id_token = jwt.decode( oauth_token.get("id_token"), key, audience=settings.OAUTH_KEY, options={"require": ["exp", "aud"]}, algorithms="RS256", ) user_id = "adfs:{}".format(id_token.get("sub")) group = id_token.get("group") role = Role.load_or_create( user_id, Role.USER, id_token.get("given_name"), email=id_token.get("email"), is_admin=settings.OAUTH_ADMIN_GROUP == group, ) role.clear_roles() if group: foreign_id = "adfs:%s" % group group_role = Role.load_or_create(foreign_id, Role.GROUP, group) role.add_role(group_role) log.debug("User %r is member of %r", role, group_role) return role
def handle_keycloak_oauth(sender, provider=None, oauth_token=None): from aleph.model import Role superuser_role = 'superuser' if 'secure.occrp.org' not in provider.api_base_url: return access_token = oauth_token.get('access_token') token_data = jwt.decode(access_token, verify=False) clients = token_data.get('resource_access', {}) client = clients.get(provider.client_id, {}) roles = set(client.get('roles', [])) is_admin = superuser_role in roles user_id = 'kc:%s' % token_data.get('email') if token_data.get('idashboard'): user_id = 'idashboard:user:%s' % token_data.get('idashboard') role = Role.load_or_create(user_id, Role.USER, token_data.get('name'), email=token_data.get('email'), is_admin=is_admin) role.clear_roles() for role_name in roles: group_role = Role.load_or_create('kc:%s' % role_name, Role.GROUP, role_name) role.add_role(group_role) log.debug("User %r is member of %r", role, group_role) return role
def callback(): resp = oauth_provider.authorized_response() if resp is None or isinstance(resp, OAuthException): log.warning("Failed OAuth: %r", resp) # FIXME: notify the user, somehow. return redirect(url_for('base_api.ui')) session['oauth'] = resp session['roles'] = [Role.system(Role.SYSTEM_USER)] if 'googleapis.com' in oauth_provider.base_url: me = oauth_provider.get('userinfo') user_id = 'google:%s' % me.data.get('id') role = Role.load_or_create(user_id, Role.USER, me.data.get('name'), email=me.data.get('email')) elif 'occrp.org' in oauth_provider.base_url or \ 'investigativedashboard.org' in oauth_provider.base_url: me = oauth_provider.get('api/2/accounts/profile/') user_id = 'idashboard:user:%s' % me.data.get('id') role = Role.load_or_create(user_id, Role.USER, me.data.get('display_name'), email=me.data.get('email'), is_admin=me.data.get('is_admin')) for group in me.data.get('groups', []): group_id = 'idashboard:%s' % group.get('id') group_role = Role.load_or_create(group_id, Role.GROUP, group.get('name')) session['roles'].append(group_role.id) else: raise RuntimeError("Unknown OAuth URL: %r" % oauth_provider.base_url) session['roles'].append(role.id) session['user'] = role.id db.session.commit() log.info("Logged in: %r", role) return redirect(url_for('base_api.ui'))
def handle_keycloak_oauth(provider, oauth_token): from aleph.model import Role access_token = oauth_token.get("access_token") token_data = jwt.decode(access_token, verify=False) clients = token_data.get("resource_access", {}) client = clients.get(provider.client_id, {}) roles = set(client.get("roles", [])) is_admin = settings.OAUTH_ADMIN_GROUP in roles user_id = "kc:%s" % token_data.get("email") if token_data.get("idashboard"): user_id = "idashboard:user:%s" % token_data.get("idashboard") role = Role.load_or_create( user_id, Role.USER, token_data.get("name"), email=token_data.get("email"), is_admin=is_admin, ) role.clear_roles() for role_name in roles: if role_name == settings.OAUTH_ADMIN_GROUP: continue foreign_id = "kc:%s" % role_name group_role = Role.load_or_create(foreign_id, Role.GROUP, role_name) role.add_role(group_role) log.debug("User %r is member of %r", role, group_role) return role
def handle_keycloak_oauth(sender, provider=None, oauth=None): from aleph.model import Role superuser_role = 'superuser' if 'secure.occrp.org' not in provider.base_url: return access_token = oauth.get('access_token') token_data = jwt.decode(access_token, verify=False) clients = token_data.get('resource_access', {}) client = clients.get(provider.consumer_key, {}) roles = set(client.get('roles', [])) is_admin = superuser_role in roles user_id = 'kc:%s' % token_data.get('email') if token_data.get('idashboard'): user_id = 'idashboard:user:%s' % token_data.get('idashboard') role = Role.load_or_create(user_id, Role.USER, token_data.get('name'), email=token_data.get('email'), is_admin=is_admin) role.clear_roles() for role_name in roles: group_role = Role.load_or_create('kc:%s' % role_name, Role.GROUP, role_name) role.add_role(group_role) log.debug("User %r is member of %r", role, group_role) return role
def handle_keycloak_oauth(sender, provider=None, session=None): from aleph.model import Role superuser_role = 'superuser' if 'secure.occrp.org' not in provider.base_url: return access_token = session.get('oauth', {}).get('access_token') access_token = jwt.decode(access_token, verify=False) clients = access_token.get('resource_access', {}) client = clients.get(provider.consumer_key, {}) roles = set(client.get('roles', [])) user_id = 'kc:%s' % access_token.get('email') if access_token.get('idashboard'): user_id = 'idashboard:user:%s' % access_token.get('idashboard') role = Role.load_or_create(user_id, Role.USER, access_token.get('name'), email=access_token.get('email'), is_admin=superuser_role in roles) role.clear_roles() for role_name in roles: if role_name == superuser_role: continue group_role = Role.load_or_create('kc:%s' % role_name, Role.GROUP, role_name) role.add_role(group_role) log.debug("User %r is member of %r", role, group_role) session['user'] = role.id
def handle_oauth(provider, oauth_token): from aleph.model import Role token = provider.parse_id_token(oauth_token) if token is None: return None name = token.get("name", token.get("given_name")) email = token.get("email", token.get("upn")) role_id = "%s:%s" % (settings.OAUTH_HANDLER, token.get("sub", email)) role = Role.by_foreign_id(role_id) if settings.OAUTH_MIGRATE_SUB and role is None: role = Role.by_email(email) if role is not None: role.foreign_id = role_id role.update({"name": name}) if role is None: role = Role.load_or_create(role_id, Role.USER, name, email=email) if not role.is_actor: return None role.clear_roles() for group in _get_groups(provider, oauth_token, token): if group == settings.OAUTH_ADMIN_GROUP: role.is_admin = True continue foreign_id = "group:%s" % group group_role = Role.load_or_create(foreign_id, Role.GROUP, group) role.add_role(group_role) log.debug("User %r is member of %r", role, group_role) return role
def setUp(self): super(GroupsApiTestCase, self).setUp() self.role = self.create_user(foreign_id='user_1') group = Role.load_or_create('group_1', Role.GROUP, 'group 1') self.role.add_role(group) group = Role.load_or_create('group_2', Role.GROUP, 'group 2') self.role.add_role(group) self.other = self.create_user(foreign_id='other') db.session.commit()
def system_role(role_name): from aleph.model import Role if not hasattr(app, '_authz_roles'): app._authz_roles = {} role = Role.load_or_create(Role.SYSTEM_GUEST, Role.SYSTEM, 'All visitors') app._authz_roles[Role.SYSTEM_GUEST] = role.id role = Role.load_or_create(Role.SYSTEM_USER, Role.SYSTEM, 'Logged-in users') app._authz_roles[Role.SYSTEM_USER] = role.id db.session.commit() return app._authz_roles.get(role_name)
def handle_cognito_oauth(provider, oauth_token): from aleph.model import Role # Pull keys from Cognito server keys = requests.get(settings.OAUTH_CERT_URL).json() key = lambda header, payload: jose.jwk.loads(keys, kid=header.get("kid")) # Verify id and access token id_token = jose.jwt.decode( oauth_token.get("id_token"), key, claims_options={ "exp": { "essential": True }, "aud": { "essential": True, "value": settings.OAUTH_KEY }, }, ) id_token.validate() access_token = jose.jwt.decode( oauth_token.get("access_token"), key, claims_options={"exp": { "essential": True }}, ) access_token.validate() # Cognito access_token uses client_id instead of aud if access_token.get("client_id") != settings.OAUTH_KEY: return False # Assign group and user permissions groups = set(access_token.get("cognito:groups", [])) user_id = "cognito:{}".format(id_token.get("sub")) role = Role.load_or_create( user_id, Role.USER, id_token.get("given_name"), email=id_token.get("email"), is_admin=settings.OAUTH_ADMIN_GROUP in groups, ) role.clear_roles() for role_name in groups: if role_name == settings.OAUTH_ADMIN_GROUP: continue foreign_id = "cognitogroup:%s" % role_name group_role = Role.load_or_create(foreign_id, Role.GROUP, role_name) role.add_role(group_role) log.debug("User %r is member of %r", role, group_role) return role
def create(): require(not request.authz.in_maintenance, settings.PASSWORD_LOGIN) data = parse_request(schema=RoleCreateSchema) try: email = Role.SIGNATURE.loads(data.get('code'), max_age=Role.SIGNATURE_MAX_AGE) except BadSignature: return jsonify({ 'status': 'error', 'message': 'Invalid code' }, status=400) role = Role.by_email(email).first() if role is not None: return jsonify( { 'status': 'error', 'message': 'Email is already registered' }, status=409) role = Role.load_or_create(foreign_id='password:{}'.format(email), type=Role.USER, name=data.get('name') or email, email=email) role.set_password(data.get('password')) db.session.add(role) db.session.commit() # Let the serializer return more info about this user request.authz.id = role.id return jsonify(role, schema=RoleSchema, status=201)
def handle_azure_oauth(sender, provider=None, oauth=None): from aleph.model import Role if 'login.microsoftonline.com' not in provider.base_url: return # Get incoming token, extract header for use with certificate verification id_token = oauth.get('id_token') headerbit = id_token.split('.')[0] headerbit = base64.b64decode(headerbit).decode('utf8') headerbit = json.loads(headerbit) # Load cert from MS - can be cached for upwards of 24hrs, not done now cert_loc = 'https://login.microsoftonline.com/common/discovery/keys' cert_data = json.loads(urlopen(cert_loc).read()) pemstart = "-----BEGIN CERTIFICATE-----\n" pemend = "\n-----END CERTIFICATE-----\n" # Find correct cert based on header for key in cert_data['keys']: if headerbit['kid'] == key['kid'] and headerbit['x5t'] == key['x5t']: mspubkey = key['x5c'][0] break cert_str = pemstart + mspubkey + pemend cert_obj = load_pem_x509_certificate(cert_str.encode('ascii'), default_backend()) public_key = cert_obj.public_key() # Decode incoming token and verify against the MS cert token_data = jwt.decode(id_token, public_key, verify=True, audience=settings.OAUTH_KEY) # All Ok, move on user_id = 'azure:%s' % token_data['upn'] return Role.load_or_create(user_id, Role.USER, token_data['name'], email=token_data['upn'])
def create(): require(not request.authz.in_maintenance, get_config('PASSWORD_REGISTRATION')) data = parse_request(schema=RoleCreateSchema) try: code = data.get('code') email = Role.SIGNATURE.loads(code, max_age=Role.SIGNATURE_MAX_AGE) assert email == data.get('email') except Exception: raise BadRequest("Invalid signature") role = Role.by_email(email).first() status = 200 if role is None: status = 201 role = Role.load_or_create( foreign_id='password:{}'.format(email), type=Role.USER, name=data.get('name') or email, email=email ) role.set_password(data.get('password')) db.session.add(role) db.session.commit() request.authz.id = role.id return jsonify(role, schema=RoleSchema, status=status)
def handle_azure_oauth(provider, oauth_token): from aleph.model import Role # Get incoming token, extract header for use with certificate verification id_token = oauth_token.get("id_token") headerbit = id_token.split(".")[0] headerbit = base64.b64decode(headerbit).decode("utf8") headerbit = json.loads(headerbit) # Load OAuth certificates from Microsoft. # TODO: this can be cached 24 hours. log.debug("Fetching Azure OAuth keys...") res = requests.get(AZURE_KEYS_URL, timeout=10) pk = jose.jwk.loads(res.json(), kid=headerbit["kid"]) # Decode incoming token and verify against the MS cert token_data = jwt.decode(id_token, pk, verify=True, audience=settings.OAUTH_KEY) upn = token_data["upn"] name = token_data["name"] log.debug("Decoded token: %s (%s)", upn, name) user_id = "azure:%s" % upn return Role.load_or_create(user_id, Role.USER, name, email=upn)
def create(): require(not request.authz.in_maintenance, settings.PASSWORD_LOGIN) data = parse_request(RoleCreateSchema) try: email = Role.SIGNATURE.loads(data.get('code'), max_age=Role.SIGNATURE_MAX_AGE) except BadSignature: return jsonify({ 'status': 'error', 'message': gettext('Invalid code') }, status=400) role = Role.by_email(email) if role is not None: return jsonify({ 'status': 'error', 'message': gettext('Email is already registered') }, status=409) role = Role.load_or_create( foreign_id='password:{}'.format(email), type=Role.USER, name=data.get('name') or email, email=email ) role.set_password(data.get('password')) db.session.add(role) db.session.commit() update_role(role) # Let the serializer return more info about this user request.authz.id = role.id tag_request(role_id=role.id) return RoleSerializer.jsonify(role, status=201)
def create(): data = request_data() email = data.get('email') password = data.get('password') signature = data.get('code') if not email or not password or not signature: abort(400) try: # Make sure registration is allowed assert get_config('PASSWORD_REGISTRATION') # Make sure password is set and not too short assert len(password) >= Role.PASSWORD_MIN_LENGTH # Make sure the signature is valid assert email == Role.SIGNATURE_SERIALIZER.loads( signature, salt=email, max_age=Role.SIGNATURE_MAX_AGE) except: abort(400) role = Role.load_or_create(foreign_id='password:{}'.format(email), type=Role.USER, name=email, email=email) role.set_password(password) db.session.add(role) db.session.flush() return jsonify(dict(role=role.to_dict())), 201
def handle_azure_oauth(provider, oauth_token): from aleph.model import Role # Get incoming token, extract header for use with certificate verification id_token = oauth_token.get('id_token') headerbit = id_token.split('.')[0] headerbit = base64.b64decode(headerbit).decode('utf8') headerbit = json.loads(headerbit) # Load cert from MS - can be cached for upwards of 24hrs, not done now cert_loc = 'https://login.microsoftonline.com/common/discovery/keys' cert_data = json.loads(urlopen(cert_loc).read()) pemstart = "-----BEGIN CERTIFICATE-----\n" pemend = "\n-----END CERTIFICATE-----\n" # Find correct cert based on header for key in cert_data['keys']: if headerbit['kid'] == key['kid'] and headerbit['x5t'] == key['x5t']: mspubkey = key['x5c'][0] break cert_str = pemstart + mspubkey + pemend cert_obj = load_pem_x509_certificate(cert_str.encode('ascii'), default_backend()) public_key = cert_obj.public_key() # Decode incoming token and verify against the MS cert token_data = jwt.decode(id_token, public_key, verify=True, audience=settings.OAUTH_KEY) # All Ok, move on user_id = 'azure:%s' % token_data['upn'] return Role.load_or_create(user_id, Role.USER, token_data['name'], email=token_data['upn'])
def create_user(self, foreign_id='tester', name=None, email=None, is_admin=False): role = Role.load_or_create(foreign_id, Role.USER, name or foreign_id, email=email or self.fake.email(), is_admin=is_admin) db.session.commit() return role
def handle_google_oauth(provider, oauth_token): from aleph.model import Role data = provider.get("userinfo", token=oauth_token).json() user_id = "google:%s" % data.get("id") return Role.load_or_create( user_id, Role.USER, data.get("name"), email=data.get("email") )
def create_user(self, foreign_id='tester', name=None, email=None, is_admin=False): role = Role.load_or_create(foreign_id, Role.USER, name or foreign_id, email=email or self.fake.email(), is_admin=is_admin) db.session.commit() return role
def handle_google_oauth(provider, oauth_token): from aleph.model import Role data = provider.get('userinfo', token=oauth_token).json() user_id = 'google:%s' % data.get('id') return Role.load_or_create(user_id, Role.USER, data.get('name'), email=data.get('email'))
def createuser(foreign_id, name=None, email=None, is_admin=False): """Create a user and show their API key.""" role = Role.load_or_create(foreign_id, Role.USER, name or foreign_id, email=email or "*****@*****.**", is_admin=is_admin) db.session.commit() return role.api_key
def handle_google_oauth(sender, provider=None, oauth_token=None): from aleph.model import Role if 'googleapis.com' not in provider.api_base_url: return data = provider.get('userinfo', token=oauth_token).json() user_id = 'google:%s' % data.get('id') return Role.load_or_create(user_id, Role.USER, data.get('name'), email=data.get('email'))
def test_load_or_create_role_exists(self): self.assertEqual( Role.load_or_create( foreign_id=self.role.foreign_id, type=self.role.type, name=self.role.name, email=self.role.email ), self.role )
def test_load_or_create_role_exists(self): self.assertEqual( Role.load_or_create( foreign_id=self.role.foreign_id, type=self.role.type, name=self.role.name, email=self.role.email, ), self.role, )
def handle_google_oauth(sender, provider=None, oauth=None): from aleph.model import Role if 'googleapis.com' not in provider.base_url: return token = (oauth.get('access_token'), '') me = provider.get('userinfo', token=token) user_id = 'google:%s' % me.data.get('id') return Role.load_or_create(user_id, Role.USER, me.data.get('name'), email=me.data.get('email'))
def handle_facebook_oauth(sender, provider=None, oauth=None): from aleph.model import Role if 'facebook.com' not in provider.base_url: return token = (oauth.get('access_token'), '') me = provider.get('me?fields=id,name,email', token=token) user_id = 'facebook:%s' % me.data.get('id') return Role.load_or_create(user_id, Role.USER, me.data.get('name'), email=me.data.get('email'))
def handle_google_oauth(sender, provider=None, oauth=None): from aleph.model import Role if 'googleapis.com' not in provider.base_url: return token = (oauth.get('access_token'), '') me = provider.get('userinfo', token=token) user_id = 'google:%s' % me.data.get('id') return Role.load_or_create(user_id, Role.USER, me.data.get('name'), email=me.data.get('email'))
def handle_facebook_oauth(sender, provider=None, oauth=None): from aleph.model import Role if 'facebook.com' not in provider.base_url: return token = (oauth.get('access_token'), '') me = provider.get('me?fields=id,name,email', token=token) user_id = 'facebook:%s' % me.data.get('id') return Role.load_or_create(user_id, Role.USER, me.data.get('name'), email=me.data.get('email'))
def handle_facebook_oauth(sender, provider=None, oauth_token=None): from aleph.model import Role if 'facebook.com' not in provider.api_base_url: return data = provider.get('me?fields=id,name,email', token=oauth_token).json() user_id = 'facebook:%s' % data.get('id') return Role.load_or_create(user_id, Role.USER, data.get('name'), email=data.get('email'))
def handle_facebook_oauth(sender, provider=None, session=None): from aleph.model import Role if 'facebook.com' not in provider.base_url: return me = provider.get('me?fields=id,name,email') user_id = 'facebook:%s' % me.data.get('id') role = Role.load_or_create(user_id, Role.USER, me.data.get('name'), email=me.data.get('email')) session['user'] = role.id
def createuser(foreign_id, password=None, name=None, email=None, is_admin=False): """Create a user and show their API key.""" role = Role.load_or_create(foreign_id, Role.USER, name or foreign_id, email=email or "*****@*****.**", is_admin=is_admin) if password is not None: role.set_password(password) db.session.add(role) db.session.commit() return role.api_key
def create_user(email, name, password, is_admin=False): """Create a password-based user.""" foreign_id = "password:{}".format(email) role = Role.load_or_create( foreign_id, Role.USER, name, email=email, is_admin=is_admin ) if password is not None: role.set_password(password) db.session.add(role) db.session.commit() update_role(role) return role
def handle_google_oauth(sender, provider=None, session=None): # If you wish to use another OAuth provider with your installation of # aleph, you can create a Python extension package and include a # custom oauth handler like this, which will create roles and state # for your session. if 'googleapis.com' not in provider.base_url: return me = provider.get('userinfo') user_id = 'google:%s' % me.data.get('id') role = Role.load_or_create(user_id, Role.USER, me.data.get('name'), email=me.data.get('email')) session['roles'].append(role.id) session['user'] = role.id
def callback(): resp = oauth_provider.authorized_response() if resp is None or isinstance(resp, OAuthException): log.warning("Failed OAuth: %r", resp) # FIXME: notify the user, somehow. return redirect(url_for('base_api.ui')) session['oauth'] = resp session['roles'] = [Role.system(Role.SYSTEM_USER)] if 'googleapis.com' in oauth_provider.base_url: me = oauth_provider.get('userinfo') user_id = 'google:%s' % me.data.get('id') role = Role.load_or_create(user_id, Role.USER, me.data.get('name'), email=me.data.get('email')) elif 'occrp.org' in oauth_provider.base_url or \ 'investigativedashboard.org' in oauth_provider.base_url: me = oauth_provider.get('api/2/accounts/profile/') user_id = 'idashboard:user:%s' % me.data.get('id') role = Role.load_or_create(user_id, Role.USER, me.data.get('display_name'), email=me.data.get('email'), is_admin=me.data.get('is_admin')) for group in me.data.get('groups', []): group_id = 'idashboard:%s' % group.get('id') group_role = Role.load_or_create(group_id, Role.GROUP, group.get('name')) session['roles'].append(group_role.id) else: raise RuntimeError("Unknown OAuth URL: %r" % oauth_provider.base_url) session['roles'].append(role.id) session['user'] = role.id db.session.commit() log.info("Logged in: %r", role) return redirect(url_for('base_api.ui'))
def create_system_roles(): log.info("Creating system roles...") Role.load_or_create(Role.SYSTEM_GUEST, Role.SYSTEM, 'All visitors') Role.load_or_create(Role.SYSTEM_USER, Role.SYSTEM, 'Logged-in users') db.session.commit()
def create_system_roles(): log.info("Creating system roles...") Role.load_or_create(Role.SYSTEM_GUEST, Role.SYSTEM, 'All visitors') Role.load_or_create(Role.SYSTEM_USER, Role.SYSTEM, 'Logged-in users') db.session.commit()
def create_group(self, foreign_id="group", *members): group = Role.load_or_create(foreign_id, Role.GROUP, foreign_id) for member in members: member.add_role(group) db.session.commit() return group