def test_publish_event(self): role = self.create_user() email = '*****@*****.**' label = 'So public' recipient = self.create_user(foreign_id='rolex', email=email) update_role(recipient) collection = self.create_collection(foreign_id='NoNoNo', label=label) event = Events.PUBLISH_COLLECTION publish(event, role.id, params={'collection': collection}, channels=[GLOBAL]) db.session.commit() result = get_notifications(recipient) notifications = result.get('hits', {}) assert 1 == notifications['total']['value'], notifications not0 = notifications['hits'][0]['_source'] assert not0['event'] == event.name, not0['event'] assert not0['params']['collection'] == str( collection.id), not0['params'] # noqa with mail.record_messages() as outbox: assert len(outbox) == 0, outbox generate_digest() assert len(outbox) == 1, outbox msg = outbox[0] assert email in msg.recipients, msg.recipients assert label in msg.html, msg.html
def test_publish_event(self): role = self.create_user() email = '*****@*****.**' label = 'So public' recipient = self.create_user(foreign_id='rolex', email=email) update_role(recipient) collection = self.create_collection(foreign_id='NoNoNo', label=label) event = Events.PUBLISH_COLLECTION publish(event, role.id, params={'collection': collection}, channels=[Notification.GLOBAL]) db.session.commit() notifications = Notification.all().all() assert 1 == len(notifications), notifications not0 = notifications[0] assert not0._event == event.name, not0._event assert not0.params['collection'] == str(collection.id), not0.params with mail.record_messages() as outbox: assert len(outbox) == 0, outbox generate_digest() assert len(outbox) == 1, outbox msg = outbox[0] assert email in msg.recipients, msg.recipients assert label in msg.html, msg.html
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 oauth_callback(): if not settings.OAUTH: abort(404) resp = oauth.provider.authorized_response() if resp is None or isinstance(resp, OAuthException): log.warning("Failed OAuth: %r", resp) return Unauthorized("Authentication has failed.") response = signals.handle_oauth_session.send(provider=oauth.provider, oauth=resp) for (_, role) in response: if role is None: continue db.session.commit() update_role(role) log.info("Logged in: %r", role) request.authz = Authz.from_role(role) record_audit(Audit.ACT_LOGIN) token = request.authz.to_token(role=role) token = token.decode('utf-8') state = request.args.get('state') next_url = get_best_next_url(state, request.referrer) next_url, _ = urldefrag(next_url) next_url = '%s#token=%s' % (next_url, token) return redirect(next_url) log.error("No OAuth handler for %r was installed.", oauth.provider.name) return Unauthorized("Authentication has failed.")
def oauth_callback(): require(settings.OAUTH) err = Unauthorized(gettext("Authentication has failed.")) state = cache.get_complex(_oauth_session(request.args.get("state"))) if state is None: raise err try: oauth.provider.framework.set_session_data(request, "state", state.get("state")) uri = state.get("redirect_uri") token = oauth.provider.authorize_access_token(redirect_uri=uri) except AuthlibBaseError as err: log.warning("Failed OAuth: %r", err) raise err if token is None or isinstance(token, AuthlibBaseError): log.warning("Failed OAuth: %r", token) raise err role = handle_oauth(oauth.provider, token) if role is None: raise err db.session.commit() update_role(role) log.debug("Logged in: %r", role) request.authz = Authz.from_role(role) next_path = get_url_path(state.get("next_url")) next_url = ui_url("oauth", next=next_path) next_url = "%s#token=%s" % (next_url, request.authz.to_token()) session.clear() return redirect(next_url)
def oauth_callback(): require(settings.OAUTH) try: token = oauth.provider.authorize_access_token() except AuthlibBaseError as err: log.warning("Failed OAuth: %r", err) raise Unauthorized(gettext("Authentication has failed.")) if token is None or isinstance(token, AuthlibBaseError): log.warning("Failed OAuth: %r", token) raise Unauthorized(gettext("Authentication has failed.")) role = handle_oauth(oauth.provider, token) if role is None: log.error("No OAuth handler was installed.") raise Unauthorized(gettext("Authentication has failed.")) if role.is_blocked: raise Unauthorized(gettext("Your account is blocked.")) db.session.commit() update_role(role) log.info("Logged in: %r", role) request.authz = Authz.from_role(role) token = request.authz.to_token(role=role) token = token.decode('utf-8') next_path = get_url_path(request.args.get('state')) next_url = ui_url(settings.OAUTH_UI_CALLBACK, next=next_path) next_url = '%s#token=%s' % (next_url, token) return redirect(next_url)
def test_publish_event(self): role = self.create_user() email = "*****@*****.**" label = "So public" recipient = self.create_user(foreign_id="rolex", email=email) update_role(recipient) collection = self.create_collection(foreign_id="NoNoNo", label=label) event = Events.PUBLISH_COLLECTION publish(event, role.id, params={"collection": collection}, channels=[GLOBAL]) db.session.commit() result = get_notifications(recipient) notifications = result.get("hits", {}) assert 1 == notifications["total"]["value"], notifications not0 = notifications["hits"][0]["_source"] assert not0["event"] == event.name, not0["event"] params = not0["params"] assert params["collection"] == str(collection.id), params with mail.record_messages() as outbox: assert len(outbox) == 0, outbox generate_digest() assert len(outbox) == 1, outbox msg = outbox[0] assert email in msg.recipients, msg.recipients assert label in msg.html, msg.html
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) update_role(role) db.session.commit() # Let the serializer return more info about this user request.authz.id = role.id return jsonify(role, RoleSchema, status=201)
def oauth_callback(): require(settings.OAUTH) resp = oauth.provider.authorized_response() if resp is None or isinstance(resp, OAuthException): log.warning("Failed OAuth: %r", resp) raise Unauthorized(gettext("Authentication has failed.")) response = signals.handle_oauth_session.send(provider=oauth.provider, oauth=resp) for (_, role) in response: if role is None: continue db.session.commit() update_role(role) log.info("Logged in: %r", role) request.authz = Authz.from_role(role) token = request.authz.to_token(role=role) token = token.decode('utf-8') next_path = get_url_path(request.args.get('state')) next_url = ui_url(settings.OAUTH_UI_CALLBACK, next=next_path) next_url = '%s#token=%s' % (next_url, token) return redirect(next_url) log.error("No OAuth handler for %r was installed.", oauth.provider.name) raise Unauthorized(gettext("Authentication has failed."))
def test_publish_event(self): role = self.create_user() email = '*****@*****.**' label = 'So public' recipient = self.create_user(foreign_id='rolex', email=email) update_role(recipient) collection = self.create_collection(foreign_id='NoNoNo', label=label) event = Events.PUBLISH_COLLECTION publish(event, role.id, params={'collection': collection}, channels=[Notification.GLOBAL]) db.session.commit() notifications = Notification.all().all() assert 1 == len(notifications), notifications not0 = notifications[0] assert not0._event == event.name, not0._event assert not0.params['collection'] == collection.id, not0.params with mail.record_messages() as outbox: assert len(outbox) == 0, outbox generate_digest() assert len(outbox) == 1, outbox msg = outbox[0] assert email in msg.recipients, msg.recipients assert label in msg.html, msg.html
def update(id): role = obj_or_404(Role.by_id(id)) require(request.authz.can_write_role(role.id)) data = parse_request(RoleSchema) role.update(data) db.session.add(role) db.session.commit() update_role(role) return RoleSerializer.jsonify(role)
def update(id): role = obj_or_404(Role.by_id(id)) require(request.authz.session_write) require(check_editable(role, request.authz)) data = parse_request(RoleSchema) role.update(data) db.session.add(role) db.session.commit() update_role(role) return RoleSerializer.jsonify(role)
def update(id): role = obj_or_404(Role.by_id(id)) require(request.authz.session_write) require(check_editable(role, request.authz)) data = parse_request(RoleSchema) role.update(data) db.session.add(role) update_role(role) db.session.commit() return view(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() update_role(role) return role.api_key
def password_login(): """Provides email and password authentication.""" data = parse_request(LoginSchema) role = Role.by_email(data.get('email')) if role is None or not role.has_password: return Unauthorized("Authentication has failed.") if not role.check_password(data.get('password')): return Unauthorized("Authentication has failed.") update_role(role) db.session.commit() authz = Authz.from_role(role) return jsonify({'status': 'ok', 'token': authz.to_token(role=role)})
def password_login(): """Provides email and password authentication.""" require(settings.PASSWORD_LOGIN) data = parse_request(LoginSchema) role = Role.by_email(data.get('email')) if role is None or not role.has_password: raise BadRequest(gettext("Invalid user or password.")) if not role.check_password(data.get('password')): raise BadRequest(gettext("Invalid user or password.")) db.session.commit() update_role(role) authz = Authz.from_role(role) request.authz = authz return jsonify({'status': 'ok', 'token': authz.to_token(role=role)})
def update(id): """Change user settings. --- post: summary: Change user settings description: > Update a role to change its display name, or to define a new login password. Users can only update roles they have write access to, i.e. their own. parameters: - in: path name: id required: true description: role ID schema: type: integer requestBody: content: application/json: schema: $ref: '#/components/schemas/RoleUpdate' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/Role' tags: - Role """ role = obj_or_404(Role.by_id(id)) require(request.authz.can_write_role(role.id)) data = parse_request("RoleUpdate") # When changing passwords, check the old password first. # cf. https://github.com/alephdata/aleph/issues/718 if data.get("password"): current_password = data.get("current_password") if not role.check_password(current_password): raise BadRequest(gettext("Incorrect password.")) role.update(data) db.session.add(role) db.session.commit() update_role(role) return RoleSerializer.jsonify(role)
def setUp(self): super(NotificationsApiTestCase, self).setUp() self.rolex = self.create_user(foreign_id='rolex') self.admin = self.create_user(foreign_id='admin') self.col = self.create_collection(creator=self.admin) update_role(self.rolex) update_role(self.admin) event = Events.PUBLISH_COLLECTION publish(event, self.admin.id, params={ 'collection': self.col }, channels=[Notification.GLOBAL]) event = Events.GRANT_COLLECTION publish(event, self.admin.id, params={ 'collection': self.col, 'role': self.rolex }) db.session.commit()
def update(id): role = obj_or_404(Role.by_id(id)) require(request.authz.can_write_role(role.id)) data = parse_request(RoleSchema) # When changing passwords, check the old password first. # cf. https://github.com/alephdata/aleph/issues/718 if data.get('password'): current_password = data.get('current_password') if not role.check_password(current_password): raise BadRequest(gettext('Incorrect password.')) role.update(data) db.session.add(role) db.session.commit() update_role(role) return RoleSerializer.jsonify(role)
def setUp(self): super(NotificationsApiTestCase, self).setUp() self.rolex = self.create_user(foreign_id='rolex') self.admin = self.create_user(foreign_id='admin') self.col = self.create_collection(creator=self.admin) update_role(self.rolex) update_role(self.admin) event = Events.PUBLISH_COLLECTION publish(event, self.admin.id, params={ 'collection': self.col }, channels=[Notification.GLOBAL]) event = Events.GRANT_COLLECTION publish(event, self.admin.id, params={ 'collection': self.col, 'role': self.rolex }, channels=[self.col, self.rolex]) db.session.commit()
def password_login(): """Provides email and password authentication. --- post: summary: Log in as a user description: Create a session token using a username and password. requestBody: content: application/json: schema: $ref: '#/components/schemas/Login' responses: '200': description: OK content: application/json: schema: type: object properties: status: type: string token: type: string tags: - Role """ require(settings.PASSWORD_LOGIN) data = parse_request("Login") role = Role.by_email(data.get("email")) if role is None or not role.has_password: raise BadRequest(gettext("Invalid user or password.")) if not role.check_password(data.get("password")): raise BadRequest(gettext("Invalid user or password.")) if role.is_blocked: raise Unauthorized(gettext("Your account is blocked.")) role.touch() db.session.commit() update_role(role) authz = Authz.from_role(role) request.authz = authz return jsonify({"status": "ok", "token": authz.to_token(role=role)})
def password_login(): """Provides email and password authentication.""" data = parse_request(LoginSchema) role = Role.by_email(data.get('email')) if role is None or not role.has_password: return Unauthorized("Authentication has failed.") if not role.check_password(data.get('password')): return Unauthorized("Authentication has failed.") db.session.commit() update_role(role) authz = Authz.from_role(role) request.authz = authz record_audit(Audit.ACT_LOGIN) return jsonify({ 'status': 'ok', 'token': authz.to_token(role=role) })
def oauth_callback(): require(settings.OAUTH) err = Unauthorized(gettext("Authentication has failed.")) state = cache.get_complex(_oauth_session(request.args.get("state"))) if state is None: raise err try: oauth.provider.framework.set_session_data(request, "state", state.get("state")) uri = state.get("redirect_uri") oauth_token = oauth.provider.authorize_access_token(redirect_uri=uri) except AuthlibBaseError as err: log.warning("Failed OAuth: %r", err) raise err if oauth_token is None or isinstance(oauth_token, AuthlibBaseError): log.warning("Failed OAuth: %r", oauth_token) raise err role = handle_oauth(oauth.provider, oauth_token) if role is None: raise err # Determine session duration based on OAuth settings expire = oauth_token.get("expires_in", Authz.EXPIRE) expire = oauth_token.get("refresh_expires_in", expire) db.session.commit() update_role(role) log.debug("Logged in: %r", role) request.authz = Authz.from_role(role, expire=expire) token = request.authz.to_token() # Store id_token to generate logout URL later id_token = oauth_token.get("id_token") if id_token is not None: cache.set(_token_session(token), id_token, expires=expire) next_path = get_url_path(state.get("next_url")) next_url = ui_url("oauth", next=next_path) next_url = "%s#token=%s" % (next_url, token) session.clear() return redirect(next_url)