Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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.")
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
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)
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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)})
Ejemplo n.º 16
0
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)})
Ejemplo n.º 17
0
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)
Ejemplo n.º 18
0
 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()
Ejemplo n.º 19
0
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)
Ejemplo n.º 20
0
 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()
Ejemplo n.º 21
0
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)})
Ejemplo n.º 22
0
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)
    })
Ejemplo n.º 23
0
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)