Merge "Removed Nickname"

This commit is contained in:
Jenkins 2015-03-30 10:07:56 +00:00 committed by Gerrit Code Review
commit 4ef8732f8f
16 changed files with 81 additions and 102 deletions

View File

@ -62,7 +62,6 @@ class ErrorMessages(object):
INVALID_NO_EMAIL = _('Please permit access to your email address.')
INVALID_NO_NAME = _('Please permit access to your name.')
INVALID_NO_NICKNAME = _('Please permit access to your nickname.')
INVALID_TOKEN_GRANT_TYPE = _('Only grant types "authorization_code" and '
'"refresh_token" are supported.')

View File

@ -112,12 +112,10 @@ class SkeletonValidator(RequestValidator):
openid = request._params["openid.claimed_id"]
email = request._params["openid.sreg.email"]
full_name = request._params["openid.sreg.fullname"]
username = request._params["openid.sreg.nickname"]
last_login = datetime.datetime.now(pytz.utc)
user = user_api.user_get_by_openid(openid)
user_dict = {"full_name": full_name,
"username": username,
"email": email,
"last_login": last_login}

View File

@ -108,7 +108,7 @@ class OpenIdClient(object):
"openid.return_to": return_to_url,
"openid.ns.sreg": "http://openid.net/sreg/1.0",
"openid.sreg.required": "fullname,email,nickname",
"openid.sreg.required": "fullname,email",
"openid.ns.ext2": "http://openid.net/srv/ax/1.0",
"openid.ext2.mode": "fetch_request",
@ -146,7 +146,6 @@ class OpenIdClient(object):
required_parameters = {
'openid.sreg.email': e_msg.INVALID_NO_EMAIL,
'openid.sreg.fullname': e_msg.INVALID_NO_NAME,
'openid.sreg.nickname': e_msg.INVALID_NO_NICKNAME,
}
for name, error in six.iteritems(required_parameters):

View File

@ -41,7 +41,7 @@ class SearchEngine(object):
models.Story: ["title", "description"],
models.Task: ["title"],
models.Comment: ["content"],
models.User: ['username', 'full_name', 'email']
models.User: ['full_name', 'email']
}
@abc.abstractmethod

View File

@ -59,7 +59,7 @@ class UsersController(rest.RestController):
@secure(checks.guest)
@wsme_pecan.wsexpose([wmodels.User], int, int, wtypes.text, wtypes.text,
wtypes.text, wtypes.text)
def get(self, marker=None, limit=None, username=None, full_name=None,
def get(self, marker=None, limit=None, full_name=None,
sort_field='id', sort_dir='asc'):
"""Page and filter the users in storyboard.
@ -80,12 +80,11 @@ class UsersController(rest.RestController):
marker_user = users_api.user_get(marker)
users = users_api.user_get_all(marker=marker_user, limit=limit,
username=username, full_name=full_name,
full_name=full_name,
filter_non_public=True,
sort_field=sort_field,
sort_dir=sort_dir)
user_count = users_api.user_get_count(username=username,
full_name=full_name)
user_count = users_api.user_get_count(full_name=full_name)
# Apply the query response headers.
response.headers['X-Limit'] = str(limit)

View File

@ -22,11 +22,6 @@ USERS_PUT_SCHEMA = {
"name": "user_schema",
"type": "object",
"properties": {
"username": {
"type": "string",
"minLength": CommonLength.lower_middle_length,
"maxLength": CommonLength.name_length
},
"full_name": {
"type": ["string"],
"minLength": CommonLength.lower_middle_length,
@ -45,7 +40,7 @@ USERS_PUT_SCHEMA = {
}
USERS_POST_SCHEMA = copy.deepcopy(USERS_PUT_SCHEMA)
USERS_POST_SCHEMA["required"] = ["username", "full_name", "email"]
USERS_POST_SCHEMA["required"] = ["full_name", "email"]
USER_PREFERENCES_POST_SCHEMA = {
"name": "userPreference_schema",

View File

@ -360,10 +360,6 @@ class TimeLineEvent(base.APIBase):
class User(base.APIBase):
"""Represents a user."""
username = wtypes.text
"""A short unique name, beginning with a lower-case letter or number, and
containing only letters, numbers, dots, hyphens, or plus signs"""
full_name = wtypes.text
"""Full (Display) name."""
@ -385,7 +381,6 @@ class User(base.APIBase):
@classmethod
def sample(cls):
return cls(
username="elbarto",
full_name="Bart Simpson",
openid="https://login.launchpad.net/+id/Abacaba",
email="skinnerstinks@springfield.net",

View File

@ -1,22 +0,0 @@
# Copyright (c) 2014 Mirantis Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from storyboard.db.api import users as users_api
def username_by_id(user_id):
user = users_api.user_get(user_id)
username = user.full_name or user.username
return username

View File

@ -0,0 +1,63 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
"""This migration removes the 'nickname' column from the user table.
Revision ID: 042
Revises: 041
Create Date: 2015-02-17 12:00:00
"""
# revision identifiers, used by Alembic.
revision = '042'
down_revision = '041'
from alembic import op
from oslo_log import log
import sqlalchemy as sa
LOG = log.getLogger(__name__)
def upgrade(active_plugins=None, options=None):
op.drop_column('users', 'username')
# Handle the FT Index on the user table.
version_info = op.get_bind().engine.dialect.server_version_info
if version_info[0] < 5 or version_info[0] == 5 and version_info[1] < 6:
LOG.warn("MySQL version is lower than 5.6. Skipping full-text indexes")
return
# Index for users
op.drop_index("users_fti", table_name='users')
op.execute("ALTER TABLE users "
"ADD FULLTEXT users_fti (full_name, email)")
def downgrade(active_plugins=None, options=None):
op.add_column(
'users',
sa.Column('username', sa.Unicode(length=30), nullable=True),
)
version_info = op.get_bind().engine.dialect.server_version_info
if version_info[0] < 5 or version_info[0] == 5 and version_info[1] < 6:
LOG.warn("MySQL version is lower than 5.6. Skipping full-text indexes")
return
# Index for users
op.drop_index("users_fti", table_name='users')
op.execute("ALTER TABLE users "
"ADD FULLTEXT users_fti (username, full_name, email)")

View File

@ -140,9 +140,8 @@ class User(FullText, ModelBuilder, Base):
schema.UniqueConstraint('email', name='uniq_user_email'),
)
__fulltext_columns__ = ['username', 'full_name', 'email']
__fulltext_columns__ = ['full_name', 'email']
username = Column(Unicode(CommonLength.name_length))
full_name = Column(Unicode(CommonLength.top_large_length), nullable=True)
email = Column(String(CommonLength.top_large_length))
openid = Column(String(CommonLength.top_large_length))
@ -156,7 +155,7 @@ class User(FullText, ModelBuilder, Base):
preferences = relationship("UserPreference")
_public_fields = ["id", "openid", "full_name", "username", "last_login",
_public_fields = ["id", "openid", "full_name", "last_login",
"enable_login"]

View File

@ -97,7 +97,6 @@ class LaunchpadWriter(object):
if lp_user is None:
return lp_user
username = lp_user.name
display_name = lp_user.display_name
user_link = lp_user.web_link
@ -114,9 +113,10 @@ class LaunchpadWriter(object):
except DiscoveryFailure:
# If we encounter a launchpad maintenance user,
# give it an invalid openid.
print "WARNING: Invalid OpenID for user \'%s\'" % (username,)
print "WARNING: Invalid OpenID for user \'%s\'" \
% (display_name,)
self._openid_map[user_link] = \
'http://example.com/invalid/~%s' % (username,)
'http://example.com/invalid/~%s' % (display_name,)
openid = self._openid_map[user_link]
@ -131,10 +131,9 @@ class LaunchpadWriter(object):
# Use a temporary email address, since LP won't give this to
# us and it'll be updated on first login anyway.
user = users_api.user_create({
'username': username,
'openid': openid,
'full_name': display_name,
'email': "%s@example.com" % (username)
'email': "%s@example.com" % (display_name)
})
self._user_map[openid] = user

View File

@ -121,7 +121,6 @@ class TestOAuthAuthorize(BaseOAuthTest):
# Check OAuth Registration parameters
self.assertIn('fullname', parameters['openid.sreg.required'][0])
self.assertIn('email', parameters['openid.sreg.required'][0])
self.assertIn('nickname', parameters['openid.sreg.required'][0])
# Check redirect URL
redirect = parameters['openid.return_to'][0]
@ -348,10 +347,9 @@ class TestOAuthAuthorizeReturn(BaseOAuthTest):
"ax.type.FirstName,ax.type.LastName,claimed_id,"
"identity,mode,ns,ns.ax,ns.sreg,op_endpoint,"
"response_nonce,return_to,signed,sreg.email,"
"sreg.fullname,sreg.nickname",
"sreg.fullname",
"openid.sreg.email": "test@example.com",
"openid.sreg.fullname": "Test User",
"openid.sreg.nickname": "superuser"
}
def _mock_response(self, mock_post, valid=True):
@ -473,34 +471,6 @@ class TestOAuthAuthorizeReturn(BaseOAuthTest):
error='invalid_request',
error_description=e_msg.INVALID_NO_EMAIL)
def test_invalid_redirect_no_username(self, mock_post):
"""If the oauth response to storyboard is valid, but does not include a
first name, it should error.
TODO: Remove during work for
https://storyboard.openstack.org/#!/story/2000152
"""
self._mock_response(mock_post, valid=True)
random_state = six.text_type(uuid.uuid4())
invalid_params = self.valid_params.copy()
del invalid_params['openid.sreg.nickname']
# Simple GET with various parameters
response = self.get_json(path='/openid/authorize_return',
expect_errors=True,
state=random_state,
**invalid_params)
# Validate the redirect response
self.assertValidRedirect(response=response,
expected_status_code=302,
redirect_uri=
self.valid_params['sb_redirect_uri'],
error='invalid_request',
error_description=e_msg.INVALID_NO_NICKNAME)
class TestOAuthAccessToken(BaseOAuthTest):
"""Functional test for the /oauth/token endpoint for the generation of

View File

@ -47,14 +47,12 @@ class TestDBExceptions(base.FunctionalTest):
# send user first time
resource = '/users'
user = {
'username': 'test_duplicate',
'full_name': 'Test duplicate',
'email': 'dupe@example.com'
}
response = self.post_json(resource, user)
users_body = response.json
self.assertEqual(user['username'], users_body['username'])
self.assertEqual(user['full_name'], users_body['full_name'])
self.assertEqual(user['email'], users_body['email'])

View File

@ -65,17 +65,15 @@ class TestUsers(base.FunctionalTest):
self.default_headers['Authorization'] = 'Bearer valid_superuser_token'
self.user_01 = {
'username': 'jsonschema_test_user1',
'full_name': 'jsonschema_test_user1',
'email': 'jsonschema_test_user1@test.ru',
'openid': 'qwerty'
}
self.user_02 = {
'username': 't2',
'full_name': 'jsonschema_test_user2',
'email': 'jsonschema_test_user2@test.ru',
'openid': 'qwertyu'
'full_name': LONG_STRING,
'email': 'jsonschema_test_user3@test.ru',
'openid': 'qwertyui'
}
self.user_03 = {
@ -85,12 +83,6 @@ class TestUsers(base.FunctionalTest):
'openid': 'qwertyui'
}
self.user_04 = {
'full_name': 'jsonschema_test_user4',
'email': 'jsonschema_test_user4@test.ru',
'openid': 'qwertyuio'
}
self.put_user_01 = {
'full_name': 'new full_name of regular User'
}
@ -107,9 +99,7 @@ class TestUsers(base.FunctionalTest):
create(self, self.user_01, self.resource)
def test_create_invalid(self):
create_invalid_length(self, self.user_02, self.resource, 'username')
create_invalid_length(self, self.user_03, self.resource, 'full_name')
create_invalid_required(self, self.user_04, self.resource, 'username')
create_invalid_length(self, self.user_02, self.resource, 'full_name')
def test_update(self):
resource = "".join([self.resource, "/2"])

View File

@ -87,5 +87,5 @@ class TestSearchUsers(base.FunctionalTest):
self.default_headers['Authorization'] = 'Bearer valid_user_token'
def testBrowse(self):
result = self.get_json(self.resource + '?username=regularuser')
result = self.get_json(self.resource + '?full_name=Regular')
self.assertEqual(1, len(result))

View File

@ -40,19 +40,16 @@ def load():
# Load users
load_data([
User(id=1,
username='superuser',
email='superuser@example.com',
openid='superuser_openid',
full_name='Super User',
is_superuser=True),
User(id=2,
username='regularuser',
email='regularuser@example.com',
openid='regularuser_openid',
full_name='Regular User',
is_superuser=False),
User(id=3,
username='otheruser',
email='otheruser@example.com',
openid='otheruser_openid',
full_name='Other User',