Beispiel #1
0
def user_getall(name):
    """
    Returns users with the given username, email address or Twitter id
    """
    names = name
    userids = set()  # Dupe checker
    if not names:
        return api_result("error", error="no_name_provided")
    results = []
    for name in names:
        user = getuser(name)
        if user and user.userid not in userids:
            results.append(
                {
                    "type": "user",
                    "userid": user.userid,
                    "buid": user.userid,
                    "name": user.username,
                    "title": user.fullname,
                    "label": user.pickername,
                }
            )
            userids.add(user.userid)
    if not results:
        return api_result("error", error="not_found")
    else:
        return api_result("ok", results=results)
Beispiel #2
0
def user_getall(name):
    """
    Returns users with the given username, email address or Twitter id
    """
    names = name
    buids = set()  # Dupe checker
    if not names:
        return api_result('error', error='no_name_provided')
    results = []
    for name in names:
        user = getuser(name)
        if user and user.buid not in buids:
            results.append({
                'type': 'user',
                'userid': user.buid,
                'buid': user.buid,
                'uuid': user.uuid,
                'name': user.username,
                'title': user.fullname,
                'label': user.pickername,
                'timezone': user.timezone,
                'oldids': [o.buid for o in user.oldids],
                'olduuids': [o.uuid for o in user.oldids],
            })
            buids.add(user.buid)
    if not results:
        return api_result('error', error='not_found')
    else:
        return api_result('ok', results=results)
Beispiel #3
0
def user_getall(name):
    """
    Returns users with the given username, email address or Twitter id
    """
    names = name
    userids = set()  # Dupe checker
    if not names:
        return api_result('error', error='no_name_provided')
    results = []
    for name in names:
        user = getuser(name)
        if user and user.userid not in userids:
            results.append({
                'type': 'user',
                'userid': user.userid,
                'buid': user.userid,
                'name': user.username,
                'title': user.fullname,
                'label': user.pickername,
                'timezone': user.timezone,
                'oldids': [o.userid for o in user.oldids],
                })
            userids.add(user.userid)
    if not results:
        return api_result('error', error='not_found')
    else:
        return api_result('ok', results=results)
Beispiel #4
0
 def validate_password(self, field):
     user = getuser(self.username.data)
     if user and not user.pw_hash:
         raise LoginPasswordResetException()
     if user is None or not user.password_is(field.data):
         if not self.username.errors:
             raise forms.ValidationError(_("Incorrect password"))
     self.user = user
Beispiel #5
0
 def validate_password(self, field):
     if not self.username.data:
         # Can't validate password without a user
         return
     user = getuser(self.username.data)
     if user and not user.pw_hash:
         raise LoginPasswordResetException()
     if user is None or not user.password_is(field.data):
         if not self.username.errors:
             raise forms.ValidationError(_("Incorrect password"))
     self.user = user
Beispiel #6
0
def user_get(name):
    """
    Returns user with the given username, email address or Twitter id
    """
    if not name:
        return api_result("error", error="no_name_provided")
    user = getuser(name)
    if user:
        return api_result("ok", type="user", userid=user.userid, name=user.username, title=user.fullname)
    else:
        return api_result("error", error="not_found")
Beispiel #7
0
    def test_getuser(self):
        """
        Test for retrieving username by prepending @
        """
        # scenario 1: with @ starting in name and extid
        crusoe = self.fixtures.crusoe
        service_twitter = 'twitter'
        oauth_token = environ.get('TWITTER_OAUTH_TOKEN')
        oauth_token_type = 'Bearer'  # NOQA: S105
        externalid = models.UserExternalId(
            service=service_twitter,
            user=crusoe,
            userid=crusoe.email.email,
            username=crusoe.username,
            oauth_token=oauth_token,
            oauth_token_type=oauth_token_type,
        )
        db.session.add(externalid)
        db.session.commit()
        result1 = models.getuser('@crusoe')
        self.assertIsInstance(result1, models.User)
        self.assertEqual(result1, crusoe)

        # scenario 2: with @ in name and not extid
        d_email = '*****@*****.**'
        daenerys = models.User(
            username='******', fullname="Daenerys Targaryen", email=d_email
        )
        daenerys_email = models.UserEmail(email=d_email, user=daenerys)
        db.session.add_all([daenerys, daenerys_email])
        db.session.commit()
        result2 = models.getuser(d_email)
        self.assertIsInstance(result2, models.User)
        self.assertEqual(result2, daenerys)
        result3 = models.getuser('@daenerys')
        self.assertIsNone(result3)

        # scenario 3: with no @ starting in name, check by UserEmailClaim
        j_email = '*****@*****.**'
        jonsnow = models.User(username='******', fullname="Jon Snow")
        jonsnow_email_claimed = models.UserEmailClaim(email=j_email, user=jonsnow)
        db.session.add_all([jonsnow, jonsnow_email_claimed])
        db.session.commit()
        result4 = models.getuser(j_email)
        self.assertIsInstance(result4, models.User)
        self.assertEqual(result4, jonsnow)

        # scenario 5: with no @ anywhere in name, fetch username
        arya = models.User(username='******', fullname="Arya Stark")
        db.session.add(arya)
        db.session.commit()
        result5 = models.getuser('arya')
        self.assertEqual(result5, arya)

        # scenario 6: with no starting with @ name and no UserEmailClaim or UserEmail
        cersei = models.User(username='******', fullname="Cersei Lannister")
        db.session.add(cersei)
        db.session.commit()
        result6 = models.getuser('*****@*****.**')
        self.assertIsNone(result6)
Beispiel #8
0
def user_get(name):
    """
    Returns user with the given username, email address or Twitter id
    """
    if not name:
        return api_result('error', error='no_name_provided')
    user = getuser(name)
    if user:
        return api_result('ok',
            type='user',
            userid=user.userid,
            name=user.username,
            title=user.fullname)
    else:
        return api_result('error', error='not_found')
Beispiel #9
0
    def test_getuser(self):
        """
        Test for retrieving username by prepending @
        """
        # scenario 1: with @ starting in name and extid
        crusoe = self.fixtures.crusoe
        service_twitter = u'twitter'
        oauth_token = environ.get('TWITTER_OAUTH_TOKEN')
        oauth_token_type = u'Bearer'
        externalid = models.UserExternalId(service=service_twitter, user=crusoe, userid=crusoe.email.email, username=crusoe.username, oauth_token=oauth_token, oauth_token_type=oauth_token_type)
        db.session.add(externalid)
        db.session.commit()
        result1 = models.getuser(u'@crusoe')
        self.assertIsInstance(result1, models.User)
        self.assertEqual(result1, crusoe)

        # scenario 2: with @ in name and not extid
        d_email = u'*****@*****.**'
        daenerys = models.User(username=d_email, fullname=u'Daenerys Targaryen', email=d_email)
        daenerys_email = models.UserEmail(email=d_email,
        user=daenerys)
        db.session.add_all([daenerys, daenerys_email])
        db.session.commit()
        result2 = models.getuser(d_email)
        self.assertIsInstance(result2, models.User)
        self.assertEqual(result2, daenerys)
        result3 = models.getuser(u'@daenerys')
        self.assertIsNone(result3)

        # scenario 3: with no @ starting in name, check by UserEmailClaim
        j_email = u'*****@*****.**'
        jonsnow = models.User(username=u'jonsnow', fullname=u'Jon Snow')
        jonsnow_email_claimed = models.UserEmailClaim(email=j_email, owner=jonsnow)
        db.session.add_all([jonsnow, jonsnow_email_claimed])
        db.session.commit()
        result4 = models.getuser(j_email)
        self.assertIsInstance(result4, models.User)
        self.assertEqual(result4, jonsnow)

        # scenario 5: with no @ anywhere in name, fetch username
        arya = models.User(username=u'arya', fullname=u'Arya Stark')
        db.session.add(arya)
        db.session.commit()
        result5 = models.getuser(u'arya')
        self.assertEqual(result5, arya)

        # scenario 6: with no starting with @ name and no UserEmailClaim or UserEmail
        cersei = models.User(username=u'cersei', fullname=u'Cersei Lannister')
        db.session.add(cersei)
        db.session.commit()
        result6 = models.getuser(u'*****@*****.**')
        self.assertIsNone(result6)
Beispiel #10
0
def user_get(name):
    """
    Returns user with the given username, email address or Twitter id
    """
    if not name:
        return api_result('error', error='no_name_provided')
    user = getuser(name)
    if user:
        return api_result('ok',
            type='user',
            userid=user.userid,
            buid=user.userid,
            name=user.username,
            title=user.fullname,
            label=user.pickername,
            timezone=user.timezone,
            oldids=[o.userid for o in user.oldids])
    else:
        return api_result('error', error='not_found')
Beispiel #11
0
def user_get(name):
    """
    Returns user with the given username, email address or Twitter id
    """
    if not name:
        return api_result('error', error='no_name_provided')
    user = getuser(name)
    if user:
        return api_result('ok',
                          type='user',
                          userid=user.userid,
                          buid=user.userid,
                          name=user.username,
                          title=user.fullname,
                          label=user.pickername,
                          timezone=user.timezone,
                          oldids=[o.userid for o in user.oldids])
    else:
        return api_result('error', error='not_found')
Beispiel #12
0
 def validate_password(self, field):
     user = getuser(self.username.data)
     if user is None or not user.password_is(field.data):
         raise wtforms.ValidationError("Incorrect password")
     self.user = user
Beispiel #13
0
 def validate_username(self, field):
     existing = getuser(field.data)
     if existing is None:
         raise wtforms.ValidationError("User does not exist")
Beispiel #14
0
 def validate_username(self, field):
     user = getuser(field.data)
     if user is None or user != self.edit_user:
         raise wtforms.ValidationError(
             "This username or email does not match the user the reset code is for")
Beispiel #15
0
 def validate_username(self, field):
     user = getuser(field.data)
     if user is None:
         raise wtforms.ValidationError("Could not find a user with that id")
     self.user = user
Beispiel #16
0
def oauth_token():
    """
    OAuth2 server -- token endpoint (confidential clients only)
    """
    # Always required parameters
    grant_type = request.form.get('grant_type')
    auth_client = current_auth.auth_client  # Provided by @requires_client_login
    scope = request.form.get('scope', '').split(' ')
    # if grant_type == 'authorization_code' (POST)
    code = request.form.get('code')
    redirect_uri = request.form.get('redirect_uri')
    # if grant_type == 'password' (POST)
    username = request.form.get('username')
    password = request.form.get('password')
    # if grant_type == 'client_credentials'
    buid = request.form.get('buid') or request.form.get(
        'userid')  # XXX: Deprecated userid parameter

    # Validations 1: Required parameters
    if not grant_type:
        return oauth_token_error('invalid_request', _("Missing grant_type"))
    # grant_type == 'refresh_token' is not supported. All tokens are permanent unless revoked
    if grant_type not in [
            'authorization_code', 'client_credentials', 'password'
    ]:
        return oauth_token_error('unsupported_grant_type')

    # Validations 2: client scope
    if grant_type == 'client_credentials':
        # AuthClient data; user isn't part of it OR trusted client and automatic scope
        try:
            # Confirm the client has access to the scope it wants
            verifyscope(scope, auth_client)
        except ScopeException as scopeex:
            return oauth_token_error('invalid_scope', str(scopeex))

        if buid:
            if auth_client.trusted:
                user = User.get(buid=buid)
                if user:
                    # This client is trusted and can receive a user access token.
                    # However, don't grant it the scope it wants as the user's
                    # permission was not obtained. Instead, the client's
                    # pre-approved scope will be used for the token's effective scope.
                    token = oauth_make_token(user=user,
                                             auth_client=auth_client,
                                             scope=[])
                    return oauth_token_success(
                        token,
                        userinfo=get_userinfo(
                            user=token.user,
                            auth_client=auth_client,
                            scope=token.effective_scope,
                        ),
                    )
                else:
                    return oauth_token_error('invalid_grant',
                                             _("Unknown user"))
            else:
                return oauth_token_error('invalid_grant',
                                         _("Untrusted client app"))
        else:
            token = oauth_make_token(user=None,
                                     auth_client=auth_client,
                                     scope=scope)
        return oauth_token_success(token)

    # Validations 3: auth code
    elif grant_type == 'authorization_code':
        authcode = AuthCode.get_for_client(auth_client=auth_client, code=code)
        if not authcode:
            return oauth_token_error('invalid_grant', _("Unknown auth code"))
        if not authcode.is_valid():
            db.session.delete(authcode)
            db.session.commit()
            return oauth_token_error('invalid_grant', _("Expired auth code"))
        # Validations 3.1: scope in authcode
        if not scope or scope[0] == '':
            return oauth_token_error('invalid_scope', _("Scope is blank"))
        if not set(scope).issubset(set(authcode.scope)):
            return oauth_token_error('invalid_scope', _("Scope expanded"))
        else:
            # Scope not provided. Use whatever the authcode allows
            scope = authcode.scope
        if redirect_uri != authcode.redirect_uri:
            return oauth_token_error('invalid_client',
                                     _("redirect_uri does not match"))

        token = oauth_make_token(user=authcode.user,
                                 auth_client=auth_client,
                                 scope=scope)
        db.session.delete(authcode)
        return oauth_token_success(
            token,
            userinfo=get_userinfo(
                user=authcode.user,
                auth_client=auth_client,
                scope=token.effective_scope,
                user_session=authcode.user_session,
            ),
        )

    elif grant_type == 'password':
        # Validations 4.1: password grant_type is only for trusted clients
        if not auth_client.trusted:
            # Refuse to untrusted clients
            return oauth_token_error(
                'unauthorized_client',
                _("AuthClient is not trusted for password grant_type"),
            )
        # Validations 4.2: Are username and password provided and correct?
        if not username or not password:
            return oauth_token_error('invalid_request',
                                     _("Username or password not provided"))
        user = getuser(username)
        if not user:
            return oauth_token_error(
                'invalid_client',
                _("No such user"))  # XXX: invalid_client doesn't seem right
        if not user.password_is(password):
            return oauth_token_error('invalid_client', _("Password mismatch"))
        # Validations 4.3: verify scope
        try:
            verifyscope(scope, auth_client)
        except ScopeException as scopeex:
            return oauth_token_error('invalid_scope', str(scopeex))
        # All good. Grant access
        token = oauth_make_token(user=user,
                                 auth_client=auth_client,
                                 scope=scope)
        return oauth_token_success(
            token,
            userinfo=get_userinfo(user=user,
                                  auth_client=auth_client,
                                  scope=scope),
        )
Beispiel #17
0
 def validate_username(self, field):
     user = getuser(field.data)
     if user is None:
         raise forms.ValidationError(
             _("Could not find a user with that id"))
     self.user = user
Beispiel #18
0
def oauth_token():
    """
    OAuth2 server -- token endpoint
    """
    # Always required parameters
    grant_type = request.form.get('grant_type')
    client = g.client  # Provided by @requires_client_login
    scope = request.form.get('scope', u'').split(u' ')
    # if grant_type == 'authorization_code' (POST)
    code = request.form.get('code')
    redirect_uri = request.form.get('redirect_uri')
    # if grant_type == 'password' (GET)
    username = request.form.get('username')
    password = request.form.get('password')

    # Validations 1: Required parameters
    if not grant_type:
        return oauth_token_error('invalid_request', "Missing grant_type")
    # grant_type == 'refresh_token' is not supported. All tokens are permanent unless revoked
    if grant_type not in [
            'authorization_code', 'client_credentials', 'password'
    ]:
        return oauth_token_error('unsupported_grant_type')

    # Validations 2: client scope
    if grant_type == 'client_credentials':
        # Client data. User isn't part of it
        try:
            verifyscope(scope, client)
        except ScopeException as scopeex:
            return oauth_token_error('invalid_scope', unicode(scopeex))

        token = oauth_make_token(user=None, client=client, scope=scope)
        return oauth_token_success(token)

    # Validations 3: auth code
    elif grant_type == 'authorization_code':
        authcode = AuthCode.query.filter_by(code=code, client=client).first()
        if not authcode:
            return oauth_token_error('invalid_grant', "Unknown auth code")
        if not authcode.is_valid():
            db.session.delete(authcode)
            db.session.commit()
            return oauth_token_error('invalid_grant', "Expired auth code")
        # Validations 3.1: scope in authcode
        if not scope or scope[0] == '':
            return oauth_token_error('invalid_scope', "Scope is blank")
        if not set(scope).issubset(set(authcode.scope)):
            return oauth_token_error('invalid_scope', "Scope expanded")
        else:
            # Scope not provided. Use whatever the authcode allows
            scope = authcode.scope
        if redirect_uri != authcode.redirect_uri:
            return oauth_token_error('invalid_client',
                                     "redirect_uri does not match")

        token = oauth_make_token(user=authcode.user,
                                 client=client,
                                 scope=scope)
        db.session.delete(authcode)
        return oauth_token_success(token,
                                   userinfo=get_userinfo(
                                       user=authcode.user,
                                       client=client,
                                       scope=scope,
                                       session=authcode.session))

    elif grant_type == 'password':
        # Validations 4.1: password grant_type is only for trusted clients
        if not client.trusted:
            # Refuse to untrusted clients
            return oauth_token_error(
                'unauthorized_client',
                "Client is not trusted for password grant_type")
        # Validations 4.2: Are username and password provided and correct?
        if not username or not password:
            return oauth_token_error('invalid_request',
                                     "Username or password not provided")
        user = getuser(username)
        if not user:
            return oauth_token_error(
                'invalid_client',
                "No such user")  # XXX: invalid_client doesn't seem right
        if not user.password_is(password):
            return oauth_token_error('invalid_client', "Password mismatch")
        # Validations 4.3: verify scope
        try:
            verifyscope(scope, client)
        except ScopeException as scopeex:
            return oauth_token_error('invalid_scope', unicode(scopeex))
        # All good. Grant access
        token = oauth_make_token(user=user, client=client, scope=scope)
        return oauth_token_success(token,
                                   userinfo=get_userinfo(user=user,
                                                         client=client,
                                                         scope=scope))
Beispiel #19
0
 def validate_username(self, field):
     existing = getuser(field.data)
     if existing is None:
         raise wtforms.ValidationError("User does not exist")
Beispiel #20
0
 def validate_username(self, field):
     user = getuser(field.data)
     if user is None or user != self.edit_user:
         raise forms.ValidationError(
             _("This username or email does not match the user the reset code is for"
               ))
Beispiel #21
0
 def validate_password(self, field):
     user = getuser(self.username.data)
     if user is None or not user.password_is(field.data):
         raise wtforms.ValidationError("Incorrect password")
     self.user = user
Beispiel #22
0
def oauth_token():
    """
    OAuth2 server -- token endpoint
    """
    # Always required parameters
    grant_type = request.form.get('grant_type')
    client = g.client  # Provided by @requires_client_login
    scope = request.form.get('scope', u'').split(u' ')
    # if grant_type == 'authorization_code' (POST)
    code = request.form.get('code')
    redirect_uri = request.form.get('redirect_uri')
    # if grant_type == 'password' (GET)
    username = request.form.get('username')
    password = request.form.get('password')

    # Validations 1: Required parameters
    if not grant_type:
        return oauth_token_error('invalid_request', "Missing grant_type")
    # grant_type == 'refresh_token' is not supported. All tokens are permanent unless revoked
    if grant_type not in ['authorization_code', 'client_credentials', 'password']:
        return oauth_token_error('unsupported_grant_type')

    # Validations 2: client scope
    if grant_type == 'client_credentials':
        # Client data. User isn't part of it
        try:
            verifyscope(scope, client)
        except ScopeException as scopeex:
            return oauth_token_error('invalid_scope', unicode(scopeex))

        token = oauth_make_token(user=None, client=client, scope=scope)
        return oauth_token_success(token)

    # Validations 3: auth code
    elif grant_type == 'authorization_code':
        authcode = AuthCode.query.filter_by(code=code, client=client).first()
        if not authcode:
            return oauth_token_error('invalid_grant', "Unknown auth code")
        if not authcode.is_valid():
            db.session.delete(authcode)
            db.session.commit()
            return oauth_token_error('invalid_grant', "Expired auth code")
        # Validations 3.1: scope in authcode
        if not scope or scope[0] == '':
            return oauth_token_error('invalid_scope', "Scope is blank")
        if not set(scope).issubset(set(authcode.scope)):
            return oauth_token_error('invalid_scope', "Scope expanded")
        else:
            # Scope not provided. Use whatever the authcode allows
            scope = authcode.scope
        if redirect_uri != authcode.redirect_uri:
            return oauth_token_error('invalid_client', "redirect_uri does not match")

        token = oauth_make_token(user=authcode.user, client=client, scope=scope)
        db.session.delete(authcode)
        return oauth_token_success(token, userinfo=get_userinfo(
            user=authcode.user, client=client, scope=scope, session=authcode.session))

    elif grant_type == 'password':
        # Validations 4.1: password grant_type is only for trusted clients
        if not client.trusted:
            # Refuse to untrusted clients
            return oauth_token_error('unauthorized_client', "Client is not trusted for password grant_type")
        # Validations 4.2: Are username and password provided and correct?
        if not username or not password:
            return oauth_token_error('invalid_request', "Username or password not provided")
        user = getuser(username)
        if not user:
            return oauth_token_error('invalid_client', "No such user")  # XXX: invalid_client doesn't seem right
        if not user.password_is(password):
            return oauth_token_error('invalid_client', "Password mismatch")
        # Validations 4.3: verify scope
        try:
            verifyscope(scope, client)
        except ScopeException as scopeex:
            return oauth_token_error('invalid_scope', unicode(scopeex))
        # All good. Grant access
        token = oauth_make_token(user=user, client=client, scope=scope)
        return oauth_token_success(token, userinfo=get_userinfo(user=user, client=client, scope=scope))