From 42749f857049d873076e73628b9174458e378fd6 Mon Sep 17 00:00:00 2001 From: Bibhas Date: Wed, 4 Dec 2019 12:48:11 +0530 Subject: [PATCH 01/10] py2to3 changes --- features/steps/failed_registration.py | 4 +- features/steps/login.py | 4 +- features/steps/registration.py | 2 +- instance/settings-sample.py | 6 +- instance/testing.py | 6 +- lastuser_core/models/client.py | 50 +++---- lastuser_core/models/notification.py | 54 ++++---- lastuser_core/models/session.py | 4 +- lastuser_core/models/user.py | 36 ++--- lastuser_core/registry.py | 16 +-- lastuser_core/utils.py | 22 +-- lastuser_oauth/forms/login.py | 2 +- lastuser_oauth/forms/profile.py | 2 +- lastuser_oauth/providers/github.py | 10 +- lastuser_oauth/providers/google.py | 14 +- lastuser_oauth/providers/linkedin.py | 16 +-- lastuser_oauth/providers/openid.py | 2 +- lastuser_oauth/providers/twitter.py | 4 +- lastuser_oauth/views/account.py | 12 +- lastuser_oauth/views/helpers.py | 6 +- lastuser_oauth/views/login.py | 34 ++--- lastuser_oauth/views/notify.py | 2 +- lastuser_oauth/views/oauth.py | 38 +++--- lastuser_oauth/views/profile.py | 20 +-- lastuser_oauth/views/resource.py | 70 +++++----- lastuser_ui/forms/client.py | 16 +-- lastuser_ui/forms/org.py | 8 +- lastuser_ui/forms/profile.py | 6 +- lastuser_ui/views/client.py | 66 ++++----- lastuser_ui/views/dashboard.py | 4 +- lastuser_ui/views/org.py | 16 +-- lastuser_ui/views/profile.py | 34 ++--- migrations/env.py | 2 +- ...46_user_password_and_client_credentials.py | 8 +- .../versions/4e206c5ddabd_uuid_userid.py | 6 +- .../versions/518321b25909_username_model.py | 18 +-- ...remove_org_and_team_ownership_of_email_.py | 48 +++---- rqinit.py | 2 +- runtestserver.py | 12 +- tests/unit/lastuser_core/fixtures.py | 38 +++--- .../test_model_client_AuthCode.py | 8 +- .../test_model_client_AuthToken.py | 48 +++---- .../lastuser_core/test_model_client_Client.py | 18 +-- .../test_model_client_Permission.py | 6 +- .../test_model_client_Resource.py | 2 +- .../test_model_client_ScopeMixin.py | 22 +-- ...test_model_client_UserClientPermissions.py | 24 ++-- .../lastuser_core/test_model_user_Name.py | 46 +++---- .../test_model_user_Organization.py | 60 ++++----- .../lastuser_core/test_model_user_Team.py | 4 +- .../lastuser_core/test_model_user_User.py | 126 +++++++++--------- .../test_model_user_UserEmail.py | 12 +- .../test_model_user_UserEmailClaim.py | 24 ++-- .../test_model_user_UserExternalId.py | 2 +- .../test_model_user_UserOldId.py | 2 +- .../test_model_user_UserPhone.py | 10 +- .../test_model_user_UserPhoneClaim.py | 20 +-- tests/unit/lastuser_core/test_models.py | 36 ++--- .../test_registry_LoginProviderRegistry.py | 2 +- .../lastuser_core/test_session_UserSession.py | 14 +- 60 files changed, 603 insertions(+), 603 deletions(-) diff --git a/features/steps/failed_registration.py b/features/steps/failed_registration.py index c3a3a44..55a1442 100644 --- a/features/steps/failed_registration.py +++ b/features/steps/failed_registration.py @@ -15,7 +15,7 @@ def given_new_user(context): # registering the test user context.browser.visit('/register') assert context.browser.find_element_by_name('csrf_token').is_enabled() - for k, v in context.test_user.iteritems(): + for k, v in context.test_user.items(): context.browser.find_element_by_name(k).send_keys(v) register_form = context.browser.find_element_by_id('form-register') @@ -30,7 +30,7 @@ def when_form_submit(context): # this will fail context.browser.visit('/register') assert context.browser.find_element_by_name('csrf_token').is_enabled() - for k, v in context.test_user.iteritems(): + for k, v in context.test_user.items(): context.browser.find_element_by_name(k).send_keys(v) register_form = context.browser.find_element_by_id('form-register') diff --git a/features/steps/login.py b/features/steps/login.py index 09a6a1e..c095f9d 100644 --- a/features/steps/login.py +++ b/features/steps/login.py @@ -15,7 +15,7 @@ def given_existing_user(context): context.browser.visit('/register') assert context.browser.find_element_by_name('csrf_token').is_enabled() - for k, v in context.test_user.iteritems(): + for k, v in context.test_user.items(): context.browser.find_element_by_name(k).send_keys(v) register_form = context.browser.find_element_by_id('form-register') @@ -34,7 +34,7 @@ def when_login_form_submit(context): assert context.browser.find_element_by_name('csrf_token').is_enabled() context.browser.find_element_by_id('showmore').click() - for k, v in context.login_data.iteritems(): + for k, v in context.login_data.items(): context.browser.find_element_by_name(k).send_keys(v) context.browser.find_element_by_name('username').submit() diff --git a/features/steps/registration.py b/features/steps/registration.py index 8c22e61..74bcc84 100644 --- a/features/steps/registration.py +++ b/features/steps/registration.py @@ -19,7 +19,7 @@ def when_form_submit(context): context.browser.visit('/register') assert context.browser.find_element_by_name('csrf_token').is_enabled() - for k, v in context.test_user.iteritems(): + for k, v in context.test_user.items(): context.browser.find_element_by_name(k).send_keys(v) register_form = context.browser.find_element_by_id('form-register') diff --git a/instance/settings-sample.py b/instance/settings-sample.py index 9c559e2..6afc2d7 100644 --- a/instance/settings-sample.py +++ b/instance/settings-sample.py @@ -135,14 +135,14 @@ USERNAME_REASON = '' EMAIL_REASON = 'Please provide an email address to complete your profile' TIMEZONE_REASON = 'Dates and times will be shown in your preferred timezone' -ORG_NAME_REASON = u"Your company’s name as it will appear in the URL. Letters, numbers and dashes only" -ORG_TITLE_REASON = u"Your organization’s given name, preferably without legal suffixes" +ORG_NAME_REASON = "Your company’s name as it will appear in the URL. Letters, numbers and dashes only" +ORG_TITLE_REASON = "Your organization’s given name, preferably without legal suffixes" LOGIN_MESSAGE_1 = "" LOGIN_MESSAGE_2 = "" SMS_VERIFICATION_TEMPLATE = ( 'Your verification code is {code}. If you did not request this, please ignore.' ) CREATE_ACCOUNT_MESSAGE = ( - u"This account is for you as an individual. We’ll make one for your company later" + "This account is for you as an individual. We’ll make one for your company later" ) LOGOUT_UNAUTHORIZED_MESSAGE = "We detected a possibly unauthorized attempt to log you out. If you really did intend to logout, please click on the logout link again" diff --git a/instance/testing.py b/instance/testing.py index 018664f..0df0977 100644 --- a/instance/testing.py +++ b/instance/testing.py @@ -99,10 +99,10 @@ EMAIL_REASON = 'Please provide an email address to complete your profile' BIO_REASON = '' TIMEZONE_REASON = 'Dates and times will be shown in your preferred timezone' -ORG_NAME_REASON = u"Your company’s name as it will appear in the URL. Letters, numbers and dashes only" -ORG_TITLE_REASON = u"Your organization’s given name, preferably without legal suffixes" +ORG_NAME_REASON = "Your company’s name as it will appear in the URL. Letters, numbers and dashes only" +ORG_TITLE_REASON = "Your organization’s given name, preferably without legal suffixes" ORG_DESCRIPTION_REASON = ( - u"A few words about your organization (optional). Plain text only" + "A few words about your organization (optional). Plain text only" ) LOGIN_MESSAGE_1 = "" LOGIN_MESSAGE_2 = "" diff --git a/lastuser_core/models/client.py b/lastuser_core/models/client.py index 0027ab8..5bb8520 100644 --- a/lastuser_core/models/client.py +++ b/lastuser_core/models/client.py @@ -2,7 +2,7 @@ from datetime import timedelta from hashlib import sha256 -import urlparse +import urllib.parse from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.orm import load_only @@ -47,16 +47,16 @@ def _scope_get(self): return tuple(sorted(self._scope.split())) def _scope_set(self, value): - if isinstance(value, basestring): + if isinstance(value, str): value = [value] - self._scope = u' '.join(sorted(t.strip() for t in value if t)) + self._scope = ' '.join(sorted(t.strip() for t in value if t)) @declared_attr def scope(cls): return db.synonym('_scope', descriptor=property(cls._scope_get, cls._scope_set)) def add_scope(self, additional): - if isinstance(additional, basestring): + if isinstance(additional, str): additional = [additional] self.scope = list(set(self.scope).union(set(additional))) @@ -83,7 +83,7 @@ class Client(ScopeMixin, BaseMixin, db.Model): #: Human-readable title title = db.Column(db.Unicode(250), nullable=False) #: Long description - description = db.Column(db.UnicodeText, nullable=False, default=u'') + description = db.Column(db.UnicodeText, nullable=False, default='') #: Confidential or public client? Public has no secret key confidential = db.Column(db.Boolean, nullable=False) #: Website @@ -92,12 +92,12 @@ class Client(ScopeMixin, BaseMixin, db.Model): namespace = db.Column(db.UnicodeText, nullable=True, unique=True) #: Redirect URIs (one or more) _redirect_uris = db.Column( - 'redirect_uri', db.UnicodeText, nullable=True, default=u'' + 'redirect_uri', db.UnicodeText, nullable=True, default='' ) #: Back-end notification URI - notification_uri = db.Column(db.UnicodeText, nullable=True, default=u'') + notification_uri = db.Column(db.UnicodeText, nullable=True, default='') #: Front-end notification URI - iframe_uri = db.Column(db.UnicodeText, nullable=True, default=u'') + iframe_uri = db.Column(db.UnicodeText, nullable=True, default='') #: Active flag active = db.Column(db.Boolean, nullable=False, default=True) #: Allow anyone to login to this app? @@ -131,7 +131,7 @@ class Client(ScopeMixin, BaseMixin, db.Model): ) def __repr__(self): - return u''.format(title=self.title, key=self.key) + return ''.format(title=self.title, key=self.key) def secret_is(self, candidate, name): """ @@ -146,7 +146,7 @@ def redirect_uris(self): @redirect_uris.setter def redirect_uris(self, value): - self._redirect_uris = u'\r\n'.join(value) + self._redirect_uris = '\r\n'.join(value) @property def redirect_uri(self): @@ -155,10 +155,10 @@ def redirect_uri(self): return uris[0] def host_matches(self, url): - netloc = urlparse.urlsplit(url or '').netloc + netloc = urllib.parse.urlsplit(url or '').netloc if netloc: return netloc in [ - urlparse.urlsplit(r).netloc + urllib.parse.urlsplit(r).netloc for r in list(self.redirect_uris) + [self.website] ] return False @@ -249,7 +249,7 @@ class ClientCredential(BaseMixin, db.Model): #: OAuth client key name = db.Column(db.String(22), nullable=False, unique=True, default=buid) #: User description for this credential - title = db.Column(db.Unicode(250), nullable=False, default=u'') + title = db.Column(db.Unicode(250), nullable=False, default='') #: OAuth client secret, hashed (64 chars hash plus 7 chars id prefix = 71 chars) secret_hash = db.Column(db.String(71), nullable=False) #: When was this credential last used for an API call? @@ -312,7 +312,7 @@ class Resource(BaseScopedNameMixin, db.Model): ) parent = db.synonym('client') title = db.Column(db.Unicode(250), nullable=False) - description = db.Column(db.UnicodeText, default=u'', nullable=False) + description = db.Column(db.UnicodeText, default='', nullable=False) siteresource = db.Column(db.Boolean, default=False, nullable=False) restricted = db.Column(db.Boolean, default=False, nullable=False) __table_args__ = ( @@ -369,7 +369,7 @@ class ResourceAction(BaseMixin, db.Model): backref=db.backref('actions', cascade='all, delete-orphan'), ) title = db.Column(db.Unicode(250), nullable=False) - description = db.Column(db.UnicodeText, default=u'', nullable=False) + description = db.Column(db.UnicodeText, default='', nullable=False) # Action names are unique per client app __table_args__ = (db.UniqueConstraint('resource_id', 'name'),) @@ -445,7 +445,7 @@ class AuthToken(ScopeMixin, BaseMixin, db.Model): token = db.Column(db.String(22), default=buid, nullable=False, unique=True) #: The token's type token_type = db.Column( - db.String(250), default=u'bearer', nullable=False + db.String(250), default='bearer', nullable=False ) # 'bearer', 'mac' or a URL #: Token secret for 'mac' type secret = db.Column(db.String(44), nullable=True) @@ -485,7 +485,7 @@ def __init__(self, **kwargs): self.secret = newsecret() def __repr__(self): - return u''.format( + return ''.format( token=self.token, client=repr(self.client)[1:-1], user=repr(self.user)[1:-1] ) @@ -513,7 +513,7 @@ def algorithm(self, value): elif value in ['hmac-sha-1', 'hmac-sha-256']: self._algorithm = value else: - raise ValueError(_(u"Unrecognized algorithm ‘{value}’").format(value=value)) + raise ValueError(_("Unrecognized algorithm ‘{value}’").format(value=value)) algorithm = db.synonym('_algorithm', descriptor=algorithm) @@ -605,7 +605,7 @@ class Permission(BaseMixin, db.Model): #: Human-friendly title title = db.Column(db.Unicode(250), nullable=False) #: Description of what this permission is about - description = db.Column(db.UnicodeText, default=u'', nullable=False) + description = db.Column(db.UnicodeText, default='', nullable=False) #: Is this permission available to all users and client apps? allusers = db.Column(db.Boolean, default=False, nullable=False) @@ -677,7 +677,7 @@ class UserClientPermissions(BaseMixin, db.Model): ) #: The permissions as a string of tokens access_permissions = db.Column( - 'permissions', db.UnicodeText, default=u'', nullable=False + 'permissions', db.UnicodeText, default='', nullable=False ) # Only one assignment per user and client @@ -702,9 +702,9 @@ def migrate_user(cls, olduser, newuser): # Merge permission strings tokens = set(operm.access_permissions.split(' ')) tokens.update(set(nperm.access_permissions.split(' '))) - if u' ' in tokens: - tokens.remove(u' ') - nperm.access_permissions = u' '.join(sorted(tokens)) + if ' ' in tokens: + tokens.remove(' ') + nperm.access_permissions = ' '.join(sorted(tokens)) db.session.delete(operm) merge_performed = True if not merge_performed: @@ -732,7 +732,7 @@ class TeamClientPermissions(BaseMixin, db.Model): ) #: The permissions as a string of tokens access_permissions = db.Column( - 'permissions', db.UnicodeText, default=u'', nullable=False + 'permissions', db.UnicodeText, default='', nullable=False ) # Only one assignment per team and client @@ -790,6 +790,6 @@ class NoticeType(BaseMixin, db.Model): #: Human-friendly title title = db.Column(db.Unicode(250), nullable=False) #: Description of what this notice type is about - description = db.Column(db.UnicodeText, default=u'', nullable=False) + description = db.Column(db.UnicodeText, default='', nullable=False) #: Is this notice type available to all users and client apps? allusers = db.Column(db.Boolean, default=False, nullable=False) diff --git a/lastuser_core/models/notification.py b/lastuser_core/models/notification.py index 38f6621..db2eb98 100644 --- a/lastuser_core/models/notification.py +++ b/lastuser_core/models/notification.py @@ -14,42 +14,42 @@ class SMS_STATUS(LabeledEnum): # NOQA: N801 - QUEUED = (0, __(u"Queued")) - PENDING = (1, __(u"Pending")) - DELIVERED = (2, __(u"Delivered")) - FAILED = (3, __(u"Failed")) - UNKNOWN = (4, __(u"Unknown")) + QUEUED = (0, __("Queued")) + PENDING = (1, __("Pending")) + DELIVERED = (2, __("Delivered")) + FAILED = (3, __("Failed")) + UNKNOWN = (4, __("Unknown")) class NOTIFICATION_FLAGS(LabeledEnum): # NOQA: N801 - DELIVERY = (0, __(u"Delivery")) - READ = (1, __(u"Read")) - BOUNCE = (2, __(u"Bounce")) + DELIVERY = (0, __("Delivery")) + READ = (1, __("Read")) + BOUNCE = (2, __("Bounce")) class NOTIFICATION_TYPE(LabeledEnum): # NOQA: N801 #: Mandatory service announcement - MANDATORY = (0, u'mandatory', __(u"Mandatory")) + MANDATORY = (0, 'mandatory', __("Mandatory")) #: Result of user activity - TRANSACTIONAL = (1, u'transactional', __(u"Transactional")) + TRANSACTIONAL = (1, 'transactional', __("Transactional")) #: Periodic alert based on set criteria - ALERT = (2, u'alert', __(u"Alert")) + ALERT = (2, 'alert', __("Alert")) # "" Mass mail from the service provider - MASS = (3, u'mass', __(u"Mass")) + MASS = (3, 'mass', __("Mass")) # A note on frequency: scheduling/batching is done by Lastuser, not by the client app class NOTIFICATION_FREQUENCY(LabeledEnum): # NOQA: N801 #: Alert user immediately - IMMEDIATE = (0, u'immed', __(u"Immediately")) + IMMEDIATE = (0, 'immed', __("Immediately")) #: Send after a timeout, allowing app to cancel (tentative) - DELAYED = (1, u'delay', __(u"Delayed")) + DELAYED = (1, 'delay', __("Delayed")) #: Send a daily digest - DAILY = (2, u'daily', __(u"Batched daily")) + DAILY = (2, 'daily', __("Batched daily")) #: Send a weekly digest - WEEKLY = (3, u'weekly', __(u"Batched weekly")) + WEEKLY = (3, 'weekly', __("Batched weekly")) #: Send a monthly digest - MONTHLY = (4, u'monthly', __(u"Batched monthly")) + MONTHLY = (4, 'monthly', __("Batched monthly")) # --- Transport Channels ------------------------------------------------------ @@ -58,8 +58,8 @@ class NOTIFICATION_FREQUENCY(LabeledEnum): # NOQA: N801 class Channel(object): - name = u'' - title = u"" + name = '' + title = "" flags = [] delivery_flag = False @@ -68,8 +68,8 @@ class Channel(object): class ChannelBrowser(Channel): - name = u'browser' - title = __(u"In app") + name = 'browser' + title = __("In app") flags = [NOTIFICATION_FLAGS.DELIVERY, NOTIFICATION_FLAGS.READ] delivery_flag = True @@ -78,8 +78,8 @@ class ChannelBrowser(Channel): class ChannelEmail(Channel): - name = u'email' - title = __(u"Email") + name = 'email' + title = __("Email") flags = [NOTIFICATION_FLAGS.BOUNCE, NOTIFICATION_FLAGS.READ] delivery_flag = False @@ -88,8 +88,8 @@ class ChannelEmail(Channel): class ChannelTwitter(Channel): - name = u'twitter' - title = __(u"Twitter") + name = 'twitter' + title = __("Twitter") flags = [NOTIFICATION_FLAGS.DELIVERY, NOTIFICATION_FLAGS.BOUNCE] delivery_flag = True @@ -98,8 +98,8 @@ class ChannelTwitter(Channel): class ChannelSMS(Channel): - name = u'sms' - title = __(u"SMS") + name = 'sms' + title = __("SMS") flags = [NOTIFICATION_FLAGS.DELIVERY, NOTIFICATION_FLAGS.BOUNCE] delivery_flag = True diff --git a/lastuser_core/models/session.py b/lastuser_core/models/session.py index dcf9d7d..c628f6b 100644 --- a/lastuser_core/models/session.py +++ b/lastuser_core/models/session.py @@ -94,8 +94,8 @@ def access(self, client=None): .values(updated_at=db.func.utcnow()) ) else: - self.ipaddr = request.remote_addr or u'' - self.user_agent = unicode(request.user_agent.string[:250]) or u'' + self.ipaddr = request.remote_addr or '' + self.user_agent = str(request.user_agent.string[:250]) or '' @cached_property def ua(self): diff --git a/lastuser_core/models/user.py b/lastuser_core/models/user.py index 63cc013..900b901 100644 --- a/lastuser_core/models/user.py +++ b/lastuser_core/models/user.py @@ -212,7 +212,7 @@ class User(SharedNameMixin, UuidMixin, BaseMixin, db.Model): # XXX: Deprecated, still here for Baseframe compatibility userid = db.synonym('buid') #: The user's fullname - fullname = db.Column(db.Unicode(__title_length__), default=u'', nullable=False) + fullname = db.Column(db.Unicode(__title_length__), default='', nullable=False) #: Alias for the user's fullname title = db.synonym('fullname') #: Bcrypt hash of the user's password @@ -352,7 +352,7 @@ def displayname(self): @property def pickername(self): if self.username: - return u'{fullname} (@{username})'.format( + return '{fullname} (@{username})'.format( fullname=self.fullname, username=self.username ) else: @@ -392,7 +392,7 @@ def email(self): # This user has no email address. Return a blank string instead of None # to support the common use case, where the caller will use unicode(user.email) # to get the email address as a string. - return u'' + return '' @cached_property def phone(self): @@ -413,7 +413,7 @@ def phone(self): # This user has no phone number. Return a blank string instead of None # to support the common use case, where the caller will use unicode(user.phone) # to get the phone number as a string. - return u'' + return '' def organizations(self): """ @@ -551,11 +551,11 @@ def autocomplete(cls, query): # Escape the '%' and '_' wildcards in SQL LIKE clauses. # Some SQL dialects respond to '[' and ']', so remove them. query = ( - query.replace(u'%', ur'\%') - .replace(u'_', ur'\_') - .replace(u'[', u'') - .replace(u']', u'') - + u'%' + query.replace('%', r'\%') + .replace('_', r'\_') + .replace('[', '') + .replace(']', '') + + '%' ) # Use User._username since 'username' is a hybrid property that checks for validity # before passing on to _username, the actual column name on the model. @@ -707,9 +707,9 @@ class Organization(SharedNameMixin, UuidMixin, BaseMixin, db.Model): cascade='all', post_update=True, ) # No delete-orphan cascade here - title = db.Column(db.Unicode(__title_length__), default=u'', nullable=False) + title = db.Column(db.Unicode(__title_length__), default='', nullable=False) #: Deprecated, but column preserved for existing data until migration - description = deferred(db.Column(db.UnicodeText, default=u'', nullable=False)) + description = deferred(db.Column(db.UnicodeText, default='', nullable=False)) #: Client id that created this account client_id = db.Column( @@ -749,9 +749,9 @@ def name(cls): # NOQA: N805 def make_teams(self): if self.owners is None: - self.owners = Team(title=_(u"Owners"), org=self) + self.owners = Team(title=_("Owners"), org=self) if self.members is None: - self.members = Team(title=_(u"Members"), org=self) + self.members = Team(title=_("Members"), org=self) def __repr__(self): return ''.format( @@ -761,7 +761,7 @@ def __repr__(self): @property def pickername(self): if self.name: - return u'{title} (@{name})'.format(title=self.title, name=self.name) + return '{title} (@{name})'.format(title=self.title, name=self.name) else: return self.title @@ -956,7 +956,7 @@ def __repr__(self): ) def __unicode__(self): - return unicode(self.email) + return str(self.email) def __str__(self): return str(self.__unicode__()) @@ -1027,7 +1027,7 @@ def __repr__(self): ) def __unicode__(self): - return unicode(self.email) + return str(self.email) def __str__(self): return str(self.__unicode__()) @@ -1096,7 +1096,7 @@ def __repr__(self): ) def __unicode__(self): - return unicode(self.phone) + return str(self.phone) def __str__(self): return str(self.__unicode__()) @@ -1166,7 +1166,7 @@ def __repr__(self): ) def __unicode__(self): - return unicode(self.phone) + return str(self.phone) def __str__(self): return str(self.__unicode__()) diff --git a/lastuser_core/registry.py b/lastuser_core/registry.py index 725bcfe..2b691ec 100644 --- a/lastuser_core/registry.py +++ b/lastuser_core/registry.py @@ -66,24 +66,24 @@ def decorated_function(): else: # Unrecognized Authorization header return resource_auth_error( - _(u"A Bearer token is required in the Authorization header") + _("A Bearer token is required in the Authorization header") ) if 'access_token' in args: return resource_auth_error( - _(u"Access token specified in both header and body") + _("Access token specified in both header and body") ) else: token = args.get('access_token') if not token: # No token provided in Authorization header or in request parameters return resource_auth_error( - _(u"An access token is required to access this resource") + _("An access token is required to access this resource") ) authtoken = AuthToken.get(token=token) if not authtoken: - return resource_auth_error(_(u"Unknown access token")) + return resource_auth_error(_("Unknown access token")) if not authtoken.is_valid(): - return resource_auth_error(_(u"Access token has expired")) + return resource_auth_error(_("Access token has expired")) tokenscope = set( authtoken.effective_scope @@ -96,11 +96,11 @@ def decorated_function(): ): # Client doesn't have access to this scope either directly or via a wildcard return resource_auth_error( - _(u"Token does not provide access to this resource") + _("Token does not provide access to this resource") ) if trusted and not authtoken.client.trusted: return resource_auth_error( - _(u"This resource can only be accessed by trusted clients") + _("This resource can only be accessed by trusted clients") ) # All good. Return the result value try: @@ -112,7 +112,7 @@ def decorated_function(): { 'status': 'error', 'error': exception.__class__.__name__, - 'error_description': unicode(exception), + 'error_description': str(exception), } ) response.status_code = 500 diff --git a/lastuser_core/utils.py b/lastuser_core/utils.py index 16e8ad5..ad4ab4b 100644 --- a/lastuser_core/utils.py +++ b/lastuser_core/utils.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- -from urllib import urlencode as make_query_string +from urllib.parse import urlencode as make_query_string import re -import urlparse +import urllib.parse # --- Constants --------------------------------------------------------------- @@ -13,21 +13,21 @@ def make_redirect_url(url, use_fragment=False, **params): - urlparts = list(urlparse.urlsplit(url)) + urlparts = list(urllib.parse.urlsplit(url)) # URL parts: # 0: scheme # 1: netloc # 2: path # 3: query -- appended to # 4: fragment - queryparts = urlparse.parse_qsl( + queryparts = urllib.parse.parse_qsl( urlparts[4] if use_fragment else urlparts[3], keep_blank_values=True ) - queryparts.extend([(k, v) for k, v in params.items() if v is not None]) + queryparts.extend([(k, v) for k, v in list(params.items()) if v is not None]) queryparts = [ ( - key.encode('utf-8') if isinstance(key, unicode) else key, - value.encode('utf-8') if isinstance(value, unicode) else value, + key.encode('utf-8') if isinstance(key, str) else key, + value.encode('utf-8') if isinstance(value, str) else value, ) for key, value in queryparts ] @@ -35,7 +35,7 @@ def make_redirect_url(url, use_fragment=False, **params): urlparts[4] = make_query_string(queryparts) else: urlparts[3] = make_query_string(queryparts) - return urlparse.urlunsplit(urlparts) + return urllib.parse.urlunsplit(urlparts) def strip_phone(candidate): @@ -55,7 +55,7 @@ def get_gravatar_md5sum(url): ... '://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png') '31b0e7df40a7e327e7908f61a314fe47' """ - parts = urlparse.urlparse(url) + parts = urllib.parse.urlparse(url) if parts.netloc not in ['www.gravatar.com', 'secure.gravatar.com', 'gravatar.com']: return None if not parts.path.startswith('/avatar/'): @@ -76,6 +76,6 @@ def mask_email(email): u'n****' """ if '@' not in email: - return u'{e}****'.format(e=email[0]) + return '{e}****'.format(e=email[0]) username, domain = email.split('@') - return u'{u}****@{d}****'.format(u=username[0], d=domain[0]) + return '{u}****@{d}****'.format(u=username[0], d=domain[0]) diff --git a/lastuser_oauth/forms/login.py b/lastuser_oauth/forms/login.py index 15323f0..05751d4 100644 --- a/lastuser_oauth/forms/login.py +++ b/lastuser_oauth/forms/login.py @@ -67,7 +67,7 @@ def validate_email(self, field): raise forms.ValidationError( Markup( _( - u"This email address is already registered. Do you want to login instead?" + "This email address is already registered. Do you want to login instead?" ).format(loginurl=escape(url_for('.login'))) ) ) diff --git a/lastuser_oauth/forms/profile.py b/lastuser_oauth/forms/profile.py index ee3d71a..2380f34 100644 --- a/lastuser_oauth/forms/profile.py +++ b/lastuser_oauth/forms/profile.py @@ -94,7 +94,7 @@ class ProfileForm(forms.Form): forms.validators.Length(max=Name.__name_length__), ], filters=[forms.filters.none_if_empty()], - prefix=u"https://hasgeek.com/", + prefix="https://hasgeek.com/", widget_attrs={'autocorrect': 'none', 'autocapitalize': 'none'}, ) timezone = forms.SelectField( diff --git a/lastuser_oauth/providers/github.py b/lastuser_oauth/providers/github.py index 612d470..91f81f2 100644 --- a/lastuser_oauth/providers/github.py +++ b/lastuser_oauth/providers/github.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from urllib import quote +from urllib.parse import quote from flask import redirect, request @@ -41,14 +41,14 @@ def do(self, callback_url): def callback(self): if request.args.get('error'): if request.args['error'] == 'user_denied': - raise LoginCallbackError(_(u"You denied the GitHub login request")) + raise LoginCallbackError(_("You denied the GitHub login request")) elif request.args['error'] == 'redirect_uri_mismatch': # TODO: Log this as an exception for the server admin to look at raise LoginCallbackError( - _(u"This server's callback URL is misconfigured") + _("This server's callback URL is misconfigured") ) else: - raise LoginCallbackError(_(u"Unknown failure")) + raise LoginCallbackError(_("Unknown failure")) code = request.args.get('code', None) try: response = requests.post( @@ -73,7 +73,7 @@ def callback(self): except requests.ConnectionError as e: raise LoginCallbackError( _( - u"GitHub appears to be having temporary issues. Please try again. Internal details: {error}" + "GitHub appears to be having temporary issues. Please try again. Internal details: {error}" ).format(error=e) ) diff --git a/lastuser_oauth/providers/google.py b/lastuser_oauth/providers/google.py index 26fbe66..5423ed1 100644 --- a/lastuser_oauth/providers/google.py +++ b/lastuser_oauth/providers/google.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import + from flask import redirect, request, session @@ -39,13 +39,13 @@ def callback(self): callback_url = session.pop('google_callback') else: raise LoginCallbackError( - _(u"Duplicate callback. Did you go back in your browser history?") + _("Duplicate callback. Did you go back in your browser history?") ) if request.args.get('error'): if request.args['error'] == 'access_denied': - raise LoginCallbackError(_(u"You denied the Google login request")) + raise LoginCallbackError(_("You denied the Google login request")) else: - raise LoginCallbackError(_(u"Unknown failure")) + raise LoginCallbackError(_("Unknown failure")) code = request.args.get('code', None) try: credentials = self.flow(callback_url).step2_exchange(code) @@ -62,13 +62,13 @@ def callback(self): except Exception as e: raise LoginCallbackError( _( - u"Unable to authenticate via Google. Internal details: {error}" + "Unable to authenticate via Google. Internal details: {error}" ).format(error=e) ) if response.get('error'): raise LoginCallbackError( - _(u"Unable to login via Google: {error}").format( - error=response['error'].get('message', u'') + _("Unable to login via Google: {error}").format( + error=response['error'].get('message', '') ) ) return { diff --git a/lastuser_oauth/providers/linkedin.py b/lastuser_oauth/providers/linkedin.py index bf8e805..dd2073d 100644 --- a/lastuser_oauth/providers/linkedin.py +++ b/lastuser_oauth/providers/linkedin.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from urllib import quote +from urllib.parse import quote from uuid import uuid4 from flask import redirect, request, session @@ -31,7 +31,7 @@ def __init__( self.secret = secret def do(self, callback_url): - session['linkedin_state'] = unicode(uuid4()) + session['linkedin_state'] = str(uuid4()) session['linkedin_callback'] = callback_url return redirect( self.auth_url.format( @@ -51,14 +51,14 @@ def callback(self): ) if 'error' in request.args: if request.args['error'] == 'access_denied': - raise LoginCallbackError(_(u"You denied the LinkedIn login request")) + raise LoginCallbackError(_("You denied the LinkedIn login request")) elif request.args['error'] == 'redirect_uri_mismatch': # TODO: Log this as an exception for the server admin to look at raise LoginCallbackError( - _(u"This server's callback URL is misconfigured") + _("This server's callback URL is misconfigured") ) else: - raise LoginCallbackError(_(u"Unknown failure")) + raise LoginCallbackError(_("Unknown failure")) code = request.args.get('code', None) try: response = requests.post( @@ -75,7 +75,7 @@ def callback(self): except requests.exceptions.RequestException as e: raise LoginCallbackError( _( - u"Unable to authenticate via LinkedIn. Internal details: {error}" + "Unable to authenticate via LinkedIn. Internal details: {error}" ).format(error=e) ) if 'error' in response: @@ -89,13 +89,13 @@ def callback(self): except requests.exceptions.RequestException as e: raise LoginCallbackError( _( - u"Unable to authenticate via LinkedIn. Internal details: {error}" + "Unable to authenticate via LinkedIn. Internal details: {error}" ).format(error=e) ) if not info.get('id'): raise LoginCallbackError( - _(u"Unable to retrieve user details from LinkedIn. Please try again") + _("Unable to retrieve user details from LinkedIn. Please try again") ) return { diff --git a/lastuser_oauth/providers/openid.py b/lastuser_oauth/providers/openid.py index 80411c9..b6cfed6 100644 --- a/lastuser_oauth/providers/openid.py +++ b/lastuser_oauth/providers/openid.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import + from flask import Markup, session diff --git a/lastuser_oauth/providers/twitter.py b/lastuser_oauth/providers/twitter.py index 01777d3..d9aafad 100644 --- a/lastuser_oauth/providers/twitter.py +++ b/lastuser_oauth/providers/twitter.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from functools import wraps -from httplib import BadStatusLine +from http.client import BadStatusLine from socket import error as socket_error from socket import gaierror from ssl import SSLError @@ -86,7 +86,7 @@ def __init__( def do(self, callback_url): try: return self.twitter.authorize(callback=callback_url) - except (OAuthException, BadStatusLine, SSLError, socket_error, gaierror), e: + except (OAuthException, BadStatusLine, SSLError, socket_error, gaierror) as e: raise LoginInitError(e) except KeyError: # As above, the lack of a Content-Type header in a 404 response breaks Flask-OAuth. Catch it. diff --git a/lastuser_oauth/views/account.py b/lastuser_oauth/views/account.py index 0a800f5..e115053 100644 --- a/lastuser_oauth/views/account.py +++ b/lastuser_oauth/views/account.py @@ -45,8 +45,8 @@ def login_service(service): try: return provider.do(callback_url=callback_url) except (LoginInitError, LoginCallbackError) as e: - msg = _(u"{service} login failed: {error}").format( - service=provider.title, error=unicode(e) + msg = _("{service} login failed: {error}").format( + service=provider.title, error=str(e) ) exception_catchall.send(e, message=msg) flash(msg, category='danger') @@ -64,8 +64,8 @@ def login_service_callback(service): try: userdata = provider.callback() except (LoginInitError, LoginCallbackError) as e: - msg = _(u"{service} login failed: {error}").format( - service=provider.title, error=unicode(e) + msg = _("{service} login failed: {error}").format( + service=provider.title, error=str(e) ) exception_catchall.send(e, message=msg) flash(msg, category='danger') @@ -98,7 +98,7 @@ def get_user_extid(service, userdata): else: # Cross-check with all other instances of the same LoginProvider (if we don't have a user) # This is (for eg) for when we have two Twitter services with different access levels. - for other_service, other_provider in login_registry.items(): + for other_service, other_provider in list(login_registry.items()): if ( other_service != service and other_provider.__class__ == provider.__class__ @@ -201,7 +201,7 @@ def login_service_postcallback(service, userdata): if not current_auth: # If a user isn't already logged in, login now. login_internal(user) flash( - _(u"You have logged in via {service}").format( + _("You have logged in via {service}").format( service=login_registry[service].title ), 'success', diff --git a/lastuser_oauth/views/helpers.py b/lastuser_oauth/views/helpers.py index a109afc..9534cc3 100644 --- a/lastuser_oauth/views/helpers.py +++ b/lastuser_oauth/views/helpers.py @@ -2,8 +2,8 @@ from datetime import timedelta from functools import wraps -from urllib import unquote -from urlparse import urlparse +from urllib.parse import unquote +from urllib.parse import urlparse from flask import Response, current_app, flash, redirect, request, session, url_for import itsdangerous @@ -145,7 +145,7 @@ def requires_login(f): def decorated_function(*args, **kwargs): add_auth_attribute('login_required', True) if not current_auth.is_authenticated: - flash(_(u"You need to be logged in for that page"), 'info') + flash(_("You need to be logged in for that page"), 'info') session['next'] = get_current_url() return redirect(url_for('login')) return f(*args, **kwargs) diff --git a/lastuser_oauth/views/login.py b/lastuser_oauth/views/login.py index 262ded9..1cf5776 100644 --- a/lastuser_oauth/views/login.py +++ b/lastuser_oauth/views/login.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- -from __future__ import print_function + from datetime import timedelta -import urlparse +import urllib.parse from flask import ( Markup, @@ -74,7 +74,7 @@ def login(): loginform = LoginForm() service_forms = {} - for service, provider in login_registry.items(): + for service, provider in list(login_registry.items()): if provider.at_login and provider.form is not None: service_forms[service] = provider.get_form() @@ -96,7 +96,7 @@ def login(): except LoginPasswordResetException: flash( _( - u"Your account does not have a password set. Please enter your username " + "Your account does not have a password set. Please enter your username " "or email address to request a reset code and set a new password" ), category='danger', @@ -143,8 +143,8 @@ def logout_user(): User-initiated logout """ if not request.referrer or ( - urlparse.urlsplit(request.referrer).netloc - != urlparse.urlsplit(request.url).netloc + urllib.parse.urlsplit(request.referrer).netloc + != urllib.parse.urlsplit(request.url).netloc ): # TODO: present a logout form flash( @@ -212,8 +212,8 @@ def logout_session(session): if ( not request.referrer or ( - urlparse.urlsplit(request.referrer).netloc - != urlparse.urlsplit(request.url).netloc + urllib.parse.urlsplit(request.referrer).netloc + != urllib.parse.urlsplit(request.url).netloc ) or (session.user != current_auth.user) ): @@ -260,7 +260,7 @@ def reset(): form = PasswordResetRequestForm() if getbool(request.args.get('expired')): message = _( - u"Your password has expired. Please enter your username " + "Your password has expired. Please enter your username " "or email address to request a reset code and set a new password" ) else: @@ -278,7 +278,7 @@ def reset(): else: # Send to their existing address # User.email is a UserEmail object - email = unicode(user.email) + email = str(user.email) if not email and user.emailclaims: email = user.emailclaims[0].email if not email: @@ -290,7 +290,7 @@ def reset(): title=_("Cannot reset password"), message=Markup( _( - u""" + """ We do not have an email address for your account. However, your account is linked to {service} with the id {username}. You can use that to login. @@ -306,7 +306,7 @@ def reset(): title=_("Cannot reset password"), message=Markup( _( - u""" + """ We do not have an email address for your account and therefore cannot email you a reset link. Please contact {email} for assistance. @@ -321,7 +321,7 @@ def reset(): return render_message( title=_("Reset password"), message=_( - u""" + """ We sent a link to reset your password to your email address: {masked_email}. Please check your email. If it doesn’t arrive in a few minutes, it may have landed in your spam or junk folder. @@ -349,7 +349,7 @@ def reset_email(user, kwargs): if not resetreq: return render_message( title=_("Invalid reset link"), - message=_(u"The reset link you clicked on is invalid"), + message=_("The reset link you clicked on is invalid"), ) if resetreq.created_at < utcnow() - timedelta(days=1): # Reset code has expired (> 24 hours). Delete it @@ -357,7 +357,7 @@ def reset_email(user, kwargs): db.session.commit() return render_message( title=_("Expired reset link"), - message=_(u"The reset link you clicked on has expired"), + message=_("The reset link you clicked on has expired"), ) # Logout *after* validating the reset request to prevent DoS attacks on the user @@ -374,7 +374,7 @@ def reset_email(user, kwargs): title=_("Password reset complete"), message=Markup( _( - u"Your password has been reset. You may now login with your new password." + "Your password has been reset. You may now login with your new password." ).format(loginurl=escape(url_for('.login'))) ), ) @@ -385,7 +385,7 @@ def reset_email(user, kwargs): submit=_("Reset password"), message=Markup( _( - u"Hello, {fullname}. You may now choose a new password." + "Hello, {fullname}. You may now choose a new password." ).format(fullname=escape(user.fullname)) ), ajax=False, diff --git a/lastuser_oauth/views/notify.py b/lastuser_oauth/views/notify.py index 037ffa1..918b1bb 100644 --- a/lastuser_oauth/views/notify.py +++ b/lastuser_oauth/views/notify.py @@ -119,7 +119,7 @@ def notify_org_data_changed(org, user, changes, team=None): continue client_users.setdefault(token.client, []).append(token.user) # Now we have a list of clients to notify and a list of users to notify them with - for client, users in client_users.items(): + for client, users in list(client_users.items()): if user is not None and user in users: notify_user = user else: diff --git a/lastuser_oauth/views/oauth.py b/lastuser_oauth/views/oauth.py index 0056e72..dc5d15c 100644 --- a/lastuser_oauth/views/oauth.py +++ b/lastuser_oauth/views/oauth.py @@ -45,13 +45,13 @@ def verifyscope(scope, client): # The '*' resource (full access) is only available to trusted clients if not client.trusted: raise ScopeException( - _(u"Full access is only available to trusted clients") + _("Full access is only available to trusted clients") ) elif item in resource_registry: if resource_registry[item]['trusted'] and not client.trusted: raise ScopeException( _( - u"The resource {scope} is only available to trusted clients" + "The resource {scope} is only available to trusted clients" ).format(scope=item) ) internal_resources.append(item) @@ -76,13 +76,13 @@ def verifyscope(scope, client): if ':' not in item: raise ScopeException( _( - u"No namespace specified for external resource ‘{scope}’ in scope" + "No namespace specified for external resource ‘{scope}’ in scope" ).format(scope=item) ) itemparts = item.split(':') if len(itemparts) != 2: raise ScopeException( - _(u"Too many ‘:’ characters in ‘{scope}’ in scope").format( + _("Too many ‘:’ characters in ‘{scope}’ in scope").format( scope=item ) ) @@ -91,7 +91,7 @@ def verifyscope(scope, client): parts = subitem.split('/') if len(parts) != 2: raise ScopeException( - _(u"Too many ‘/’ characters in ‘{scope}’ in scope").format( + _("Too many ‘/’ characters in ‘{scope}’ in scope").format( scope=item ) ) @@ -107,12 +107,12 @@ def verifyscope(scope, client): else: raise ScopeException( _( - u"This application does not have access to all resources of app ‘{client}’" + "This application does not have access to all resources of app ‘{client}’" ).format(client=resource_client.title) ) else: raise ScopeException( - _(u"Unknown resource namespace ‘{namespace}’ in scope").format( + _("Unknown resource namespace ‘{namespace}’ in scope").format( namespace=namespace ) ) @@ -123,13 +123,13 @@ def verifyscope(scope, client): if not resource: raise ScopeException( _( - u"Unknown resource ‘{resource}’ under namespace ‘{namespace}’ in scope" + "Unknown resource ‘{resource}’ under namespace ‘{namespace}’ in scope" ).format(resource=resource_name, namespace=namespace) ) if resource.restricted and resource.client.owner != client.owner: raise ScopeException( _( - u"This application does not have access to resource ‘{resource}’ in scope" + "This application does not have access to resource ‘{resource}’ in scope" ).format(resource=resource_name) ) @@ -139,7 +139,7 @@ def verifyscope(scope, client): if not action: raise ScopeException( _( - u"Unknown action ‘{action}’ on resource ‘{resource}’ under namespace ‘{namespace}’" + "Unknown action ‘{action}’ on resource ‘{resource}’ under namespace ‘{namespace}’" ).format( action=action_name, resource=resource_name, @@ -272,7 +272,7 @@ def oauth_authorize(): response_type = request.args.get('response_type') client_id = request.args.get('client_id') redirect_uri = request.args.get('redirect_uri') - scope = request.args.get('scope', u'').split(u' ') + scope = request.args.get('scope', '').split(' ') state = request.args.get('state') # Validation 1.1: Client_id present @@ -301,7 +301,7 @@ def oauth_authorize(): client.redirect_uri, state, 'invalid_request', - _(u"Redirect URI hostname doesn't match"), + _("Redirect URI hostname doesn't match"), ) # Validation 1.4: Client allows login for this user @@ -325,7 +325,7 @@ def oauth_authorize(): client.redirect_uri, state, 'invalid_scope', - _(u"You do not have access to this application"), + _("You do not have access to this application"), ) # Validation 2.1: Is response_type present? @@ -334,7 +334,7 @@ def oauth_authorize(): redirect_uri, state, 'invalid_request', _("response_type missing") ) # Validation 2.2: Is response_type acceptable? - if response_type not in [u'code', u'token']: + if response_type not in ['code', 'token']: return oauth_auth_error(redirect_uri, state, 'unsupported_response_type') # Validation 3.1: Is scope present? @@ -349,7 +349,7 @@ def oauth_authorize(): scope, client ) except ScopeException as scopeex: - return oauth_auth_error(redirect_uri, state, 'invalid_scope', unicode(scopeex)) + return oauth_auth_error(redirect_uri, state, 'invalid_scope', str(scopeex)) # Validations complete. Now ask user for permission # If the client is trusted (Lastuser feature, not in OAuth2 spec), don't ask user. @@ -501,7 +501,7 @@ def oauth_make_token(user, client, scope, user_session=None): def oauth_token_success(token, **params): params['access_token'] = token.token params['token_type'] = token.token_type - params['scope'] = u' '.join(token.effective_scope) + params['scope'] = ' '.join(token.effective_scope) if token.client.trusted: # Trusted client. Send back waiting user messages. for ufm in list(UserFlashMessage.query.filter_by(user=token.user).all()): @@ -531,7 +531,7 @@ def oauth_token(): # Always required parameters grant_type = request.form.get('grant_type') client = current_auth.client # Provided by @requires_client_login - scope = request.form.get('scope', u'').split(u' ') + scope = request.form.get('scope', '').split(' ') # if grant_type == 'authorization_code' (POST) code = request.form.get('code') redirect_uri = request.form.get('redirect_uri') @@ -557,7 +557,7 @@ def oauth_token(): # Confirm the client has access to the scope it wants verifyscope(scope, client) except ScopeException as scopeex: - return oauth_token_error('invalid_scope', unicode(scopeex)) + return oauth_token_error('invalid_scope', str(scopeex)) if buid: if client.trusted: @@ -638,7 +638,7 @@ def oauth_token(): try: verifyscope(scope, client) except ScopeException as scopeex: - return oauth_token_error('invalid_scope', unicode(scopeex)) + return oauth_token_error('invalid_scope', str(scopeex)) # All good. Grant access token = oauth_make_token(user=user, client=client, scope=scope) return oauth_token_success( diff --git a/lastuser_oauth/views/profile.py b/lastuser_oauth/views/profile.py index be6815a..697d4d4 100644 --- a/lastuser_oauth/views/profile.py +++ b/lastuser_oauth/views/profile.py @@ -81,7 +81,7 @@ def account_edit(newprofile=False): submit=_("Continue"), message=Markup( _( - u"Hello, {fullname}. Please spare a minute to fill out your profile" + "Hello, {fullname}. Please spare a minute to fill out your profile" ).format(fullname=escape(current_auth.user.fullname)) ), ajax=True, @@ -118,7 +118,7 @@ def confirm_email(md5sum, secret): title=_("Email address already claimed"), message=Markup( _( - u"The email address {email} has already been verified by another user" + "The email address {email} has already been verified by another user" ).format(email=escape(claimed_email)) ), ) @@ -127,8 +127,8 @@ def confirm_email(md5sum, secret): title=_("Email address already verified"), message=Markup( _( - u"Hello {fullname}! " - u"Your email address {email} has already been verified" + "Hello {fullname}! " + "Your email address {email} has already been verified" ).format( fullname=escape(claimed_user.fullname), email=escape(claimed_email), @@ -153,8 +153,8 @@ def confirm_email(md5sum, secret): title=_("Email address verified"), message=Markup( _( - u"Hello {fullname}! " - u"Your email address {email} has now been verified" + "Hello {fullname}! " + "Your email address {email} has now been verified" ).format( fullname=escape(emailclaim.user.fullname), email=escape(useremail.email), @@ -165,9 +165,9 @@ def confirm_email(md5sum, secret): return render_message( title=_("This was not for you"), message=_( - u"You’ve opened an email verification link that was meant for another user. " - u"If you are managing multiple accounts, please login with the correct account " - u"and open the link again" + "You’ve opened an email verification link that was meant for another user. " + "If you are managing multiple accounts, please login with the correct account " + "and open the link again" ), code=403, ) @@ -175,7 +175,7 @@ def confirm_email(md5sum, secret): return render_message( title=_("Expired confirmation link"), message=_( - u"The confirmation link you clicked on is either invalid or has expired" + "The confirmation link you clicked on is either invalid or has expired" ), code=404, ) diff --git a/lastuser_oauth/views/resource.py b/lastuser_oauth/views/resource.py index a21c901..76d3f1c 100644 --- a/lastuser_oauth/views/resource.py +++ b/lastuser_oauth/views/resource.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from urlparse import urlparse +from urllib.parse import urlparse from flask import abort, jsonify, render_template, request from werkzeug.exceptions import BadRequest @@ -55,9 +55,9 @@ def get_userinfo(user, client, scope=[], session=None, get_permissions=True): userinfo['sessionid'] = session.buid if '*' in scope or 'email' in scope or 'email/*' in scope: - userinfo['email'] = unicode(user.email) + userinfo['email'] = str(user.email) if '*' in scope or 'phone' in scope or 'phone/*' in scope: - userinfo['phone'] = unicode(user.phone) + userinfo['phone'] = str(user.phone) if '*' in scope or 'organizations' in scope or 'organizations/*' in scope: userinfo['organizations'] = { 'owner': [ @@ -129,7 +129,7 @@ def get_userinfo(user, client, scope=[], session=None, get_permissions=True): } if teams: - userinfo['teams'] = teams.values() + userinfo['teams'] = list(teams.values()) if get_permissions: if client.user: @@ -137,7 +137,7 @@ def get_userinfo(user, client, scope=[], session=None, get_permissions=True): user=user, client=client ).first() if perms: - userinfo['permissions'] = perms.access_permissions.split(u' ') + userinfo['permissions'] = perms.access_permissions.split(' ') else: permsset = set() if user.teams: @@ -151,7 +151,7 @@ def get_userinfo(user, client, scope=[], session=None, get_permissions=True): .all() ) for permob in perms: - permsset.update(permob.access_permissions.split(u' ')) + permsset.update(permob.access_permissions.split(' ')) userinfo['permissions'] = sorted(permsset) return userinfo @@ -323,7 +323,7 @@ def sync_resources(): if len(parts) != 2: results[name] = { 'status': 'error', - 'error': _(u"Invalid resource name {name}").format(name=name), + 'error': _("Invalid resource name {name}").format(name=name), } continue resource_name, action_name = parts @@ -352,7 +352,7 @@ def sync_resources(): name=resource_name, title=resources.get(resource_name, {}).get('title') or resource_name.title(), - description=resources.get(resource_name, {}).get('description') or u'', + description=resources.get(resource_name, {}).get('description') or '', ) db.session.add(resource) results[resource.name] = {'status': 'added', 'actions': {}} @@ -394,7 +394,7 @@ def sync_resources(): results[resource_name]['actions'][action.name] = {'status': 'deleted'} actions.delete(synchronize_session='fetch') del_resources = Resource.query.filter( - ~Resource.name.in_(actions_list.keys()), Resource.client == current_auth.client + ~Resource.name.in_(list(actions_list.keys())), Resource.client == current_auth.client ) for resource in del_resources.all(): ResourceAction.query.filter_by(resource=resource).delete( @@ -666,7 +666,7 @@ def login_beacon_json(client_id): @lastuser_oauth.route('/api/1/id') -@resource_registry.resource('id', __(u"Read your name and basic profile data")) +@resource_registry.resource('id', __("Read your name and basic profile data")) def resource_id(authtoken, args, files=None): """ Return user's id @@ -685,7 +685,7 @@ def resource_id(authtoken, args, files=None): @lastuser_oauth.route('/api/1/session/verify', methods=['POST']) -@resource_registry.resource('session/verify', __(u"Verify user session"), scope='id') +@resource_registry.resource('session/verify', __("Verify user session"), scope='id') def session_verify(authtoken, args, files=None): sessionid = args['sessionid'] session = UserSession.authenticate(buid=sessionid) @@ -705,7 +705,7 @@ def session_verify(authtoken, args, files=None): @lastuser_oauth.route('/api/1/avatar/edit', methods=['POST']) -@resource_registry.resource('avatar/edit', __(u"Update your profile picture")) +@resource_registry.resource('avatar/edit', __("Update your profile picture")) def resource_avatar_edit(authtoken, args, files=None): """ Set a user's avatar image @@ -722,24 +722,24 @@ def resource_avatar_edit(authtoken, args, files=None): @lastuser_oauth.route('/api/1/email') -@resource_registry.resource('email', __(u"Read your email address")) +@resource_registry.resource('email', __("Read your email address")) def resource_email(authtoken, args, files=None): """ Return user's email addresses. """ if 'all' in args and getbool(args['all']): return { - 'email': unicode(authtoken.user.email), + 'email': str(authtoken.user.email), 'all': [ - unicode(email) for email in authtoken.user.emails if not email.private + str(email) for email in authtoken.user.emails if not email.private ], } else: - return {'email': unicode(authtoken.user.email)} + return {'email': str(authtoken.user.email)} @lastuser_oauth.route('/api/1/email/add', methods=['POST']) -@resource_registry.resource('email/add', __(u"Add an email address to your profile")) +@resource_registry.resource('email/add', __("Add an email address to your profile")) def resource_email_add(authtoken, args, files=None): """ TODO: Add an email address to the user's profile. @@ -749,24 +749,24 @@ def resource_email_add(authtoken, args, files=None): @lastuser_oauth.route('/api/1/phone') -@resource_registry.resource('phone', __(u"Read your phone number")) +@resource_registry.resource('phone', __("Read your phone number")) def resource_phone(authtoken, args, files=None): """ Return user's phone numbers. """ if 'all' in args and getbool(args['all']): return { - 'phone': unicode(authtoken.user.phone), - 'all': [unicode(phone) for phone in authtoken.user.phones], + 'phone': str(authtoken.user.phone), + 'all': [str(phone) for phone in authtoken.user.phones], } else: - return {'phone': unicode(authtoken.user.phone)} + return {'phone': str(authtoken.user.phone)} @lastuser_oauth.route('/api/1/user/externalids') @resource_registry.resource( 'user/externalids', - __(u"Access your external account information such as Twitter and Google"), + __("Access your external account information such as Twitter and Google"), trusted=True, ) def resource_login_providers(authtoken, args, files=None): @@ -778,17 +778,17 @@ def resource_login_providers(authtoken, args, files=None): for extid in authtoken.user.externalids: if service is None or extid.service == service: response[extid.service] = { - 'userid': unicode(extid.userid), - 'username': unicode(extid.username), - 'oauth_token': unicode(extid.oauth_token), - 'oauth_token_secret': unicode(extid.oauth_token_secret), - 'oauth_token_type': unicode(extid.oauth_token_type), + 'userid': str(extid.userid), + 'username': str(extid.username), + 'oauth_token': str(extid.oauth_token), + 'oauth_token_secret': str(extid.oauth_token_secret), + 'oauth_token_type': str(extid.oauth_token_type), } return response @lastuser_oauth.route('/api/1/user/new', methods=['POST']) -@resource_registry.resource('user/new', __(u"Create a new user account"), trusted=True) +@resource_registry.resource('user/new', __("Create a new user account"), trusted=True) def resource_user_new(authtoken, args, files=None): # Set User.client to authtoken.client and User.referrer to authtoken.user pass @@ -796,7 +796,7 @@ def resource_user_new(authtoken, args, files=None): @lastuser_oauth.route('/api/1/organizations') @resource_registry.resource( - 'organizations', __(u"Read the organizations you are a member of") + 'organizations', __("Read the organizations you are a member of") ) def resource_organizations(authtoken, args, files=None): """ @@ -809,7 +809,7 @@ def resource_organizations(authtoken, args, files=None): @lastuser_oauth.route('/api/1/organizations/new', methods=['POST']) @resource_registry.resource( - 'organizations/new', __(u"Create a new organization"), trusted=True + 'organizations/new', __("Create a new organization"), trusted=True ) def resource_organizations_new(authtoken, args, files=None): pass @@ -817,7 +817,7 @@ def resource_organizations_new(authtoken, args, files=None): @lastuser_oauth.route('/api/1/organizations/edit', methods=['POST']) @resource_registry.resource( - 'organizations/edit', __(u"Edit your organizations"), trusted=True + 'organizations/edit', __("Edit your organizations"), trusted=True ) def resource_organizations_edit(authtoken, args, files=None): pass @@ -825,7 +825,7 @@ def resource_organizations_edit(authtoken, args, files=None): @lastuser_oauth.route('/api/1/teams') @resource_registry.resource( - 'teams', __(u"Read the list of teams in your organizations") + 'teams', __("Read the list of teams in your organizations") ) def resource_teams(authtoken, args, files=None): """ @@ -838,7 +838,7 @@ def resource_teams(authtoken, args, files=None): @lastuser_oauth.route('/api/1/teams/new', methods=['POST']) @resource_registry.resource( - 'teams/new', __(u"Create a new team in your organizations"), trusted=True + 'teams/new', __("Create a new team in your organizations"), trusted=True ) def resource_teams_new(authtoken, args, files=None): pass @@ -847,13 +847,13 @@ def resource_teams_new(authtoken, args, files=None): # GET to read member list, POST to write to it @lastuser_oauth.route('/api/1/teams/edit', methods=['GET', 'POST']) @resource_registry.resource( - 'teams/edit', __(u"Edit your organizations' teams"), trusted=True + 'teams/edit', __("Edit your organizations' teams"), trusted=True ) def resource_teams_edit(authtoken, args, files=None): pass @lastuser_oauth.route('/api/1/notice/send') -@resource_registry.resource('notice/send', __(u"Send you notifications")) +@resource_registry.resource('notice/send', __("Send you notifications")) def resource_notice_send(authtoken, args, files=None): pass diff --git a/lastuser_ui/forms/client.py b/lastuser_ui/forms/client.py index 3b7e927..ae5fc93 100644 --- a/lastuser_ui/forms/client.py +++ b/lastuser_ui/forms/client.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from urlparse import urlparse +from urllib.parse import urlparse from flask import Markup, url_for @@ -86,9 +86,9 @@ class RegisterClientForm(forms.Form): filters=[forms.filters.none_if_empty()], description=Markup( __( - u"A dot-based namespace that uniquely identifies your client application. " - u"For example, if your client website is https://auth.hasgeek.com, " - u"use com.hasgeek.auth. Only required if your client app provides resources" + "A dot-based namespace that uniquely identifies your client application. " + "For example, if your client website is https://auth.hasgeek.com, " + "use com.hasgeek.auth. Only required if your client app provides resources" ) ), widget_attrs={'autocorrect': 'none', 'autocapitalize': 'none'}, @@ -101,8 +101,8 @@ class RegisterClientForm(forms.Form): ], filters=[forms.strip_each()], description=__( - u"OAuth2 Redirect URL. If your app is available on multiple hostnames, " - u"list each redirect URL on a separate line" + "OAuth2 Redirect URL. If your app is available on multiple hostnames, " + "list each redirect URL on a separate line" ), ) notification_uri = forms.URLField( @@ -188,7 +188,7 @@ def validate_namespace(self, field): if not domain_namespace_match(self.website.data, field.data): raise forms.ValidationError( _( - u"The namespace should be derived from your application’s website domain" + "The namespace should be derived from your application’s website domain" ) ) client = self.edit_model.get(namespace=field.data) @@ -206,7 +206,7 @@ class ClientCredentialForm(forms.Form): """ title = forms.StringField( - __(u"What’s this for?"), + __("What’s this for?"), validators=[forms.validators.DataRequired(), forms.validators.Length(max=250)], description=__( "Add a description to help yourself remember why this was generated" diff --git a/lastuser_ui/forms/org.py b/lastuser_ui/forms/org.py index bf8ebff..d33d42e 100644 --- a/lastuser_ui/forms/org.py +++ b/lastuser_ui/forms/org.py @@ -24,7 +24,7 @@ class OrganizationForm(forms.Form): forms.validators.DataRequired(), forms.validators.Length(max=Name.__name_length__), ], - prefix=u"https://hasgeek.com/", + prefix="https://hasgeek.com/", widget_attrs={'autocorrect': 'none', 'autocapitalize': 'none'}, ) @@ -52,9 +52,9 @@ def validate_name(self, field): raise forms.ValidationError( Markup( _( - u"This is your current username. " - u'You must change it first from your account ' - u"before you can assign it to an organization" + "This is your current username. " + 'You must change it first from your account ' + "before you can assign it to an organization" ).format(account=url_for('account')) ) ) diff --git a/lastuser_ui/forms/profile.py b/lastuser_ui/forms/profile.py index 1361d79..b19b4ee 100644 --- a/lastuser_ui/forms/profile.py +++ b/lastuser_ui/forms/profile.py @@ -28,9 +28,9 @@ class NewEmailAddressForm(forms.RecaptchaForm): coerce=nullstr, validators=[forms.validators.Optional()], choices=[ - (__(u"Home"), __(u"Home")), - (__(u"Work"), __(u"Work")), - (__(u"Other"), __(u"Other")), + (__("Home"), __("Home")), + (__("Work"), __("Work")), + (__("Other"), __("Other")), ], ) diff --git a/lastuser_ui/views/client.py b/lastuser_ui/views/client.py index f61f8bb..b5e43fb 100644 --- a/lastuser_ui/views/client.py +++ b/lastuser_ui/views/client.py @@ -143,7 +143,7 @@ def client_edit(client): db.session.delete(perm) flash( _( - u"This application’s owner has changed, so all previously assigned permissions " + "This application’s owner has changed, so all previously assigned permissions " "have been revoked" ), 'warning', @@ -174,10 +174,10 @@ def client_delete(client): return render_delete_sqla( client, db, - title=_(u"Confirm delete"), - message=_(u"Delete application ‘{title}’? ").format(title=client.title), + title=_("Confirm delete"), + message=_("Delete application ‘{title}’? ").format(title=client.title), success=_( - u"You have deleted application ‘{title}’ and all its associated resources and permission assignments" + "You have deleted application ‘{title}’ and all its associated resources and permission assignments" ).format(title=client.title), next=url_for('.client_list'), ) @@ -220,9 +220,9 @@ def client_cred_delete(client, cred): return render_delete_sqla( cred, db, - title=_(u"Confirm delete"), - message=_(u"Delete access key ‘{title}’? ").format(title=cred.title), - success=_(u"You have deleted access key ‘{title}’").format(title=cred.title), + title=_("Confirm delete"), + message=_("Delete access key ‘{title}’? ").format(title=cred.title), + success=_("You have deleted access key ‘{title}’").format(title=cred.title), next=url_for('.client_info', key=client.key), ) @@ -311,8 +311,8 @@ def permission_delete(perm): return render_delete_sqla( perm, db, - title=_(u"Confirm delete"), - message=_(u"Delete permission ‘{name}’?").format(name=perm.name), + title=_("Confirm delete"), + message=_("Delete permission ‘{name}’?").format(name=perm.name), success=_("Your permission has been deleted"), next=url_for('.permission_list'), ) @@ -350,7 +350,7 @@ def permission_user_new(client): else: abort(403) # This should never happen. Clients always have an owner. form.perms.choices = [ - (ap.name, _(u"{name} – {title}").format(name=ap.name, title=ap.title)) + (ap.name, _("{name} – {title}").format(name=ap.name, title=ap.title)) for ap in available_perms ] if form.validate_on_submit(): @@ -360,7 +360,7 @@ def permission_user_new(client): user=form.user.data, client=client ).first() if permassign: - perms.update(permassign.access_permissions.split(u' ')) + perms.update(permassign.access_permissions.split(' ')) else: permassign = UserClientPermissions(user=form.user.data, client=client) db.session.add(permassign) @@ -369,23 +369,23 @@ def permission_user_new(client): team=form.team, client=client ).first() if permassign: - perms.update(permassign.access_permissions.split(u' ')) + perms.update(permassign.access_permissions.split(' ')) else: permassign = TeamClientPermissions(team=form.team, client=client) db.session.add(permassign) perms.update(form.perms.data) - permassign.access_permissions = u' '.join(sorted(perms)) + permassign.access_permissions = ' '.join(sorted(perms)) db.session.commit() if client.user: flash( - _(u"Permissions have been assigned to user {pname}").format( + _("Permissions have been assigned to user {pname}").format( pname=form.user.data.pickername ), 'success', ) else: flash( - _(u"Permissions have been assigned to team ‘{pname}’").format( + _("Permissions have been assigned to team ‘{pname}’").format( pname=permassign.team.pickername ), 'success', @@ -437,15 +437,15 @@ def permission_user_edit(client, kwargs): ).first_or_404() form = PermissionEditForm() form.perms.choices = [ - (ap.name, _(u"{name} – {title}").format(name=ap.name, title=ap.title)) + (ap.name, _("{name} – {title}").format(name=ap.name, title=ap.title)) for ap in available_perms ] if request.method == 'GET': if permassign: - form.perms.data = permassign.access_permissions.split(u' ') + form.perms.data = permassign.access_permissions.split(' ') if form.validate_on_submit(): form.perms.data.sort() - perms = u' '.join(form.perms.data) + perms = ' '.join(form.perms.data) if not perms: db.session.delete(permassign) else: @@ -454,14 +454,14 @@ def permission_user_edit(client, kwargs): if perms: if client.user: flash( - _(u"Permissions have been updated for user {pname}").format( + _("Permissions have been updated for user {pname}").format( pname=user.pickername ), 'success', ) else: flash( - _(u"Permissions have been updated for team {title}").format( + _("Permissions have been updated for team {title}").format( title=team.title ), 'success', @@ -469,14 +469,14 @@ def permission_user_edit(client, kwargs): else: if client.user: flash( - _(u"All permissions have been revoked for user {pname}").format( + _("All permissions have been revoked for user {pname}").format( pname=user.pickername ), 'success', ) else: flash( - _(u"All permissions have been revoked for team {title}").format( + _("All permissions have been revoked for team {title}").format( title=team.title ), 'success', @@ -507,11 +507,11 @@ def permission_user_delete(client, kwargs): return render_delete_sqla( permassign, db, - title=_(u"Confirm delete"), + title=_("Confirm delete"), message=_( - u"Remove all permissions assigned to user {pname} for app ‘{title}’?" + "Remove all permissions assigned to user {pname} for app ‘{title}’?" ).format(pname=user.pickername, title=client.title), - success=_(u"You have revoked permisions for user {pname}").format( + success=_("You have revoked permisions for user {pname}").format( pname=user.pickername ), next=url_for('.client_info', key=client.key), @@ -526,11 +526,11 @@ def permission_user_delete(client, kwargs): return render_delete_sqla( permassign, db, - title=_(u"Confirm delete"), + title=_("Confirm delete"), message=_( - u"Remove all permissions assigned to team ‘{pname}’ for app ‘{title}’?" + "Remove all permissions assigned to team ‘{pname}’ for app ‘{title}’?" ).format(pname=team.title, title=client.title), - success=_(u"You have revoked permisions for team {title}").format( + success=_("You have revoked permisions for team {title}").format( title=team.title ), next=url_for('.client_info', key=client.key), @@ -598,11 +598,11 @@ def resource_delete(client, resource): return render_delete_sqla( resource, db, - title=_(u"Confirm delete"), - message=_(u"Delete resource ‘{resource}’ from app ‘{client}’?").format( + title=_("Confirm delete"), + message=_("Delete resource ‘{resource}’ from app ‘{client}’?").format( resource=resource.title, client=client.title ), - success=_(u"You have deleted resource ‘{resource}’ on app ‘{client}’").format( + success=_("You have deleted resource ‘{resource}’ on app ‘{client}’").format( resource=resource.title, client=client.title ), next=url_for('.client_info', key=client.key), @@ -684,10 +684,10 @@ def resource_action_delete(client, resource, action): db, title=_("Confirm delete"), message=_( - u"Delete action ‘{action}’ from resource ‘{resource}’ of app ‘{client}’?" + "Delete action ‘{action}’ from resource ‘{resource}’ of app ‘{client}’?" ).format(action=action.title, resource=resource.title, client=client.title), success=_( - u"You have deleted action ‘{action}’ on resource ‘{resource}’ of app ‘{client}’" + "You have deleted action ‘{action}’ on resource ‘{resource}’ of app ‘{client}’" ).format(action=action.title, resource=resource.title, client=client.title), next=url_for('.client_info', key=client.key), ) diff --git a/lastuser_ui/views/dashboard.py b/lastuser_ui/views/dashboard.py index 03fa5bd..ae298ac 100644 --- a/lastuser_ui/views/dashboard.py +++ b/lastuser_ui/views/dashboard.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from collections import defaultdict -from cStringIO import StringIO +from io import StringIO from functools import wraps from flask import abort, current_app, render_template @@ -116,7 +116,7 @@ def dashboard_data_users_by_client(): ) users_by_client = sorted( - client_users.values(), key=lambda r: sum(r['counts'].values()), reverse=True + list(client_users.values()), key=lambda r: sum(r['counts'].values()), reverse=True ) outfile = StringIO() diff --git a/lastuser_ui/views/org.py b/lastuser_ui/views/org.py index 9f050b8..b8e0fd5 100644 --- a/lastuser_ui/views/org.py +++ b/lastuser_ui/views/org.py @@ -94,10 +94,10 @@ def delete(self): return render_delete_sqla( self.obj, db, - title=_(u"Confirm delete"), - message=_(u"Delete organization ‘{title}’? ").format(title=self.obj.title), + title=_("Confirm delete"), + message=_("Delete organization ‘{title}’? ").format(title=self.obj.title), success=_( - u"You have deleted organization ‘{title}’ and all its associated teams" + "You have deleted organization ‘{title}’ and all its associated teams" ).format(title=self.obj.title), next=url_for('.OrgView_index'), ) @@ -121,7 +121,7 @@ def new_team(self): return render_redirect(self.obj.url_for('view'), code=303) return render_form( form=form, - title=_(u"Create new team"), + title=_("Create new team"), formid='new_team', submit=_("Create"), ) @@ -156,7 +156,7 @@ def edit(self): return render_redirect(self.obj.org.url_for(), code=303) return render_form( form=form, - title=_(u"Edit team: {title}").format(title=self.obj.title), + title=_("Edit team: {title}").format(title=self.obj.title), formid='team_edit', submit=_("Save"), ajax=False, @@ -172,10 +172,10 @@ def delete(self): return render_delete_sqla( self.obj, db, - title=_(u"Confirm delete"), - message=_(u"Delete team {title}?").format(title=self.obj.title), + title=_("Confirm delete"), + message=_("Delete team {title}?").format(title=self.obj.title), success=_( - u"You have deleted team ‘{team}’ from organization ‘{org}’" + "You have deleted team ‘{team}’ from organization ‘{org}’" ).format(team=self.obj.title, org=self.obj.org.title), next=self.obj.org.url_for(), ) diff --git a/lastuser_ui/views/profile.py b/lastuser_ui/views/profile.py index fad1b70..e30b191 100644 --- a/lastuser_ui/views/profile.py +++ b/lastuser_ui/views/profile.py @@ -48,7 +48,7 @@ def account(): primary_email_form = EmailPrimaryForm() primary_phone_form = PhonePrimaryForm() service_forms = {} - for service, provider in login_registry.items(): + for service, provider in list(login_registry.items()): if provider.at_login and provider.form is not None: service_forms[service] = provider.get_form() return render_template( @@ -126,7 +126,7 @@ def make_email_primary(): user_data_changed.send( current_auth.user, changes=['email-update-primary'] ) - flash(_(u"Your primary email address has been updated"), 'success') + flash(_("Your primary email address has been updated"), 'success') else: flash(_("No such email address is linked to this user account"), 'danger') else: @@ -151,7 +151,7 @@ def make_phone_primary(): user_data_changed.send( current_auth.user, changes=['phone-update-primary'] ) - flash(_(u"Your primary phone number has been updated"), 'success') + flash(_("Your primary phone number has been updated"), 'success') else: flash(_("No such phone number is linked to this user account"), 'danger') else: @@ -176,15 +176,15 @@ def remove_email(md5sum): return render_delete_sqla( useremail, db, - title=_(u"Confirm removal"), - message=_(u"Remove email address {email} from your account?").format( + title=_("Confirm removal"), + message=_("Remove email address {email} from your account?").format( email=useremail.email ), - success=_(u"You have removed your email address {email}").format( + success=_("You have removed your email address {email}").format( email=useremail.email ), next=url_for('.account'), - delete_text=_(u"Remove"), + delete_text=_("Remove"), ) @@ -208,7 +208,7 @@ def verify_email(md5sum): verify_form = VerifyEmailForm() if verify_form.validate_on_submit(): send_email_verify_link(emailclaim) - flash(_(u"The verification email has been sent to this address"), 'success') + flash(_("The verification email has been sent to this address"), 'success') return render_redirect(url_for('.account'), code=303) return render_form( form=verify_form, @@ -243,7 +243,7 @@ def add_phone(): ) except ValueError as e: db.session.rollback() - form.phone.errors.append(unicode(e)) + form.phone.errors.append(str(e)) return render_form( form=form, title=_("Add a phone number"), @@ -278,15 +278,15 @@ def remove_phone(number): return render_delete_sqla( userphone, db, - title=_(u"Confirm removal"), - message=_(u"Remove phone number {phone} from your account?").format( + title=_("Confirm removal"), + message=_("Remove phone number {phone} from your account?").format( phone=userphone.phone ), - success=_(u"You have removed your number {phone}").format( + success=_("You have removed your number {phone}").format( phone=userphone.phone ), next=url_for('.account'), - delete_text=_(u"Remove"), + delete_text=_("Remove"), ) @@ -362,13 +362,13 @@ def remove_extid(extid): return render_delete_sqla( extid, db, - title=_(u"Confirm removal"), - message=_(u"Remove {service} account ‘{username}’ from your account?").format( + title=_("Confirm removal"), + message=_("Remove {service} account ‘{username}’ from your account?").format( service=login_registry[extid.service].title, username=extid.username ), - success=_(u"You have removed the {service} account ‘{username}’").format( + success=_("You have removed the {service} account ‘{username}’").format( service=login_registry[extid.service].title, username=extid.username ), next=url_for('.account'), - delete_text=_(u"Remove"), + delete_text=_("Remove"), ) diff --git a/migrations/env.py b/migrations/env.py index 89e0198..a3519b6 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from __future__ import with_statement + from logging.config import fileConfig import logging diff --git a/migrations/versions/4d2baa5b1c46_user_password_and_client_credentials.py b/migrations/versions/4d2baa5b1c46_user_password_and_client_credentials.py index 5189e27..4175a1b 100644 --- a/migrations/versions/4d2baa5b1c46_user_password_and_client_credentials.py +++ b/migrations/versions/4d2baa5b1c46_user_password_and_client_credentials.py @@ -30,11 +30,11 @@ def upgrade(): sa.PrimaryKeyConstraint('id'), sa.UniqueConstraint('name'), ) - op.add_column(u'user', sa.Column('pw_expires_at', sa.DateTime(), nullable=True)) - op.add_column(u'user', sa.Column('pw_set_at', sa.DateTime(), nullable=True)) + op.add_column('user', sa.Column('pw_expires_at', sa.DateTime(), nullable=True)) + op.add_column('user', sa.Column('pw_set_at', sa.DateTime(), nullable=True)) def downgrade(): - op.drop_column(u'user', 'pw_set_at') - op.drop_column(u'user', 'pw_expires_at') + op.drop_column('user', 'pw_set_at') + op.drop_column('user', 'pw_expires_at') op.drop_table('client_credential') diff --git a/migrations/versions/4e206c5ddabd_uuid_userid.py b/migrations/versions/4e206c5ddabd_uuid_userid.py index 23760c5..abcabdc 100644 --- a/migrations/versions/4e206c5ddabd_uuid_userid.py +++ b/migrations/versions/4e206c5ddabd_uuid_userid.py @@ -97,7 +97,7 @@ def upgrade(): progress.update(counter) progress.finish() - op.drop_constraint(u'organization_userid_key', 'organization', type_='unique') + op.drop_constraint('organization_userid_key', 'organization', type_='unique') op.drop_column('organization', 'userid') # Upgrade Team @@ -114,7 +114,7 @@ def upgrade(): progress.update(counter) progress.finish() - op.drop_constraint(u'team_userid_key', 'team', type_='unique') + op.drop_constraint('team_userid_key', 'team', type_='unique') op.drop_column('team', 'userid') # Upgrade User @@ -131,7 +131,7 @@ def upgrade(): progress.update(counter) progress.finish() - op.drop_constraint(u'user_userid_key', 'user', type_='unique') + op.drop_constraint('user_userid_key', 'user', type_='unique') op.drop_column('user', 'userid') # Upgrade UserOldId diff --git a/migrations/versions/518321b25909_username_model.py b/migrations/versions/518321b25909_username_model.py index 23961ae..d7fb65d 100644 --- a/migrations/versions/518321b25909_username_model.py +++ b/migrations/versions/518321b25909_username_model.py @@ -28,7 +28,7 @@ def upgrade(): sa.Column('reserved', sa.Boolean(), nullable=False), sa.Column('id', UUIDType(binary=False), nullable=False), sa.CheckConstraint( - u'CASE WHEN (user_id IS NOT NULL) THEN 1 ELSE 0 END + CASE WHEN (org_id IS NOT NULL) THEN 1 ELSE 0 END + CASE WHEN (reserved = true) THEN 1 ELSE 0 END = 1', + 'CASE WHEN (user_id IS NOT NULL) THEN 1 ELSE 0 END + CASE WHEN (org_id IS NOT NULL) THEN 1 ELSE 0 END + CASE WHEN (reserved = true) THEN 1 ELSE 0 END = 1', name='username_owner_check', ), sa.ForeignKeyConstraint(['org_id'], ['organization.id'], ondelete='CASCADE'), @@ -68,25 +68,25 @@ def upgrade(): ) ) - op.drop_constraint(u'organization_name_key', 'organization', type_='unique') - op.drop_column(u'organization', 'name') - op.drop_constraint(u'user_username_key', 'user', type_='unique') - op.drop_column(u'user', 'username') + op.drop_constraint('organization_name_key', 'organization', type_='unique') + op.drop_column('organization', 'name') + op.drop_constraint('user_username_key', 'user', type_='unique') + op.drop_column('user', 'username') def downgrade(): op.add_column( - u'user', + 'user', sa.Column( 'username', sa.VARCHAR(length=80), autoincrement=False, nullable=True ), ) - op.create_unique_constraint(u'user_username_key', 'user', ['username']) + op.create_unique_constraint('user_username_key', 'user', ['username']) op.add_column( - u'organization', + 'organization', sa.Column('name', sa.VARCHAR(length=80), autoincrement=False, nullable=True), ) - op.create_unique_constraint(u'organization_name_key', 'organization', ['name']) + op.create_unique_constraint('organization_name_key', 'organization', ['name']) op.drop_index(op.f('ix_name_name_lower'), table_name='name') op.execute( diff --git a/migrations/versions/c446b9bc0691_remove_org_and_team_ownership_of_email_.py b/migrations/versions/c446b9bc0691_remove_org_and_team_ownership_of_email_.py index a10ecbe..554cc44 100644 --- a/migrations/versions/c446b9bc0691_remove_org_and_team_ownership_of_email_.py +++ b/migrations/versions/c446b9bc0691_remove_org_and_team_ownership_of_email_.py @@ -19,8 +19,8 @@ def upgrade(): op.alter_column('useremail', 'user_id', existing_type=sa.INTEGER(), nullable=False) - op.drop_constraint(u'useremail_team_id_fkey', 'useremail', type_='foreignkey') - op.drop_constraint(u'useremail_org_id_fkey', 'useremail', type_='foreignkey') + op.drop_constraint('useremail_team_id_fkey', 'useremail', type_='foreignkey') + op.drop_constraint('useremail_org_id_fkey', 'useremail', type_='foreignkey') op.drop_column('useremail', 'team_id') op.drop_column('useremail', 'org_id') @@ -28,23 +28,23 @@ def upgrade(): 'useremailclaim', 'user_id', existing_type=sa.INTEGER(), nullable=False ) op.drop_constraint( - u'useremailclaim_org_id_email_key', 'useremailclaim', type_='unique' + 'useremailclaim_org_id_email_key', 'useremailclaim', type_='unique' ) op.drop_constraint( - u'useremailclaim_team_id_email_key', 'useremailclaim', type_='unique' + 'useremailclaim_team_id_email_key', 'useremailclaim', type_='unique' ) op.drop_constraint( - u'useremailclaim_team_id_fkey', 'useremailclaim', type_='foreignkey' + 'useremailclaim_team_id_fkey', 'useremailclaim', type_='foreignkey' ) op.drop_constraint( - u'useremailclaim_org_id_fkey', 'useremailclaim', type_='foreignkey' + 'useremailclaim_org_id_fkey', 'useremailclaim', type_='foreignkey' ) op.drop_column('useremailclaim', 'team_id') op.drop_column('useremailclaim', 'org_id') op.alter_column('userphone', 'user_id', existing_type=sa.INTEGER(), nullable=False) - op.drop_constraint(u'userphone_org_id_fkey', 'userphone', type_='foreignkey') - op.drop_constraint(u'userphone_team_id_fkey', 'userphone', type_='foreignkey') + op.drop_constraint('userphone_org_id_fkey', 'userphone', type_='foreignkey') + op.drop_constraint('userphone_team_id_fkey', 'userphone', type_='foreignkey') op.drop_column('userphone', 'team_id') op.drop_column('userphone', 'org_id') @@ -52,16 +52,16 @@ def upgrade(): 'userphoneclaim', 'user_id', existing_type=sa.INTEGER(), nullable=False ) op.drop_constraint( - u'userphoneclaim_org_id_phone_key', 'userphoneclaim', type_='unique' + 'userphoneclaim_org_id_phone_key', 'userphoneclaim', type_='unique' ) op.drop_constraint( - u'userphoneclaim_team_id_phone_key', 'userphoneclaim', type_='unique' + 'userphoneclaim_team_id_phone_key', 'userphoneclaim', type_='unique' ) op.drop_constraint( - u'userphoneclaim_team_id_fkey', 'userphoneclaim', type_='foreignkey' + 'userphoneclaim_team_id_fkey', 'userphoneclaim', type_='foreignkey' ) op.drop_constraint( - u'userphoneclaim_org_id_fkey', 'userphoneclaim', type_='foreignkey' + 'userphoneclaim_org_id_fkey', 'userphoneclaim', type_='foreignkey' ) op.drop_column('userphoneclaim', 'team_id') op.drop_column('userphoneclaim', 'org_id') @@ -77,20 +77,20 @@ def downgrade(): sa.Column('team_id', sa.INTEGER(), autoincrement=False, nullable=True), ) op.create_foreign_key( - u'userphoneclaim_org_id_fkey', + 'userphoneclaim_org_id_fkey', 'userphoneclaim', 'organization', ['org_id'], ['id'], ) op.create_foreign_key( - u'userphoneclaim_team_id_fkey', 'userphoneclaim', 'team', ['team_id'], ['id'] + 'userphoneclaim_team_id_fkey', 'userphoneclaim', 'team', ['team_id'], ['id'] ) op.create_unique_constraint( - u'userphoneclaim_team_id_phone_key', 'userphoneclaim', ['team_id', 'phone'] + 'userphoneclaim_team_id_phone_key', 'userphoneclaim', ['team_id', 'phone'] ) op.create_unique_constraint( - u'userphoneclaim_org_id_phone_key', 'userphoneclaim', ['org_id', 'phone'] + 'userphoneclaim_org_id_phone_key', 'userphoneclaim', ['org_id', 'phone'] ) op.alter_column( 'userphoneclaim', 'user_id', existing_type=sa.INTEGER(), nullable=True @@ -113,10 +113,10 @@ def downgrade(): sa.Column('team_id', sa.INTEGER(), autoincrement=False, nullable=True), ) op.create_foreign_key( - u'userphone_team_id_fkey', 'userphone', 'team', ['team_id'], ['id'] + 'userphone_team_id_fkey', 'userphone', 'team', ['team_id'], ['id'] ) op.create_foreign_key( - u'userphone_org_id_fkey', 'userphone', 'organization', ['org_id'], ['id'] + 'userphone_org_id_fkey', 'userphone', 'organization', ['org_id'], ['id'] ) op.alter_column('userphone', 'user_id', existing_type=sa.INTEGER(), nullable=True) op.create_check_constraint( @@ -137,20 +137,20 @@ def downgrade(): sa.Column('team_id', sa.INTEGER(), autoincrement=False, nullable=True), ) op.create_foreign_key( - u'useremailclaim_org_id_fkey', + 'useremailclaim_org_id_fkey', 'useremailclaim', 'organization', ['org_id'], ['id'], ) op.create_foreign_key( - u'useremailclaim_team_id_fkey', 'useremailclaim', 'team', ['team_id'], ['id'] + 'useremailclaim_team_id_fkey', 'useremailclaim', 'team', ['team_id'], ['id'] ) op.create_unique_constraint( - u'useremailclaim_team_id_email_key', 'useremailclaim', ['team_id', 'email'] + 'useremailclaim_team_id_email_key', 'useremailclaim', ['team_id', 'email'] ) op.create_unique_constraint( - u'useremailclaim_org_id_email_key', 'useremailclaim', ['org_id', 'email'] + 'useremailclaim_org_id_email_key', 'useremailclaim', ['org_id', 'email'] ) op.alter_column( 'useremailclaim', 'user_id', existing_type=sa.INTEGER(), nullable=True @@ -173,10 +173,10 @@ def downgrade(): sa.Column('team_id', sa.INTEGER(), autoincrement=False, nullable=True), ) op.create_foreign_key( - u'useremail_org_id_fkey', 'useremail', 'organization', ['org_id'], ['id'] + 'useremail_org_id_fkey', 'useremail', 'organization', ['org_id'], ['id'] ) op.create_foreign_key( - u'useremail_team_id_fkey', 'useremail', 'team', ['team_id'], ['id'] + 'useremail_team_id_fkey', 'useremail', 'team', ['team_id'], ['id'] ) op.alter_column('useremail', 'user_id', existing_type=sa.INTEGER(), nullable=True) op.create_check_constraint( diff --git a/rqinit.py b/rqinit.py index a0c3534..8a75caf 100644 --- a/rqinit.py +++ b/rqinit.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from urlparse import urlparse +from urllib.parse import urlparse from lastuserapp import app diff --git a/runtestserver.py b/runtestserver.py index d18eb66..e4dd2ec 100644 --- a/runtestserver.py +++ b/runtestserver.py @@ -16,23 +16,23 @@ # Add fixtures for test app # user for CRUD workflow: creating client app gustav = User( - username=u"gustav", fullname=u"Gustav 'world' Dachshund", password='worldismyball' + username="gustav", fullname="Gustav 'world' Dachshund", password='worldismyball' ) # org for associating with client # client for CRUD workflow of defining perms *in* client # spare user for CRUD workflow of assigning permissions -oakley = User(username=u"oakley", fullname=u"Oakley 'huh' Dachshund") -dachsunited = Organization(name=u"dachsunited", title=u"Dachs United") +oakley = User(username="oakley", fullname="Oakley 'huh' Dachshund") +dachsunited = Organization(name="dachsunited", title="Dachs United") dachsunited.owners.users.append(gustav) dachsunited.members.users.append(oakley) dachshundworld = Client( - title=u"Dachshund World", + title="Dachshund World", org=dachsunited, confidential=True, - website=u"http://gustavsdachshundworld.com", + website="http://gustavsdachshundworld.com", ) -partyanimal = Permission(name=u"partyanimal", title=u"Party Animal", org=dachsunited) +partyanimal = Permission(name="partyanimal", title="Party Animal", org=dachsunited) db.session.add(gustav) db.session.add(oakley) diff --git a/tests/unit/lastuser_core/fixtures.py b/tests/unit/lastuser_core/fixtures.py index 7817448..5c75621 100644 --- a/tests/unit/lastuser_core/fixtures.py +++ b/tests/unit/lastuser_core/fixtures.py @@ -25,9 +25,9 @@ def make_fixtures(self): Create users, attach them to organizations. Create test client app, add test resource, action and message. """ - crusoe = User(username=u"crusoe", fullname=u"Crusoe Celebrity Dachshund") - oakley = User(username=u"oakley") - piglet = User(username=u"piglet") + crusoe = User(username="crusoe", fullname="Crusoe Celebrity Dachshund") + oakley = User(username="oakley") + piglet = User(username="piglet") nameless = User(fullname="Nameless") db.session.add_all([crusoe, oakley, piglet, nameless]) @@ -37,42 +37,42 @@ def make_fixtures(self): self.nameless = nameless crusoe_email = UserEmail( - email=u"crusoe@keepballin.ca", primary=True, user=crusoe + email="crusoe@keepballin.ca", primary=True, user=crusoe ) - crusoe_phone = UserPhone(phone=u"+8080808080", primary=True, user=crusoe) - oakley_email = UserEmail(email=u"huh@keepballin.ca", user=oakley) + crusoe_phone = UserPhone(phone="+8080808080", primary=True, user=crusoe) + oakley_email = UserEmail(email="huh@keepballin.ca", user=oakley) db.session.add_all([crusoe_email, crusoe_phone, oakley_email]) self.crusoe_email = crusoe_email self.crusoe_phone = crusoe_phone - batdog = Organization(name=u'batdog', title=u'Batdog') + batdog = Organization(name='batdog', title='Batdog') batdog.owners.users.append(crusoe) batdog.members.users.append(oakley) db.session.add(batdog) self.batdog = batdog - specialdachs = Organization(name=u"specialdachs", title=u"Special Dachshunds") + specialdachs = Organization(name="specialdachs", title="Special Dachshunds") specialdachs.owners.users.append(oakley) specialdachs.members.users.append(piglet) db.session.add(specialdachs) self.specialdachs = specialdachs client = Client( - title=u"Batdog Adventures", + title="Batdog Adventures", org=batdog, confidential=True, - namespace=u'fun.batdogadventures.com', - website=u"http://batdogadventures.com", + namespace='fun.batdogadventures.com', + website="http://batdogadventures.com", ) db.session.add(client) self.client = client - dachshunds = Team(title=u"Dachshunds", org=batdog) + dachshunds = Team(title="Dachshunds", org=batdog) db.session.add(dachshunds) self.dachshunds = dachshunds team_client_permission = TeamClientPermissions( - team=dachshunds, client=client, access_permissions=u"admin" + team=dachshunds, client=client, access_permissions="admin" ) self.team_client_permission = team_client_permission db.session.add(team_client_permission) @@ -82,7 +82,7 @@ def make_fixtures(self): ) db.session.add(client_team_access) - bdfl = Permission(name=u"bdfl", title=u"BDFL", user=crusoe) + bdfl = Permission(name="bdfl", title="BDFL", user=crusoe) db.session.add(bdfl) self.bdfl = bdfl @@ -91,23 +91,23 @@ def make_fixtures(self): self.user_client_permissions = user_client_permissions resource = Resource( - name=u"test_resource", title=u"Test Resource", client=client + name="test_resource", title="Test Resource", client=client ) db.session.add(resource) self.resource = resource - resource_action = ResourceAction(name=u'Fun', resource=resource, title=u'fun') + resource_action = ResourceAction(name='Fun', resource=resource, title='fun') db.session.add(resource_action) self.resource_action = resource_action - action = ResourceAction(name=u"read", title=u"Read", resource=resource) + action = ResourceAction(name="read", title="Read", resource=resource) db.session.add(action) self.action = action message = SMSMessage( phone_number=crusoe_phone.phone, - transaction_id=u"Ruff" * 5, - message=u"Wuff Wuff", + transaction_id="Ruff" * 5, + message="Wuff Wuff", ) db.session.add(message) db.session.commit() diff --git a/tests/unit/lastuser_core/test_model_client_AuthCode.py b/tests/unit/lastuser_core/test_model_client_AuthCode.py index 10639c6..14b9c41 100644 --- a/tests/unit/lastuser_core/test_model_client_AuthCode.py +++ b/tests/unit/lastuser_core/test_model_client_AuthCode.py @@ -14,8 +14,8 @@ def test_authcode_init(self): auth_code = models.AuthCode( user=crusoe, client=client, - redirect_uri=u'http://batdogadventures.com/fun', - scope=u'id', + redirect_uri='http://batdogadventures.com/fun', + scope='id', ) # code redirect_uri, used db.session.add(auth_code) @@ -33,8 +33,8 @@ def test_authcode_is_valid(self): user=oakley, client=client, used=True, - redirect_uri=u'http://batdogadventures.com/fun', - scope=u'email', + redirect_uri='http://batdogadventures.com/fun', + scope='email', ) db.session.add(auth_code) db.session.commit() diff --git a/tests/unit/lastuser_core/test_model_client_AuthToken.py b/tests/unit/lastuser_core/test_model_client_AuthToken.py index 86e73b0..53e0791 100644 --- a/tests/unit/lastuser_core/test_model_client_AuthToken.py +++ b/tests/unit/lastuser_core/test_model_client_AuthToken.py @@ -17,14 +17,14 @@ def test_authtoken_init(self): """ client = self.fixtures.client crusoe = self.fixtures.crusoe - result = models.AuthToken(client=client, user=crusoe, scope=u'id', validity=0) + result = models.AuthToken(client=client, user=crusoe, scope='id', validity=0) self.assertIsInstance(result, models.AuthToken) self.assertEqual(result.user, crusoe) self.assertEqual(result.client, client) def test_authtoken_refresh(self): """Test to verify creation of new token while retaining the refresh token.""" - hagrid = models.User(username=u'hagrid', fullname=u'Rubeus Hagrid') + hagrid = models.User(username='hagrid', fullname='Rubeus Hagrid') auth_token = models.AuthToken(user=hagrid, algorithm='hmac-sha-1') existing_token = auth_token.token existing_secret = auth_token.secret @@ -38,28 +38,28 @@ def test_authtoken_is_valid(self): """ client = self.fixtures.client # scenario 1: when validity is unlimited (0) - tomriddle = models.User(username=u'voldemort', fullname=u'Tom Riddle') - scope = [u'id', u'email'] + tomriddle = models.User(username='voldemort', fullname='Tom Riddle') + scope = ['id', 'email'] tomriddle_token = models.AuthToken( client=client, user=tomriddle, scope=scope, validity=0 ) self.assertTrue(tomriddle_token.is_valid()) # scenario 2: when validity has not been given - draco = models.User(username=u'draco', fullname=u'Draco Malfoy') + draco = models.User(username='draco', fullname='Draco Malfoy') draco_token = models.AuthToken(client=client, user=draco, scope=scope) with self.assertRaises(TypeError): draco_token.is_valid() # scenario 3: when validity is limited - harry = models.User(username=u'harry', fullname=u'Harry Potter') + harry = models.User(username='harry', fullname='Harry Potter') harry_token = models.AuthToken( client=client, user=harry, scope=scope, validity=3600, created_at=utcnow() ) self.assertTrue(harry_token.is_valid()) # scenario 4: when validity is limited *and* the token has expired - cedric = models.User(username=u'cedric', fullname=u'Cedric Diggory') + cedric = models.User(username='cedric', fullname='Cedric Diggory') cedric_token = models.AuthToken( client=client, user=cedric, @@ -75,12 +75,12 @@ def test_authtoken_get(self): """ specialdachs = self.fixtures.specialdachs oakley = self.fixtures.oakley - scope = [u'id'] + scope = ['id'] dachsadv = models.Client( - title=u"Dachshund Adventures", + title="Dachshund Adventures", org=specialdachs, confidential=True, - website=u"http://dachsadv.com", + website="http://dachsadv.com", ) auth_token = models.AuthToken(client=dachsadv, user=oakley, scope=scope) token = auth_token.token @@ -96,15 +96,15 @@ def test_authtoken_all(self): client = self.fixtures.client # scenario 1: When users passed are an instance of Query class - hermione = models.User(username=u'herminone', fullname=u'Hermione Granger') - herminone_token = models.AuthToken(client=client, user=hermione, scope=[u'id']) - myrtle = models.User(username=u'myrtle', fullname=u'Moaning Myrtle') - myrtle_token = models.AuthToken(client=client, user=myrtle, scope=[u'id']) - alastor = models.User(username=u'alastor', fullname=u'Alastor Moody') - alastor_token = models.AuthToken(client=client, user=alastor, scope=[u'id']) - greyback = models.User(username=u'greyback', fullname=u'Fenrir Greyback') - greyback_token = models.AuthToken(client=client, user=greyback, scope=[u'id']) - pottermania = models.Organization(name=u'pottermania', title=u'Pottermania') + hermione = models.User(username='herminone', fullname='Hermione Granger') + herminone_token = models.AuthToken(client=client, user=hermione, scope=['id']) + myrtle = models.User(username='myrtle', fullname='Moaning Myrtle') + myrtle_token = models.AuthToken(client=client, user=myrtle, scope=['id']) + alastor = models.User(username='alastor', fullname='Alastor Moody') + alastor_token = models.AuthToken(client=client, user=alastor, scope=['id']) + greyback = models.User(username='greyback', fullname='Fenrir Greyback') + greyback_token = models.AuthToken(client=client, user=greyback, scope=['id']) + pottermania = models.Organization(name='pottermania', title='Pottermania') pottermania.owners.users.append(hermione) pottermania_members = [hermione, alastor, greyback, myrtle] for member in pottermania_members: @@ -140,10 +140,10 @@ def test_authtoken_all(self): ) # Scenario 2: When users passed are not an instance of Query class - lily = models.User(username=u'lily', fullname=u'Lily Evans Potter') - cho = models.User(username=u'cho', fullname=u'Cho Chang') - lily_token = models.AuthToken(client=client, user=lily, scope=[u'memories']) - cho_token = models.AuthToken(client=client, user=cho, scope=[u'charms']) + lily = models.User(username='lily', fullname='Lily Evans Potter') + cho = models.User(username='cho', fullname='Cho Chang') + lily_token = models.AuthToken(client=client, user=lily, scope=['memories']) + cho_token = models.AuthToken(client=client, user=cho, scope=['charms']) db.session.add_all([lily, lily_token, cho, cho_token]) db.session.commit() @@ -226,7 +226,7 @@ def test_authtoken_algorithm(self): """ Test for checking AuthToken's algorithm property """ - snape = models.User(username=u'snape', fullname=u'Professor Severus Snape') + snape = models.User(username='snape', fullname='Professor Severus Snape') valid_algorithm = 'hmac-sha-1' auth_token = models.AuthToken(user=snape) auth_token.algorithm = None diff --git a/tests/unit/lastuser_core/test_model_client_Client.py b/tests/unit/lastuser_core/test_model_client_Client.py index 3dbd3f2..6ba6f69 100644 --- a/tests/unit/lastuser_core/test_model_client_Client.py +++ b/tests/unit/lastuser_core/test_model_client_Client.py @@ -22,8 +22,8 @@ def test_client_host_matches(self): split the referrer URL correctly """ client = self.fixtures.client - client.redirect_uris = [u"http://hasjob.dev:5000"] - referrer = u"http://hasjob.dev:5000/logout" + client.redirect_uris = ["http://hasjob.dev:5000"] + referrer = "http://hasjob.dev:5000/logout" self.assertTrue(client.host_matches(referrer)) def test_client_owner(self): @@ -78,7 +78,7 @@ def test_client_authtoken_for(self): crusoe = self.fixtures.crusoe result = client.authtoken_for(crusoe) client_token = models.AuthToken( - client=client, user=crusoe, scope=u'id', validity=0 + client=client, user=crusoe, scope='id', validity=0 ) result = client.authtoken_for(user=crusoe) self.assertEqual(client_token, result) @@ -86,23 +86,23 @@ def test_client_authtoken_for(self): assert "Crusoe Celebrity Dachshund" in repr(result) # scenario 2: for a client that has confidential=False - varys = models.User(username=u'varys', fullname=u'Lord Varys') + varys = models.User(username='varys', fullname='Lord Varys') house_lannisters = models.Client( - title=u'House of Lannisters', + title='House of Lannisters', confidential=False, user=varys, - website=u'houseoflannisters.westeros', + website='houseoflannisters.westeros', ) varys_session = models.UserSession( user=varys, ipaddr='192.168.1.99', - user_agent=u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', + user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', accessed_at=utcnow(), ) lannisters_auth_token = models.AuthToken( client=house_lannisters, user=varys, - scope=u'throne', + scope='throne', validity=0, user_session=varys_session, ) @@ -140,7 +140,7 @@ def test_client_get(self): self.assertEqual(result1.key, key) self.assertEqual(result1.owner, batdog) # scenario 3: when given namespace - namespace = u'fun.batdogadventures.com' + namespace = 'fun.batdogadventures.com' result2 = models.Client.get(namespace=namespace) self.assertIsInstance(result2, models.Client) self.assertEqual(result2.namespace, namespace) diff --git a/tests/unit/lastuser_core/test_model_client_Permission.py b/tests/unit/lastuser_core/test_model_client_Permission.py index 83b3a43..891318a 100644 --- a/tests/unit/lastuser_core/test_model_client_Permission.py +++ b/tests/unit/lastuser_core/test_model_client_Permission.py @@ -14,7 +14,7 @@ def test_permission_get(self): # scenario 1: when allusers is False specialdachs = self.fixtures.specialdachs netizens = models.Permission( - name=u"netizens", title=u"Netizens", org=specialdachs, allusers=True + name="netizens", title="Netizens", org=specialdachs, allusers=True ) db.session.add(netizens) db.session.commit() @@ -59,9 +59,9 @@ def test_permission_owner(self): get_owner_by_user = bdfl.owner self.assertEqual(get_owner_by_user, crusoe) specialdachs = self.fixtures.specialdachs - permission_name = u"netizens" + permission_name = "netizens" netizens = models.Permission( - name=permission_name, title=u"Netizens", allusers=True, org=specialdachs + name=permission_name, title="Netizens", allusers=True, org=specialdachs ) db.session.add(netizens) db.session.commit() diff --git a/tests/unit/lastuser_core/test_model_client_Resource.py b/tests/unit/lastuser_core/test_model_client_Resource.py index 3cb0fb1..93712ab 100644 --- a/tests/unit/lastuser_core/test_model_client_Resource.py +++ b/tests/unit/lastuser_core/test_model_client_Resource.py @@ -11,7 +11,7 @@ def test_resource_get(self): Test for retrieving a Resource given a name """ # scenario 3: if namespace given - name = u'test_resource' + name = 'test_resource' client = self.fixtures.client namespace = client.namespace # scenario 1: if both client and namespace not given diff --git a/tests/unit/lastuser_core/test_model_client_ScopeMixin.py b/tests/unit/lastuser_core/test_model_client_ScopeMixin.py index f93aefc..d5987fb 100644 --- a/tests/unit/lastuser_core/test_model_client_ScopeMixin.py +++ b/tests/unit/lastuser_core/test_model_client_ScopeMixin.py @@ -11,8 +11,8 @@ def test_scopemixin__scope(self): """ Test to retrieve scope on an ScopeMixin inherited class instance via _scope method """ - scope = u'id' - bellatrix = models.User(username=u'bellatrix', fullname=u'Bellatrix Lestrange') + scope = 'id' + bellatrix = models.User(username='bellatrix', fullname='Bellatrix Lestrange') client = self.fixtures.client bellatrix_token = models.AuthToken( client=client, user=bellatrix, scope=scope, validity=0 @@ -23,8 +23,8 @@ def test_scopemixin__scope(self): def test_scopemixin_scope(self): """Test to retrieve scope on an ScopeMixin inherited class instance via scope method""" - scope = u'tricks' - ginny = models.User(username=u'ginny', fullname=u'Ginny Weasley') + scope = 'tricks' + ginny = models.User(username='ginny', fullname='Ginny Weasley') client = self.fixtures.client ginny_token = models.AuthToken( client=client, user=ginny, scope=scope, validity=0 @@ -35,8 +35,8 @@ def test_scopemixin_scope(self): def test_scopemixin__scope_get(self): """Test to retrieve scope with __scope_get on an AuthToken instance """ - scope = [u'teams', u'email', u'id'] - khal = models.User(username=u'khal', fullname=u'Khal Drogo') + scope = ['teams', 'email', 'id'] + khal = models.User(username='khal', fullname='Khal Drogo') client = self.fixtures.client khal_token = models.AuthToken(client=client, user=khal, scope=scope, validity=0) db.session.add_all([khal, khal_token]) @@ -46,8 +46,8 @@ def test_scopemixin__scope_get(self): def test_scopemixin__scope_set(self): """Test to set scope with __scope_set on an AuthToken instance""" """Test to retrieve scope with __scope_get on an AuthToken instance """ - scope = [u'teams', u'wars', u'alliances'] - sansa = models.User(username=u'sansa', fullname=u'Sansa Stark') + scope = ['teams', 'wars', 'alliances'] + sansa = models.User(username='sansa', fullname='Sansa Stark') client = self.fixtures.client sansa_token = models.AuthToken(client=client, user=sansa, validity=0) sansa_token._scope_set(scope) @@ -59,9 +59,9 @@ def test_scopemixin_add_scope(self): """ Test for adding scope to a ScopeMixin inherited class instance """ - scope1 = u'spells' - scope2 = u'charms' - neville = models.User(username=u'neville', fullname=u'Neville Longbottom') + scope1 = 'spells' + scope2 = 'charms' + neville = models.User(username='neville', fullname='Neville Longbottom') client = self.fixtures.client neville_token = models.AuthToken( client=client, user=neville, validity=0, scope=scope1 diff --git a/tests/unit/lastuser_core/test_model_client_UserClientPermissions.py b/tests/unit/lastuser_core/test_model_client_UserClientPermissions.py index e6d30f8..7138d76 100644 --- a/tests/unit/lastuser_core/test_model_client_UserClientPermissions.py +++ b/tests/unit/lastuser_core/test_model_client_UserClientPermissions.py @@ -11,9 +11,9 @@ def test_userclientpermissions(self): """ Test for verifying creation of UserClientPermissions instance """ - gustav = models.User(username=u'gustav') + gustav = models.User(username='gustav') client = self.fixtures.client - access_permissions = u'siteadmin' + access_permissions = 'siteadmin' result = models.UserClientPermissions( user=gustav, client=client, access_permissions=access_permissions ) @@ -28,7 +28,7 @@ def test_userclientpermissions_migrate_user(self): """ # scenario 1: when *only* olduser has UserClientPermissions instance old_crusoe = self.fixtures.crusoe - new_crusoe = models.User(username=u'chef-crusoe') + new_crusoe = models.User(username='chef-crusoe') models.UserClientPermissions.migrate_user(old_crusoe, new_crusoe) for each in new_crusoe.client_permissions: self.assertIsInstance(each, models.UserClientPermissions) @@ -37,14 +37,14 @@ def test_userclientpermissions_migrate_user(self): # scenario 2: when *both* olduser and newuser have UserClientPermissions instances old_oakley = self.fixtures.oakley client = self.fixtures.client - access_permissions_old_oakley = u'siteadmin' - access_permissions_new_oakley = u'siteeditor' + access_permissions_old_oakley = 'siteadmin' + access_permissions_new_oakley = 'siteeditor' old_oakley_userclientperms = models.UserClientPermissions( user=old_oakley, client=client, access_permissions=access_permissions_old_oakley, ) - new_oakley = models.User(username=u'oakley-the-stud') + new_oakley = models.User(username='oakley-the-stud') new_oakley_userclientperms = models.UserClientPermissions( user=new_oakley, client=client, @@ -67,9 +67,9 @@ def test_userclientpermissions_pickername(self): """ Test for UserClientPermissions' pickername """ - finnick = models.User(username=u'finnick', fullname=u"Finnick Odair") - district4 = models.Client(title=u"District 4") - access_permissions = u'siteadmin' + finnick = models.User(username='finnick', fullname="Finnick Odair") + district4 = models.Client(title="District 4") + access_permissions = 'siteadmin' result = models.UserClientPermissions( user=finnick, client=district4, access_permissions=access_permissions ) @@ -79,9 +79,9 @@ def test_userclientpermissions_buid(self): """ Test for UserClientPermissions' buid """ - beetee = models.User(username=u'beetee', fullname=u"Beetee") - district3 = models.Client(title=u'District 3') - access_permissions = u'siteadmin' + beetee = models.User(username='beetee', fullname="Beetee") + district3 = models.Client(title='District 3') + access_permissions = 'siteadmin' result = models.UserClientPermissions( user=beetee, client=district3, access_permissions=access_permissions ) diff --git a/tests/unit/lastuser_core/test_model_user_Name.py b/tests/unit/lastuser_core/test_model_user_Name.py index 72403e8..0b30af5 100644 --- a/tests/unit/lastuser_core/test_model_user_Name.py +++ b/tests/unit/lastuser_core/test_model_user_Name.py @@ -29,7 +29,7 @@ def test_validate_name_candidate(self): assert models.Name.validate_name_candidate('0123456789' * 7) == 'long' assert models.Name.validate_name_candidate('0123456789' * 6) is None assert models.Name.validate_name_candidate('test-reserved') is None - db.session.add(models.Name(name=u'test-reserved', reserved=True)) + db.session.add(models.Name(name='test-reserved', reserved=True)) db.session.commit() assert models.Name.validate_name_candidate('test-reserved') == 'reserved' assert models.Name.validate_name_candidate('piglet') == 'user' @@ -39,10 +39,10 @@ def test_reserved_name(self): """ Names can be reserved, with no user or organization """ - reserved_name = models.Name(name=u'reserved-name', reserved=True) + reserved_name = models.Name(name='reserved-name', reserved=True) db.session.add(reserved_name) db.session.commit() - retrieved_name = models.Name.get(u'reserved-name') + retrieved_name = models.Name.get('reserved-name') assert retrieved_name is reserved_name assert reserved_name.user is None assert reserved_name.user_id is None @@ -53,7 +53,7 @@ def test_unassigned_name(self): """ Names must be assigned to a user or organization if not reserved """ - unassigned_name = models.Name(name=u'unassigned') + unassigned_name = models.Name(name='unassigned') db.session.add(unassigned_name) with self.assertRaises(IntegrityError): db.session.commit() @@ -62,9 +62,9 @@ def test_double_assigned_name(self): """ Names cannot be assigned to both a user and an organization simultaneously """ - user = models.User(fullname=u"User") - org = models.Organization(title=u"Organization") - name = models.Name(name=u'double-assigned', user=user, org=org) + user = models.User(fullname="User") + org = models.Organization(title="Organization") + name = models.Name(name='double-assigned', user=user, org=org) db.session.add_all([user, org, name]) with self.assertRaises(IntegrityError): db.session.commit() @@ -73,8 +73,8 @@ def test_user_two_names(self): """ A user cannot have two names """ - assert self.fixtures.piglet.username == u'piglet' - peppa = models.Name(name=u'peppa', user=self.fixtures.piglet) + assert self.fixtures.piglet.username == 'piglet' + peppa = models.Name(name='peppa', user=self.fixtures.piglet) db.session.add(peppa) with self.assertRaises(IntegrityError): db.session.commit() @@ -83,8 +83,8 @@ def test_org_two_names(self): """ An organization cannot have two names """ - assert self.fixtures.batdog.name == u'batdog' - bathound = models.Name(name=u'bathound', org=self.fixtures.batdog) + assert self.fixtures.batdog.name == 'batdog' + bathound = models.Name(name='bathound', org=self.fixtures.batdog) db.session.add(bathound) with self.assertRaises(IntegrityError): db.session.commit() @@ -93,30 +93,30 @@ def test_remove_name(self): """ Removing a name from a user or org also removes it from the Name table """ - assert self.fixtures.oakley.username == u'oakley' - assert models.Name.get(u'oakley') is not None + assert self.fixtures.oakley.username == 'oakley' + assert models.Name.get('oakley') is not None self.fixtures.oakley.username = None db.session.commit() - assert models.Name.get(u'oakley') is None + assert models.Name.get('oakley') is None - assert self.fixtures.specialdachs.name == u'specialdachs' - assert models.Name.get(u'specialdachs') is not None + assert self.fixtures.specialdachs.name == 'specialdachs' + assert models.Name.get('specialdachs') is not None self.fixtures.specialdachs.name = None db.session.commit() - assert models.Name.get(u'specialdachs') is None + assert models.Name.get('specialdachs') is None def test_name_transfer(self): assert self.fixtures.nameless.username is None - assert models.Name.get(u'newname') is None - newname = models.User(username=u'newname', fullname="New Name") + assert models.Name.get('newname') is None + newname = models.User(username='newname', fullname="New Name") db.session.add(newname) db.session.commit() - assert models.Name.get(u'newname') is not None - assert newname.username == u'newname' + assert models.Name.get('newname') is not None + assert newname.username == 'newname' merged = models.merge_users(self.fixtures.nameless, newname) assert merged is not newname assert merged is self.fixtures.nameless assert newname.username is None - assert merged.username == u'newname' - assert self.fixtures.nameless.username == u'newname' + assert merged.username == 'newname' + assert self.fixtures.nameless.username == 'newname' diff --git a/tests/unit/lastuser_core/test_model_user_Organization.py b/tests/unit/lastuser_core/test_model_user_Organization.py index 4baeb37..4806fc3 100644 --- a/tests/unit/lastuser_core/test_model_user_Organization.py +++ b/tests/unit/lastuser_core/test_model_user_Organization.py @@ -11,8 +11,8 @@ def test_organization_init(self): """ Test for initializing a Organization instance """ - name = u'dachshunited' - title = u'Dachshunds United' + name = 'dachshunited' + title = 'Dachshunds United' dachsunited = models.Organization(name=name, title=title) self.assertIsInstance(dachsunited, models.Organization) self.assertEqual(dachsunited.title, title) @@ -25,8 +25,8 @@ def test_organization_make_teams(self): crusoe = self.fixtures.crusoe oakley = self.fixtures.oakley piglet = self.fixtures.piglet - name = u'dachshunited' - title = u'Dachshunds United' + name = 'dachshunited' + title = 'Dachshunds United' dachsunited = models.Organization(name=name, title=title) # Scenario: before any users were added to the organization self.assertIsInstance(dachsunited.owners, models.Team) @@ -39,10 +39,10 @@ def test_organization_make_teams(self): dachsunited.owners.users.append(crusoe) dachsunited.members.users.append(oakley) dachsunited.members.users.append(piglet) - assert u''.format( + assert ''.format( name=name, title=title ) in repr(dachsunited.owners) - assert u''.format( + assert ''.format( name=name, title=title ) in repr(dachsunited.members) @@ -50,8 +50,8 @@ def test_organization_get(self): """ Test for retrieving an organization """ - name = u'spew' - title = u'S.P.E.W' + name = 'spew' + title = 'S.P.E.W' spew = models.Organization(name=name, title=title) db.session.add(spew) db.session.commit() @@ -62,18 +62,18 @@ def test_organization_get(self): buid = spew.buid get_by_buid = models.Organization.get(buid=buid) self.assertIsInstance(get_by_buid, models.Organization) - assert u''.format(title=title) in repr(get_by_buid) + assert ''.format(title=title) in repr(get_by_buid) # scenario 3: when username is passed get_by_name = models.Organization.get(name=name) self.assertIsInstance(get_by_name, models.Organization) - assert u''.format( + assert ''.format( name=name, title=title ) in repr(get_by_name) # scenario 4: when defercols is set to True get_by_name_with_defercols = models.Organization.get(name=name, defercols=True) self.assertIsInstance(get_by_name_with_defercols, models.Organization) - assert u''.format( + assert ''.format( name=name, title=title ) in repr(get_by_name_with_defercols) @@ -81,8 +81,8 @@ def test_organization_all(self): """ Test for getting all organizations (takes buid or name optionally) """ - gryffindor = models.Organization(name=u'gryffindor') - ravenclaw = models.Organization(name=u'ravenclaw') + gryffindor = models.Organization(name='gryffindor') + ravenclaw = models.Organization(name='ravenclaw') db.session.add(gryffindor) db.session.add(ravenclaw) db.session.commit() @@ -112,29 +112,29 @@ def test_organization_valid_name(self): """ Test for checking if given is a valid organization name """ - hufflepuffs = models.Organization(name=u'hufflepuffs', title=u'Huffle Puffs') - self.assertFalse(hufflepuffs.is_valid_name(u'#$%#%___2836273untitled')) - self.assertTrue(hufflepuffs.is_valid_name(u'hufflepuffs')) + hufflepuffs = models.Organization(name='hufflepuffs', title='Huffle Puffs') + self.assertFalse(hufflepuffs.is_valid_name('#$%#%___2836273untitled')) + self.assertTrue(hufflepuffs.is_valid_name('hufflepuffs')) def test_organization_pickername(self): """ Test for checking Organization's pickername """ # scenario 1: when only title is given - abnegation = models.Organization(title=u"Abnegation") - self.assertIsInstance(abnegation.pickername, unicode) + abnegation = models.Organization(title="Abnegation") + self.assertIsInstance(abnegation.pickername, str) self.assertEqual(abnegation.pickername, abnegation.title) # scenario 2: when both name and title are given - name = u'cullens' - title = u'The Cullens' + name = 'cullens' + title = 'The Cullens' olympic_coven = models.Organization(title=title) olympic_coven.name = name db.session.add(olympic_coven) db.session.commit() - self.assertIsInstance(olympic_coven.pickername, unicode) + self.assertIsInstance(olympic_coven.pickername, str) assert ( - u'{title} (@{name})'.format(title=title, name=name) + '{title} (@{name})'.format(title=title, name=name) in olympic_coven.pickername ) @@ -154,7 +154,7 @@ def test_organization_permissions(self): valid_permissions_received.append(each) self.assertItemsEqual(permissions_expected, valid_permissions_received) # scenario 2: if user is not owner - oakley_permission = models.Permission(name=u"huh", title=u"Huh!?", user=oakley) + oakley_permission = models.Permission(name="huh", title="Huh!?", user=oakley) perms = oakley_permission.permissions(user=oakley) perms.add('view') oakley_query = batdog.permissions(oakley) @@ -171,7 +171,7 @@ def test_organization_available_permissions(self): self.assertIsInstance(org_with_no_permissions, list) self.assertEqual(org_with_no_permissions, []) specialdachs = self.fixtures.specialdachs - permission_name = u"netizens" + permission_name = "netizens" netizens = models.client.Permission( name=permission_name, title=permission_name, allusers=True, org=specialdachs ) @@ -186,13 +186,13 @@ def test_organization_name(self): Test for retrieving Organization's name name is a setter method """ - insurgent = models.Organization(title=u'Insurgent') + insurgent = models.Organization(title='Insurgent') with self.assertRaises(ValueError): - insurgent.name = u'35453496*%&^$%^' + insurgent.name = '35453496*%&^$%^' with self.assertRaises(ValueError): - insurgent.name = u'Insurgent' - insurgent.name = u'insurgent' - self.assertEqual(insurgent.name, u'insurgent') + insurgent.name = 'Insurgent' + insurgent.name = 'insurgent' + self.assertEqual(insurgent.name, 'insurgent') def test_organization_clients_with_team_access(self): """ diff --git a/tests/unit/lastuser_core/test_model_user_Team.py b/tests/unit/lastuser_core/test_model_user_Team.py index 511fc44..3406e18 100644 --- a/tests/unit/lastuser_core/test_model_user_Team.py +++ b/tests/unit/lastuser_core/test_model_user_Team.py @@ -13,7 +13,7 @@ def test_team_get(self): dachshunds = self.fixtures.dachshunds dachshunds_buid = dachshunds.buid result_with_buid = models.Team.get(buid=dachshunds_buid) - assert u''.format( + assert ''.format( team=dachshunds.title, org=repr(dachshunds.org)[1:-1] ) in repr(result_with_buid) with self.assertRaises(TypeError): @@ -26,7 +26,7 @@ def test_team_pickername(self): dachshunds = self.fixtures.dachshunds title = dachshunds.title pickername = dachshunds.pickername - self.assertIsInstance(pickername, unicode) + self.assertIsInstance(pickername, str) self.assertEqual(title, pickername) def test_team_permissions(self): diff --git a/tests/unit/lastuser_core/test_model_user_User.py b/tests/unit/lastuser_core/test_model_user_User.py index ac6f581..3e5a9ef 100644 --- a/tests/unit/lastuser_core/test_model_user_User.py +++ b/tests/unit/lastuser_core/test_model_user_User.py @@ -16,13 +16,13 @@ def test_user(self): """ Test for creation of user object from User model """ - user = models.User(username=u'lena', fullname=u"Lena Audrey Dachshund") + user = models.User(username='lena', fullname="Lena Audrey Dachshund") db.session.add_all([user]) db.session.commit() - lena = models.User.get(username=u'lena') + lena = models.User.get(username='lena') self.assertIsInstance(lena, models.User) - self.assertEqual(user.username, u'lena') - self.assertEqual(user.fullname, u"Lena Audrey Dachshund") + self.assertEqual(user.username, 'lena') + self.assertEqual(user.fullname, "Lena Audrey Dachshund") def test_user_is_valid_name(self): """ @@ -30,12 +30,12 @@ def test_user_is_valid_name(self): """ crusoe = self.fixtures.crusoe # scenario 1: not a valid username - number_one = models.User(username=u'number1', fullname=u'Number One') - self.assertFalse(number_one.is_valid_name(u'Number1')) + number_one = models.User(username='number1', fullname='Number One') + self.assertFalse(number_one.is_valid_name('Number1')) # scenario 2: a valid username but not the username of instance passed - self.assertFalse(crusoe.is_valid_name(u"oakley")) + self.assertFalse(crusoe.is_valid_name("oakley")) # scenario 3: a existing username - self.assertTrue(crusoe.is_valid_name(u"crusoe")) + self.assertTrue(crusoe.is_valid_name("crusoe")) # scenario 4: a existing org batdog = self.fixtures.batdog self.assertFalse(crusoe.is_valid_name(batdog.name)) @@ -48,7 +48,7 @@ def test_user_profileid(self): # scenario 1: when username is given self.assertEqual(crusoe.profileid(), crusoe.username) # scenario 2: when username doesn't exist - mollie = models.User(fullname=u'Mollie') + mollie = models.User(fullname='Mollie') self.assertEqual(len(mollie.profileid()), 22) def test_user_displayname(self): @@ -71,14 +71,14 @@ def test_user_pickername(self): # scenario 1: when username exists crusoe = self.fixtures.crusoe result = crusoe.pickername - expected_result = u'{fullname} (@{username})'.format( + expected_result = '{fullname} (@{username})'.format( fullname=crusoe.fullname, username=crusoe.username ) self.assertEqual(result, expected_result) # scenario 2: when username doesnt exist - mr_fedrick = models.User(fullname=u'Mr. Fedrick') + mr_fedrick = models.User(fullname='Mr. Fedrick') result = mr_fedrick.pickername - expected_result = u'{fullname}'.format(fullname=mr_fedrick.fullname) + expected_result = '{fullname}'.format(fullname=mr_fedrick.fullname) self.assertEqual(result, expected_result) def test_user_is_profile_complete(self): @@ -163,7 +163,7 @@ def test_user_username(self): """ crusoe = self.fixtures.crusoe result = crusoe.username - self.assertIsInstance(result, unicode) + self.assertIsInstance(result, str) self.assertEqual(crusoe.username, result) def test_user_email(self): @@ -175,33 +175,33 @@ def test_user_email(self): self.assertIsInstance(crusoe.email, models.UserEmail) self.assertEqual(crusoe.email, crusoe.email) # scenario 2: when there is no primary email address - mr_pilkington = models.User(username=u'pilkington') + mr_pilkington = models.User(username='pilkington') mr_pilkington_email = models.UserEmail( - user=mr_pilkington, email=u'pilkington@animalfarm.co.uk' + user=mr_pilkington, email='pilkington@animalfarm.co.uk' ) db.session.add_all([mr_pilkington, mr_pilkington_email]) db.session.commit() self.assertEqual(mr_pilkington.email.email, mr_pilkington_email.email) self.assertTrue(mr_pilkington.email.primary) # scenario 3: when no email address is on db - clover = models.User(username=u'clover') + clover = models.User(username='clover') db.session.add(clover) db.session.commit() - self.assertEqual(clover.email, u'') + self.assertEqual(clover.email, '') def test_user_del_email(self): """ Test to delete email address for a user """ - mr_jones = models.User(username=u'mrjones') + mr_jones = models.User(username='mrjones') mr_jones_primary_email = models.UserEmail( - email=u'mrjones@animalfarm.co.uk', primary=True, user=mr_jones + email='mrjones@animalfarm.co.uk', primary=True, user=mr_jones ) mr_jones_secondary_email = models.UserEmail( - email=u'jones@animalfarm.co.uk', user=mr_jones + email='jones@animalfarm.co.uk', user=mr_jones ) mr_jones_spare_email = models.UserEmail( - email=u'j@animalfarm.co.uk', user=mr_jones + email='j@animalfarm.co.uk', user=mr_jones ) db.session.add_all( [ @@ -240,8 +240,8 @@ def test_user_phone(self): self.assertEqual(crusoe_phone, crusoe.phone) self.assertTrue(crusoe.phone.primary) # scenario 2: when there is a phone but not as primary - snowball = models.User(username=u'snowball') - snowball_phone = models.UserPhone(phone=u'+918574808032', user=snowball) + snowball = models.User(username='snowball') + snowball_phone = models.UserPhone(phone='+918574808032', user=snowball) db.session.add_all([snowball, snowball_phone]) db.session.commit() self.assertIsInstance(snowball.phone, models.UserPhone) @@ -249,56 +249,56 @@ def test_user_phone(self): self.assertTrue(snowball.phone.primary) # scenario 3: when there is no phone on db piglet = self.fixtures.piglet - assert piglet.phone == u'' + assert piglet.phone == '' def test_user_password(self): """ Test to set user password """ # Scenario 1: Set None as password - castle = models.User(username=u'castle', fullname=u'Rick Castle') + castle = models.User(username='castle', fullname='Rick Castle') castle.password = None self.assertIsNone(castle.pw_hash) # Scenario 2: Set valid password - kate = models.User(username=u'kate', fullname=u'Detective Kate Beckette') - kate.password = u'12thprecinct' + kate = models.User(username='kate', fullname='Detective Kate Beckette') + kate.password = '12thprecinct' db.session.add(kate) db.session.commit() result = models.User.get(buid=kate.buid) self.assertEqual(len(result.pw_hash), 60) - self.assertTrue(result.password_is(u'12thprecinct')) + self.assertTrue(result.password_is('12thprecinct')) self.assertGreater(result.pw_expires_at, result.pw_set_at) def test_user_clients_with_team_access(self): """ Test to verify a list of clients with access to the user's organizations' teams. """ - aro = models.User(username=u'aro') - jane = models.User(username=u'jane') - marcus = models.User(username=u'marcus') - volturi = models.Organization(name=u'volturi', title=u'The Volturi') + aro = models.User(username='aro') + jane = models.User(username='jane') + marcus = models.User(username='marcus') + volturi = models.Organization(name='volturi', title='The Volturi') volturi.owners.users.append(aro) volturi.members.users.append(marcus) volturi.members.users.append(jane) volturi.make_teams() volterra = models.Client( - title=u'Volterra, Tuscany', + title='Volterra, Tuscany', org=volturi, confidential=True, - website=u'volterra.co.it', + website='volterra.co.it', ) enforcers = models.Client( - title=u'Volturi\'s thugs', + title='Volturi\'s thugs', org=volturi, confidential=True, - website=u'volturi.co.it', + website='volturi.co.it', ) volterra_auth_token = models.AuthToken( - client=volterra, user=aro, scope=u'teams', validity=0 + client=volterra, user=aro, scope='teams', validity=0 ) volterra_auth_token enforcers_auth_token = models.AuthToken( - client=enforcers, user=marcus, scope=u'teams', validity=0 + client=enforcers, user=marcus, scope='teams', validity=0 ) enforcers_auth_token self.assertItemsEqual(aro.clients_with_team_access(), [volterra]) @@ -309,8 +309,8 @@ def test_user_password_has_expired(self): """ Test to check if password for a user has expired """ - alexis = models.User(username=u'alexis', fullname=u'Alexis Castle') - alexis.password = u'unfortunateincidents' + alexis = models.User(username='alexis', fullname='Alexis Castle') + alexis.password = 'unfortunateincidents' alexis.pw_expires_at = utcnow() + timedelta(0, 0, 1) db.session.add(alexis) db.session.commit() @@ -323,11 +323,11 @@ def test_user_password_is(self): Test to retrieve hashed password for a user """ # scenario 1: no password been set - oldmajor = models.User(username=u'oldmajor') - self.assertFalse(oldmajor.password_is(u'oinkoink')) + oldmajor = models.User(username='oldmajor') + self.assertFalse(oldmajor.password_is('oinkoink')) # scenario 3: if password has been set - dumbeldore = models.User(u'dumbeldore', fullname=u'Albus Dumberldore') - dumbeldore_password = u'dissendium' + dumbeldore = models.User('dumbeldore', fullname='Albus Dumberldore') + dumbeldore_password = 'dissendium' dumbeldore.password = dumbeldore_password self.assertTrue(dumbeldore.password_is(dumbeldore_password)) @@ -338,7 +338,7 @@ def test_user_is_active(self): """ crusoe = self.fixtures.crusoe self.assertEqual(crusoe.status, 0) - oakley = models.User.get(username=u'oakley') + oakley = models.User.get(username='oakley') oakley.status = 1 self.assertEqual(oakley.status, 1) @@ -354,7 +354,7 @@ def test_user_autocomplete(self): # result1 = models.User.autocomplete(u'*') # self.assertEqual(result1 or lena) # scenario 2: when query passed - queries = [u"[oa]", u"Pig", "crusoe@keepballin.ca"] + queries = ["[oa]", "Pig", "crusoe@keepballin.ca"] result2 = [] for each in queries: result2.append(models.User.autocomplete(each)) @@ -375,7 +375,7 @@ def test_user_merged_user(self): """ # ## Merge a user onto an older user ### crusoe = self.fixtures.crusoe - crusoe2 = models.User(username=u"crusoe2", fullname=u"Crusoe2") + crusoe2 = models.User(username="crusoe2", fullname="Crusoe2") db.session.add(crusoe2) db.session.commit() merged_user = models.merge_users(crusoe, crusoe2) @@ -385,9 +385,9 @@ def test_user_merged_user(self): # because the logic is to merge into older account so merge status set on newer account self.assertEqual(crusoe.status, 0) self.assertEqual(crusoe2.status, 2) - self.assertEqual(merged_user.username, u"crusoe") + self.assertEqual(merged_user.username, "crusoe") self.assertIsInstance(merged_user.oldids, InstrumentedList) - assert u'of User crusoe "Crusoe Celebrity Dachshund">' in repr( + assert 'of User crusoe "Crusoe Celebrity Dachshund">' in repr( merged_user.oldids ) @@ -405,13 +405,13 @@ def test_user_get(self): self.assertIsInstance(lookup_by_buid, models.client.User) self.assertEqual(lookup_by_buid.buid, crusoe.buid) # scenario 3: if username is passed - lookup_by_username = models.User.get(username=u"crusoe") + lookup_by_username = models.User.get(username="crusoe") self.assertIsInstance(lookup_by_username, models.User) - self.assertEqual(lookup_by_username.username, u"crusoe") + self.assertEqual(lookup_by_username.username, "crusoe") # scenario 4: if defercols is set to True - lookup_by_username = models.User.get(username=u"crusoe", defercols=True) + lookup_by_username = models.User.get(username="crusoe", defercols=True) self.assertIsInstance(lookup_by_username, models.User) - self.assertEqual(lookup_by_username.username, u"crusoe") + self.assertEqual(lookup_by_username.username, "crusoe") # scenario 5: when user.status is active lector = models.User() lector.status = models.USER_STATUS.ACTIVE @@ -422,7 +422,7 @@ def test_user_get(self): self.assertEqual(lookup_by_buid_status.status, lector.status) # scenario 6 : when user.status is USER_STATUS.MERGED piglet = self.fixtures.piglet - piggy = models.User(username=u'piggy') + piggy = models.User(username='piggy') db.session.add(piggy) db.session.commit() merged_user = models.merge_users(piglet, piggy) @@ -466,7 +466,7 @@ def test_user_all(self): self.assertIsInstance(lookup_by_usernames, list) self.assertItemsEqual(lookup_by_usernames, expected_result) # scenario 6: when user.status is active - hannibal = models.User(username=u'hannibal') + hannibal = models.User(username='hannibal') hannibal.status = models.USER_STATUS.ACTIVE db.session.add(hannibal) db.session.commit() @@ -490,22 +490,22 @@ def test_user_add_email(self): Test to add email address for a user """ # scenario 1: if primary flag is True and user has no existing email - mr_whymper = models.User(username=u'whymper') - whymper_email = u'whmmm@animalfarm.co.uk' + mr_whymper = models.User(username='whymper') + whymper_email = 'whmmm@animalfarm.co.uk' whymper_result = mr_whymper.add_email(whymper_email, primary=True) self.assertEqual(whymper_result.email, whymper_email) # # scenario 2: when primary flag is True but user has existing primary email crusoe = self.fixtures.crusoe - crusoe_new_email = u'crusoe@batdog.ca' + crusoe_new_email = 'crusoe@batdog.ca' crusoe_result = crusoe.add_email(email=crusoe_new_email, primary=True) self.assertEqual(crusoe_result.email, crusoe_new_email) # # scenario 3: when primary flag is True but user has existing email same as one passed - crusoe_existing_email = u'crusoe@keepballin.ca' + crusoe_existing_email = 'crusoe@keepballin.ca' crusoe_result = crusoe.add_email(crusoe_existing_email, primary=True) self.assertEqual(crusoe_result.email, crusoe_existing_email) # scenario 4: when requested to adds an email with domain belonging to a team, add user to team - gustav = models.User(username=u'gustav') - gustav_email = u'g@keepballin.ca' + gustav = models.User(username='gustav') + gustav_email = 'g@keepballin.ca' gustav_result = gustav.add_email(gustav_email) db.session.add(gustav) db.session.commit() @@ -515,8 +515,8 @@ def test_make_email_primary(self): """ Test to make an email primary for a user """ - mr_whymper = models.User(username=u'whymmper') - whymper_email = u'whmmmm@animalfarm.co.uk' + mr_whymper = models.User(username='whymmper') + whymper_email = 'whmmmm@animalfarm.co.uk' whymper_result = mr_whymper.add_email(whymper_email) mr_whymper.primary_email = whymper_result self.assertEqual(whymper_result.email, whymper_email) diff --git a/tests/unit/lastuser_core/test_model_user_UserEmail.py b/tests/unit/lastuser_core/test_model_user_UserEmail.py index a2db3bf..4c9408f 100644 --- a/tests/unit/lastuser_core/test_model_user_UserEmail.py +++ b/tests/unit/lastuser_core/test_model_user_UserEmail.py @@ -12,9 +12,9 @@ def test_useremail(self): Test for verifying creation of UserEmail object """ oakley = self.fixtures.oakley - email_domain = u'batdog.ca' + email_domain = 'batdog.ca' oakley_new_email = models.user.UserEmail( - email=u'oakley@' + email_domain, user=oakley + email='oakley@' + email_domain, user=oakley ) self.assertIsInstance(oakley_new_email, models.user.UserEmail) self.assertTrue(hasattr(oakley_new_email, '_email')) @@ -49,8 +49,8 @@ def test_useremail_unicode(self): """ crusoe = self.fixtures.crusoe email = crusoe.email.email - result = unicode(models.UserEmail(email=email)) - self.assertIsInstance(result, unicode) + result = str(models.UserEmail(email=email)) + self.assertIsInstance(result, str) assert email in result def test_useremail_email(self): @@ -58,8 +58,8 @@ def test_useremail_email(self): Test for verifying UserEmail instance's email property """ oakley = self.fixtures.oakley - email = u'oakley@batdogs.ca' + email = 'oakley@batdogs.ca' oakley_new_email = models.UserEmail(email=email, user=oakley) result = oakley_new_email.email - self.assertIsInstance(result, unicode) + self.assertIsInstance(result, str) self.assertEqual(email, result) diff --git a/tests/unit/lastuser_core/test_model_user_UserEmailClaim.py b/tests/unit/lastuser_core/test_model_user_UserEmailClaim.py index fe67ee6..56512f4 100644 --- a/tests/unit/lastuser_core/test_model_user_UserEmailClaim.py +++ b/tests/unit/lastuser_core/test_model_user_UserEmailClaim.py @@ -10,8 +10,8 @@ class TestUserEmailClaim(TestDatabaseFixture): def test_useremailclaim(self): crusoe = self.fixtures.crusoe - domain = u'batdogs.ca' - new_email = u'crusoe@' + domain + domain = 'batdogs.ca' + new_email = 'crusoe@' + domain emd5sum = md5sum(new_email) result = models.UserEmailClaim(email=new_email, user=crusoe) db.session.add(result) @@ -20,7 +20,7 @@ def test_useremailclaim(self): self.assertEqual(emd5sum, result.md5sum) self.assertEqual(domain, result.domain) self.assertEqual(crusoe, result.user) - assert u''.format( + assert ''.format( email=new_email, user=repr(crusoe)[1:-1] ) in (repr(result)) @@ -29,7 +29,7 @@ def test_useremailclaim_permissions(self): Test for verifying whether user has verify permission on a UserEmailClaim instance """ crusoe = self.fixtures.crusoe - email = u'crusoe@batdogs.ca' + email = 'crusoe@batdogs.ca' email_claim = models.UserEmailClaim(email=email, user=crusoe) permissions_expected = ['verify'] result = email_claim.permissions(crusoe) @@ -44,8 +44,8 @@ def test_useremailclaim_get(self): Test for retrieving a UserEmailClaim instance given a user """ - katnis = models.User(username=u'katnis', fullname=u'Katnis Everdeen') - email = u'katnis@hungergames.org' + katnis = models.User(username='katnis', fullname='Katnis Everdeen') + email = 'katnis@hungergames.org' email_claim = models.UserEmailClaim(email=email, user=katnis) db.session.add(email_claim) db.session.commit() @@ -58,9 +58,9 @@ def test_useremailclaim_all(self): """ Test for retrieving all UserEmailClaim instances given an email address """ - gail = models.User(username=u'gail', fullname=u'Gail Hawthorne') - peeta = models.User(username=u'peeta', fullname=u'Peeta Mallark') - email = u'gail@district7.gov' + gail = models.User(username='gail', fullname='Gail Hawthorne') + peeta = models.User(username='peeta', fullname='Peeta Mallark') + email = 'gail@district7.gov' claim_by_gail = models.UserEmailClaim(email=email, user=gail) claim_by_peeta = models.UserEmailClaim(email=email, user=peeta) db.session.add(claim_by_gail) @@ -74,8 +74,8 @@ def test_useremailclaim_email(self): """ Test for verifying UserEmailClaim email property """ - effie = models.User(username=u'effie', fullname=u'Miss. Effie Trinket') - email = u'effie@hungergames.org' + effie = models.User(username='effie', fullname='Miss. Effie Trinket') + email = 'effie@hungergames.org' claim_by_effie = models.UserEmailClaim(email=email, user=effie) - self.assertIsInstance(claim_by_effie.email, unicode) + self.assertIsInstance(claim_by_effie.email, str) self.assertEqual(claim_by_effie.email, email) diff --git a/tests/unit/lastuser_core/test_model_user_UserExternalId.py b/tests/unit/lastuser_core/test_model_user_UserExternalId.py index 733b054..84e7e73 100644 --- a/tests/unit/lastuser_core/test_model_user_UserExternalId.py +++ b/tests/unit/lastuser_core/test_model_user_UserExternalId.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals + from os import environ diff --git a/tests/unit/lastuser_core/test_model_user_UserOldId.py b/tests/unit/lastuser_core/test_model_user_UserOldId.py index ef6dc80..7a23069 100644 --- a/tests/unit/lastuser_core/test_model_user_UserOldId.py +++ b/tests/unit/lastuser_core/test_model_user_UserOldId.py @@ -18,7 +18,7 @@ def test_useroldid_get(self): Test for verifying creation and retrieval of UserOldId instance """ crusoe = self.fixtures.crusoe - bathound = models.User(username=u"bathound", fullname=u"Bathound") + bathound = models.User(username="bathound", fullname="Bathound") db.session.add(bathound) db.session.commit() merged = models.merge_users(crusoe, bathound) diff --git a/tests/unit/lastuser_core/test_model_user_UserPhone.py b/tests/unit/lastuser_core/test_model_user_UserPhone.py index 14a17ce..4663fe0 100644 --- a/tests/unit/lastuser_core/test_model_user_UserPhone.py +++ b/tests/unit/lastuser_core/test_model_user_UserPhone.py @@ -16,7 +16,7 @@ def test_userphone(self): """ Test for verifying creationg of UserPhone instance """ - phone = u"+987645321" + phone = "+987645321" result = models.UserPhone(phone=phone) self.assertIsInstance(result, models.UserPhone) @@ -25,7 +25,7 @@ def test_userphone_get(self): Test for verifying UserPhone's get given a phone number """ crusoe = self.fixtures.crusoe - phone = u'+8080808080' + phone = '+8080808080' result = models.UserPhone.get(phone) self.assertIsInstance(result, models.UserPhone) self.assertEqual(result.user, crusoe) @@ -36,7 +36,7 @@ def test_userphone_unicode(self): Test for verifying whether UserPhone's unicode method returns phone number in unicode """ - phone = u'+8080808080' - result = unicode(models.UserPhone(phone)) - self.assertIsInstance(result, unicode) + phone = '+8080808080' + result = str(models.UserPhone(phone)) + self.assertIsInstance(result, str) self.assertEqual(result, phone) diff --git a/tests/unit/lastuser_core/test_model_user_UserPhoneClaim.py b/tests/unit/lastuser_core/test_model_user_UserPhoneClaim.py index ba6d612..393c6d0 100644 --- a/tests/unit/lastuser_core/test_model_user_UserPhoneClaim.py +++ b/tests/unit/lastuser_core/test_model_user_UserPhoneClaim.py @@ -11,7 +11,7 @@ def test_userphoneclaim(self): """ Test for creation of UserPhoneClaim instance """ - phone = u'9123456780' + phone = '9123456780' result = models.UserPhoneClaim(phone) self.assertIsInstance(result, models.UserPhoneClaim) self.assertEqual(result.phone, phone) @@ -23,7 +23,7 @@ def test_userphoneclaim_all(self): """ crusoe = self.fixtures.crusoe oakley = self.fixtures.oakley - phone = u'9191919191' + phone = '9191919191' claim_by_crusoe = models.UserPhoneClaim(phone=phone, user=crusoe) claim_by_oakley = models.UserPhoneClaim(phone=phone, user=oakley) db.session.add(claim_by_crusoe, claim_by_oakley) @@ -37,8 +37,8 @@ def test_userphoneclaim_get(self): Test for retrieving UserPhoneClaim instances given phone number and a user """ - snow = models.User(username=u'', fullname=u'President Coriolanus Snow') - phone = u'9191919191' + snow = models.User(username='', fullname='President Coriolanus Snow') + phone = '9191919191' phone_claim = models.UserPhoneClaim(phone=phone, user=snow) db.session.add(phone_claim) db.session.commit() @@ -52,13 +52,13 @@ def test_userphoneclaim_unicode(self): Test for verifying whether UserPhoneClaim instance returns phone in unicode format """ - haymitch = models.User(username=u'haymitch', fullname=u'Haymitch Abernathy') - phone = u'9191919191' + haymitch = models.User(username='haymitch', fullname='Haymitch Abernathy') + phone = '9191919191' phone_claim = models.UserPhoneClaim(phone=phone, user=haymitch) db.session.add(phone_claim) db.session.commit() - result = unicode(models.UserPhoneClaim(phone=phone)) - self.assertIsInstance(result, unicode) + result = str(models.UserPhoneClaim(phone=phone)) + self.assertIsInstance(result, str) assert phone in result def test_userphoneclaim_permissions(self): @@ -66,8 +66,8 @@ def test_userphoneclaim_permissions(self): Test for verifying whether user has verify permission on a UserPhoneClaim instance """ - coin = models.User(username=u'coin', fullname=u'President Alma Coin') - phone = u'9191919191' + coin = models.User(username='coin', fullname='President Alma Coin') + phone = '9191919191' phone_claim = models.UserPhoneClaim(phone=phone, user=coin) permissions_expected = ['verify'] result = phone_claim.permissions(coin) diff --git a/tests/unit/lastuser_core/test_models.py b/tests/unit/lastuser_core/test_models.py index a1933ee..12150da 100644 --- a/tests/unit/lastuser_core/test_models.py +++ b/tests/unit/lastuser_core/test_models.py @@ -14,7 +14,7 @@ def test_merge_users(self): """ # Scenario 1: if first user's created_at date younger than second user's created_at crusoe = self.fixtures.crusoe - bathound = models.User(username=u"bathound", fullname=u"Bathound") + bathound = models.User(username="bathound", fullname="Bathound") db.session.add(bathound) db.session.commit() merged = models.merge_users(crusoe, bathound) @@ -25,11 +25,11 @@ def test_merge_users(self): self.assertEqual(bathound.status, 2) # Scenario 1: if second user's created_at date older than first user 's created_at - tyrion = models.User(username=u'tyrion', fullname=u"Tyrion Lannister") + tyrion = models.User(username='tyrion', fullname="Tyrion Lannister") db.session.add(tyrion) db.session.commit() subramanian = models.User( - username=u'subramanian', fullname=u"Tyrion Subramanian" + username='subramanian', fullname="Tyrion Subramanian" ) db.session.add(subramanian) db.session.commit() @@ -46,9 +46,9 @@ def test_getuser(self): """ # scenario 1: with @ starting in name and extid crusoe = self.fixtures.crusoe - service_twitter = u'twitter' + service_twitter = 'twitter' oauth_token = environ.get('TWITTER_OAUTH_TOKEN') - oauth_token_type = u'Bearer' # NOQA: S105 + oauth_token_type = 'Bearer' # NOQA: S105 externalid = models.UserExternalId( service=service_twitter, user=crusoe, @@ -59,14 +59,14 @@ def test_getuser(self): ) db.session.add(externalid) db.session.commit() - result1 = models.getuser(u'@crusoe') + result1 = models.getuser('@crusoe') self.assertIsInstance(result1, models.User) self.assertEqual(result1, crusoe) # scenario 2: with @ in name and not extid - d_email = u'd@dothraki.vly' + d_email = 'd@dothraki.vly' daenerys = models.User( - username=u'daenerys', fullname=u"Daenerys Targaryen", email=d_email + username='daenerys', fullname="Daenerys Targaryen", email=d_email ) daenerys_email = models.UserEmail(email=d_email, user=daenerys) db.session.add_all([daenerys, daenerys_email]) @@ -74,12 +74,12 @@ def test_getuser(self): result2 = models.getuser(d_email) self.assertIsInstance(result2, models.User) self.assertEqual(result2, daenerys) - result3 = models.getuser(u'@daenerys') + result3 = models.getuser('@daenerys') self.assertIsNone(result3) # scenario 3: with no @ starting in name, check by UserEmailClaim - j_email = u'jonsnow@nightswatch.co.uk' - jonsnow = models.User(username=u'jonsnow', fullname=u"Jon Snow") + j_email = 'jonsnow@nightswatch.co.uk' + jonsnow = models.User(username='jonsnow', fullname="Jon Snow") jonsnow_email_claimed = models.UserEmailClaim(email=j_email, user=jonsnow) db.session.add_all([jonsnow, jonsnow_email_claimed]) db.session.commit() @@ -88,17 +88,17 @@ def test_getuser(self): self.assertEqual(result4, jonsnow) # scenario 5: with no @ anywhere in name, fetch username - arya = models.User(username=u'arya', fullname=u"Arya Stark") + arya = models.User(username='arya', fullname="Arya Stark") db.session.add(arya) db.session.commit() - result5 = models.getuser(u'arya') + result5 = models.getuser('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") + cersei = models.User(username='cersei', fullname="Cersei Lannister") db.session.add(cersei) db.session.commit() - result6 = models.getuser(u'cersei@thelannisters.co.uk') + result6 = models.getuser('cersei@thelannisters.co.uk') self.assertIsNone(result6) def test_getextid(self): @@ -107,7 +107,7 @@ def test_getextid(self): """ crusoe = self.fixtures.crusoe email = crusoe.email.email - service_facebook = u'facebook' + service_facebook = 'facebook' externalid = models.UserExternalId( # NOQA: S106 service=service_facebook, @@ -115,13 +115,13 @@ def test_getextid(self): userid=crusoe.email.email, username=crusoe.email.email, oauth_token=environ.get('FACEBOOK_OAUTH_TOKEN'), - oauth_token_type=u'Bearer', + oauth_token_type='Bearer', ) db.session.add(externalid) db.session.commit() result = models.getextid(service_facebook, userid=email) self.assertIsInstance(result, models.UserExternalId) - assert u''.format( + assert ''.format( service=service_facebook, username=email, user=repr(crusoe)[1:-1] ) in repr(result) diff --git a/tests/unit/lastuser_core/test_registry_LoginProviderRegistry.py b/tests/unit/lastuser_core/test_registry_LoginProviderRegistry.py index f6e6c8e..03a0444 100644 --- a/tests/unit/lastuser_core/test_registry_LoginProviderRegistry.py +++ b/tests/unit/lastuser_core/test_registry_LoginProviderRegistry.py @@ -32,4 +32,4 @@ def test_loginproviderregistry(self): if app.config.get('OAUTH_GITHUB_KEY') and app.config.get('OAUTH_GITHUB_SECRET'): expected_login_providers.append('github') self.assertIsInstance(login_registry, LoginProviderRegistry) - self.assertItemsEqual(expected_login_providers, login_registry.keys()) + self.assertItemsEqual(expected_login_providers, list(login_registry.keys())) diff --git a/tests/unit/lastuser_core/test_session_UserSession.py b/tests/unit/lastuser_core/test_session_UserSession.py index b0d2393..7df3e11 100644 --- a/tests/unit/lastuser_core/test_session_UserSession.py +++ b/tests/unit/lastuser_core/test_session_UserSession.py @@ -15,7 +15,7 @@ def test_usersession_init(self): def test_usersession_ua(self): """Test to verify user_agent property of UserSession instance""" - ua = u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36' + ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36' another_user_session = models.UserSession(user_agent=ua) self.assertIsInstance(another_user_session.ua, dict) @@ -25,7 +25,7 @@ def test_usersession_has_sudo(self): another_user_session = models.UserSession( user=crusoe, ipaddr='192.168.1.1', - user_agent=u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', + user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', accessed_at=utcnow(), ) another_user_session.set_sudo() @@ -39,7 +39,7 @@ def test_usersession_revoke(self): yet_another_usersession = models.UserSession( user=crusoe, ipaddr='192.168.1.1', - user_agent=u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', + user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', accessed_at=utcnow(), ) yet_another_usersession.revoke() @@ -56,7 +56,7 @@ def test_usersession_get(self): user=oakley, ipaddr='192.168.1.2', buid=oakley_buid, - user_agent=u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', + user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', accessed_at=utcnow(), ) result = oakley_session.get(buid=oakley_buid) @@ -70,7 +70,7 @@ def test_usersession_active_sessions(self): user=piglet, ipaddr='192.168.1.3', buid=buid(), - user_agent=u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', + user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', accessed_at=utcnow(), ) self.assertIsInstance(piglet.active_sessions.all(), list) @@ -78,13 +78,13 @@ def test_usersession_active_sessions(self): def test_usersession_authenticate(self): """Test to verify authenticate method on UserSession""" - chandler = models.User(username=u'chandler', fullname=u'Chandler Bing') + chandler = models.User(username='chandler', fullname='Chandler Bing') chandler_buid = buid() chandler_session = models.UserSession( user=chandler, ipaddr='192.168.1.4', buid=chandler_buid, - user_agent=u'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', + user_agent='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36', accessed_at=utcnow(), ) db.session.add(chandler) From 89463adc021d1ed2a55e29880a859d6161d2db8a Mon Sep 17 00:00:00 2001 From: Bibhas Date: Wed, 12 Feb 2020 15:22:56 +0530 Subject: [PATCH 02/10] dont need to set encoding and adding flask_oauth to repo --- lastuser_oauth/providers/flask_oauth.py | 435 ++++++++++++++++++++++++ lastuser_oauth/providers/twitter.py | 2 +- lastuser_oauth/views/login.py | 6 +- runserver.py | 5 - runtestserver.py | 5 - 5 files changed, 437 insertions(+), 16 deletions(-) create mode 100644 lastuser_oauth/providers/flask_oauth.py diff --git a/lastuser_oauth/providers/flask_oauth.py b/lastuser_oauth/providers/flask_oauth.py new file mode 100644 index 0000000..c3f6d1d --- /dev/null +++ b/lastuser_oauth/providers/flask_oauth.py @@ -0,0 +1,435 @@ +# -*- coding: utf-8 -*- +""" + flask_oauth + ~~~~~~~~~~~ + + Implements basic OAuth support for Flask. + + :copyright: (c) 2010 by Armin Ronacher. + :license: BSD, see LICENSE for more details. +""" +import httplib2 +from functools import wraps +from urllib.parse import urljoin +from flask import request, session, json, redirect, Response +from werkzeug import url_decode, url_encode, url_quote, \ + parse_options_header, Headers +import oauth2 + + +_etree = None +def get_etree(): + """Return an elementtree implementation. Prefers lxml""" + global _etree + if _etree is None: + try: + from lxml import etree as _etree + except ImportError: + try: + from xml.etree import cElementTree as _etree + except ImportError: + try: + from xml.etree import ElementTree as _etree + except ImportError: + raise TypeError('lxml or etree not found') + return _etree + + +def parse_response(resp, content, strict=False): + ct, options = parse_options_header(resp['content-type']) + if ct in ('application/json', 'text/javascript'): + return json.loads(content) + elif ct in ('application/xml', 'text/xml'): + # technically, text/xml is ascii based but because many + # implementations get that wrong and utf-8 is a superset + # of utf-8 anyways, so there is not much harm in assuming + # utf-8 here + charset = options.get('charset', 'utf-8') + return get_etree().fromstring(content.decode(charset)) + elif ct != 'application/x-www-form-urlencoded': + if strict: + return content + charset = options.get('charset', 'utf-8') + return url_decode(content, charset=charset).to_dict() + + +def add_query(url, args): + if not args: + return url + return url + ('?' in url and '&' or '?') + url_encode(args) + + +def encode_request_data(data, format): + if format is None: + return data, None + elif format == 'json': + return json.dumps(data or {}), 'application/json' + elif format == 'urlencoded': + return url_encode(data or {}), 'application/x-www-form-urlencoded' + raise TypeError('Unknown format %r' % format) + + +class OAuthResponse(object): + """Contains the response sent back from an OAuth protected remote + application. + """ + + def __init__(self, resp, content): + #: a :class:`~werkzeug.Headers` object with the response headers + #: the application sent. + self.headers = Headers(resp) + #: the raw, unencoded content from the server + self.raw_data = content + #: the parsed content from the server + self.data = parse_response(resp, content, strict=True) + + @property + def status(self): + """The status code of the response.""" + return self.headers.get('status', type=int) + + +class OAuthClient(oauth2.Client): + + def request_new_token(self, uri, callback=None, params={}): + if callback is not None: + params['oauth_callback'] = callback + req = oauth2.Request.from_consumer_and_token( + self.consumer, token=self.token, + http_method='POST', http_url=uri, parameters=params, + is_form_encoded=True) + req.sign_request(self.method, self.consumer, self.token) + body = req.to_postdata() + headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': str(len(body)) + } + return httplib2.Http.request(self, uri, method='POST', + body=body, headers=headers) + + +class OAuthException(RuntimeError): + """Raised if authorization fails for some reason.""" + message = None + type = None + + def __init__(self, message, type=None, data=None): + #: A helpful error message for debugging + self.message = message + #: A unique type for this exception if available. + self.type = type + #: If available, the parsed data from the remote API that can be + #: used to pointpoint the error. + self.data = data + + def __str__(self): + return self.message.encode('utf-8') + + def __unicode__(self): + return self.message + + +class OAuth(object): + """Registry for remote applications. In the future this will also + be the central class for OAuth provider functionality. + """ + + def __init__(self): + self.remote_apps = {} + + def remote_app(self, name, register=True, **kwargs): + """Registers a new remote applicaton. If `param` register is + set to `False` the application is not registered in the + :attr:`remote_apps` dictionary. The keyword arguments are + forwarded to the :class:`OAuthRemoteApp` consturctor. + """ + app = OAuthRemoteApp(self, name, **kwargs) + if register: + assert name not in self.remote_apps, \ + 'application already registered' + self.remote_apps[name] = app + return app + + +class OAuthRemoteApp(object): + """Represents a remote application. + + :param oauth: the associated :class:`OAuth` object. + :param name: then name of the remote application + :param request_token_url: the URL for requesting new tokens + :param access_token_url: the URL for token exchange + :param authorize_url: the URL for authorization + :param consumer_key: the application specific consumer key + :param consumer_secret: the application specific consumer secret + :param request_token_params: an optional dictionary of parameters + to forward to the request token URL + or authorize URL depending on oauth + version. + :param access_token_params: an option diction of parameters to forward to + the access token URL + :param access_token_method: the HTTP method that should be used + for the access_token_url. Defaults + to ``'GET'``. + """ + + def __init__(self, oauth, name, base_url, + request_token_url, + access_token_url, authorize_url, + consumer_key, consumer_secret, + request_token_params=None, + access_token_params=None, + access_token_method='GET'): + self.oauth = oauth + #: the `base_url` all URLs are joined with. + self.base_url = base_url + self.name = name + self.request_token_url = request_token_url + self.access_token_url = access_token_url + self.authorize_url = authorize_url + self.consumer_key = consumer_key + self.consumer_secret = consumer_secret + self.tokengetter_func = None + self.request_token_params = request_token_params or {} + self.access_token_params = access_token_params or {} + self.access_token_method = access_token_method + self._consumer = oauth2.Consumer(self.consumer_key, + self.consumer_secret) + self._client = OAuthClient(self._consumer) + + def status_okay(self, resp): + """Given request data, checks if the status is okay.""" + try: + return int(resp['status']) in (200, 201) + except ValueError: + return False + + def get(self, *args, **kwargs): + """Sends a ``GET`` request. Accepts the same parameters as + :meth:`request`. + """ + kwargs['method'] = 'GET' + return self.request(*args, **kwargs) + + def post(self, *args, **kwargs): + """Sends a ``POST`` request. Accepts the same parameters as + :meth:`request`. + """ + kwargs['method'] = 'POST' + return self.request(*args, **kwargs) + + def put(self, *args, **kwargs): + """Sends a ``PUT`` request. Accepts the same parameters as + :meth:`request`. + """ + kwargs['method'] = 'PUT' + return self.request(*args, **kwargs) + + def delete(self, *args, **kwargs): + """Sends a ``DELETE`` request. Accepts the same parameters as + :meth:`request`. + """ + kwargs['method'] = 'DELETE' + return self.request(*args, **kwargs) + + def make_client(self, token=None): + """Creates a new `oauth2` Client object with the token attached. + Usually you don't have to do that but use the :meth:`request` + method instead. + """ + return oauth2.Client(self._consumer, self.get_request_token(token)) + + def request(self, url, data="", headers=None, format='urlencoded', + method='GET', content_type=None, token=None): + """Sends a request to the remote server with OAuth tokens attached. + The `url` is joined with :attr:`base_url` if the URL is relative. + + .. versionadded:: 0.12 + added the `token` parameter. + + :param url: where to send the request to + :param data: the data to be sent to the server. If the request method + is ``GET`` the data is appended to the URL as query + parameters, otherwise encoded to `format` if the format + is given. If a `content_type` is provided instead, the + data must be a string encoded for the given content + type and used as request body. + :param headers: an optional dictionary of headers. + :param format: the format for the `data`. Can be `urlencoded` for + URL encoded data or `json` for JSON. + :param method: the HTTP request method to use. + :param content_type: an optional content type. If a content type is + provided, the data is passed as it and the + `format` parameter is ignored. + :param token: an optional token to pass to tokengetter. Use this if you + want to support sending requests using multiple tokens. + If you set this to anything not None, `tokengetter_func` + will receive the given token as an argument, in which case + the tokengetter should return the `(token, secret)` tuple + for the given token. + :return: an :class:`OAuthResponse` object. + """ + headers = dict(headers or {}) + client = self.make_client(token) + url = self.expand_url(url) + if method == 'GET': + assert format == 'urlencoded' + if data: + url = add_query(url, data) + data = "" + else: + if content_type is None: + data, content_type = encode_request_data(data, format) + if content_type is not None: + headers['Content-Type'] = content_type + return OAuthResponse(*client.request(url, method=method, + body=data or '', + headers=headers)) + + def expand_url(self, url): + return urljoin(self.base_url, url) + + def generate_request_token(self, callback=None): + if callback is not None: + callback = urljoin(request.url, callback) + resp, content = self._client.request_new_token( + self.expand_url(self.request_token_url), callback, + self.request_token_params) + if not self.status_okay(resp): + raise OAuthException('Failed to generate request token', + type='token_generation_failed') + data = parse_response(resp, content) + if data is None: + raise OAuthException('Invalid token response from ' + self.name, + type='token_generation_failed') + tup = (data['oauth_token'], data['oauth_token_secret']) + session[self.name + '_oauthtok'] = tup + return tup + + def get_request_token(self, token=None): + assert self.tokengetter_func is not None, 'missing tokengetter function' + # Don't pass the token if the token is None to support old + # tokengetter functions. + rv = self.tokengetter_func(*(token and (token,) or ())) + if rv is None: + rv = session.get(self.name + '_oauthtok') + if rv is None: + raise OAuthException('No token available', type='token_missing') + return oauth2.Token(*rv) + + def free_request_token(self): + session.pop(self.name + '_oauthtok', None) + session.pop(self.name + '_oauthredir', None) + + def authorize(self, callback=None): + """Returns a redirect response to the remote authorization URL with + the signed callback given. The callback must be `None` in which + case the application will most likely switch to PIN based authentication + or use a remotely stored callback URL. Alternatively it's an URL + on the system that has to be decorated as :meth:`authorized_handler`. + """ + if self.request_token_url: + token = self.generate_request_token(callback)[0] + url = '%s?oauth_token=%s' % (self.expand_url(self.authorize_url), + url_quote(token)) + else: + assert callback is not None, 'Callback is required OAuth2' + # This is for things like facebook's oauth. Since we need the + # callback for the access_token_url we need to keep it in the + # session. + params = dict(self.request_token_params) + params['redirect_uri'] = callback + params['client_id'] = self.consumer_key + params['response_type'] = 'code' + session[self.name + '_oauthredir'] = callback + url = add_query(self.expand_url(self.authorize_url), params) + + return redirect(url) + + def tokengetter(self, f): + """Registers a function as tokengetter. The tokengetter has to return + a tuple of ``(token, secret)`` with the user's token and token secret. + If the data is unavailable, the function must return `None`. + + If the `token` parameter is passed to the request function it's + forwarded to the tokengetter function:: + + @oauth.tokengetter + def get_token(token='user'): + if token == 'user': + return find_the_user_token() + elif token == 'app': + return find_the_app_token() + raise RuntimeError('invalid token') + """ + self.tokengetter_func = f + return f + + def handle_oauth1_response(self): + """Handles an oauth1 authorization response. The return value of + this method is forwarded as first argument to the handling view + function. + """ + client = self.make_client() + resp, content = client.request('%s?oauth_verifier=%s' % ( + self.expand_url(self.access_token_url), + request.args['oauth_verifier'] + ), self.access_token_method) + data = parse_response(resp, content) + if not self.status_okay(resp): + raise OAuthException('Invalid response from ' + self.name, + type='invalid_response', data=data) + return data + + def handle_oauth2_response(self): + """Handles an oauth2 authorization response. The return value of + this method is forwarded as first argument to the handling view + function. + """ + remote_args = { + 'code': request.args.get('code'), + 'client_id': self.consumer_key, + 'client_secret': self.consumer_secret, + 'redirect_uri': session.get(self.name + '_oauthredir') + } + remote_args.update(self.access_token_params) + if self.access_token_method == 'POST': + resp, content = self._client.request(self.expand_url(self.access_token_url), + self.access_token_method, + url_encode(remote_args)) + elif self.access_token_method == 'GET': + url = add_query(self.expand_url(self.access_token_url), remote_args) + resp, content = self._client.request(url, self.access_token_method) + else: + raise OAuthException('Unsupported access_token_method: ' + + self.access_token_method) + data = parse_response(resp, content) + if not self.status_okay(resp): + raise OAuthException('Invalid response from ' + self.name, + type='invalid_response', data=data) + return data + + def handle_unknown_response(self): + """Called if an unknown response came back from the server. This + usually indicates a denied response. The default implementation + just returns `None`. + """ + return None + + def authorized_handler(self, f): + """Injects additional authorization functionality into the function. + The function will be passed the response object as first argument + if the request was allowed, or `None` if access was denied. When the + authorized handler is called, the temporary issued tokens are already + destroyed. + """ + @wraps(f) + def decorated(*args, **kwargs): + if 'oauth_verifier' in request.args: + data = self.handle_oauth1_response() + elif 'code' in request.args: + data = self.handle_oauth2_response() + else: + data = self.handle_unknown_response() + self.free_request_token() + return f(*((data,) + args), **kwargs) + return decorated diff --git a/lastuser_oauth/providers/twitter.py b/lastuser_oauth/providers/twitter.py index d9aafad..637824e 100644 --- a/lastuser_oauth/providers/twitter.py +++ b/lastuser_oauth/providers/twitter.py @@ -6,7 +6,7 @@ from socket import gaierror from ssl import SSLError -from flask_oauth import OAuth, OAuthException # OAuth 1.0a +from .flask_oauth import OAuth, OAuthException # OAuth 1.0a from tweepy import API as TwitterAPI # NOQA: N811 from tweepy import OAuthHandler as TwitterOAuthHandler from tweepy import TweepError diff --git a/lastuser_oauth/views/login.py b/lastuser_oauth/views/login.py index 1cf5776..d51bacf 100644 --- a/lastuser_oauth/views/login.py +++ b/lastuser_oauth/views/login.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- - - from datetime import timedelta import urllib.parse @@ -57,9 +55,7 @@ def openid_log(message, level=0): if current_app.debug: - import sys - - print(message, file=sys.stderr) # NOQA: T001 + print(message) oidutil.log = openid_log diff --git a/runserver.py b/runserver.py index 403cbff..2e44837 100755 --- a/runserver.py +++ b/runserver.py @@ -1,10 +1,5 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -import sys - -reload(sys) -sys.setdefaultencoding('utf-8') - from lastuserapp import app # isort:skip app.run('0.0.0.0', 7000) diff --git a/runtestserver.py b/runtestserver.py index e4dd2ec..6598882 100644 --- a/runtestserver.py +++ b/runtestserver.py @@ -1,10 +1,5 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -import sys - -reload(sys) -sys.setdefaultencoding('utf-8') - from lastuser_core.models import Client, Organization, Permission, User # isort:skip from lastuserapp import app, db # isort:skip From fd670bc48f34ae7105ff3b989db40d86315593ba Mon Sep 17 00:00:00 2001 From: Kiran Jonnalagadda Date: Thu, 13 Feb 2020 14:02:20 +0530 Subject: [PATCH 03/10] Fix werkzeug imports --- lastuser_core/models/session.py | 2 +- lastuser_core/models/user.py | 3 ++- lastuser_oauth/providers/flask_oauth.py | 5 +++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lastuser_core/models/session.py b/lastuser_core/models/session.py index c628f6b..0c050c4 100644 --- a/lastuser_core/models/session.py +++ b/lastuser_core/models/session.py @@ -3,7 +3,7 @@ from datetime import timedelta from flask import request -from werkzeug import cached_property +from werkzeug.utils import cached_property from ua_parser import user_agent_parser diff --git a/lastuser_core/models/user.py b/lastuser_core/models/user.py index 900b901..c329057 100644 --- a/lastuser_core/models/user.py +++ b/lastuser_core/models/user.py @@ -7,7 +7,8 @@ from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.orm import defer, deferred -from werkzeug import cached_property, check_password_hash +from werkzeug.security import check_password_hash +from werkzeug.utils import cached_property import bcrypt import phonenumbers diff --git a/lastuser_oauth/providers/flask_oauth.py b/lastuser_oauth/providers/flask_oauth.py index c3f6d1d..aecf6c4 100644 --- a/lastuser_oauth/providers/flask_oauth.py +++ b/lastuser_oauth/providers/flask_oauth.py @@ -12,8 +12,9 @@ from functools import wraps from urllib.parse import urljoin from flask import request, session, json, redirect, Response -from werkzeug import url_decode, url_encode, url_quote, \ - parse_options_header, Headers +from werkzeug.urls import url_decode, url_encode, url_quote +from werkzeug.http import parse_options_header +from werkzeug.datastructures import Headers import oauth2 From 6eb1f3c6b1c48ae93af2f077c29db2def8b8eefc Mon Sep 17 00:00:00 2001 From: Kiran Jonnalagadda Date: Thu, 13 Feb 2020 14:18:24 +0530 Subject: [PATCH 04/10] Reformat all files with black --- instance/settings-sample.py | 4 +- instance/testing.py | 4 +- lastuser_core/models/client.py | 6 +- lastuser_core/models/session.py | 2 +- lastuser_core/models/user.py | 2 +- lastuser_oauth/providers/flask_oauth.py | 152 +++++++++++------- lastuser_oauth/providers/google.py | 1 - lastuser_oauth/providers/openid.py | 1 - lastuser_oauth/providers/twitter.py | 3 +- lastuser_oauth/views/helpers.py | 3 +- lastuser_oauth/views/login.py | 2 +- lastuser_oauth/views/resource.py | 11 +- lastuser_ui/views/dashboard.py | 4 +- lastuser_ui/views/org.py | 5 +- lastuser_ui/views/profile.py | 4 +- migrations/env.py | 2 +- pyproject.toml | 2 +- tests/unit/lastuser_core/fixtures.py | 4 +- .../test_model_user_Organization.py | 12 +- .../test_model_user_UserExternalId.py | 1 - tests/unit/lastuser_core/test_models.py | 4 +- tests/unit/lastuser_core/test_utils.py | 7 +- 22 files changed, 127 insertions(+), 109 deletions(-) diff --git a/instance/settings-sample.py b/instance/settings-sample.py index 6afc2d7..7d79d1c 100644 --- a/instance/settings-sample.py +++ b/instance/settings-sample.py @@ -135,7 +135,9 @@ USERNAME_REASON = '' EMAIL_REASON = 'Please provide an email address to complete your profile' TIMEZONE_REASON = 'Dates and times will be shown in your preferred timezone' -ORG_NAME_REASON = "Your company’s name as it will appear in the URL. Letters, numbers and dashes only" +ORG_NAME_REASON = ( + "Your company’s name as it will appear in the URL. Letters, numbers and dashes only" +) ORG_TITLE_REASON = "Your organization’s given name, preferably without legal suffixes" LOGIN_MESSAGE_1 = "" LOGIN_MESSAGE_2 = "" diff --git a/instance/testing.py b/instance/testing.py index 0df0977..65744a6 100644 --- a/instance/testing.py +++ b/instance/testing.py @@ -99,7 +99,9 @@ EMAIL_REASON = 'Please provide an email address to complete your profile' BIO_REASON = '' TIMEZONE_REASON = 'Dates and times will be shown in your preferred timezone' -ORG_NAME_REASON = "Your company’s name as it will appear in the URL. Letters, numbers and dashes only" +ORG_NAME_REASON = ( + "Your company’s name as it will appear in the URL. Letters, numbers and dashes only" +) ORG_TITLE_REASON = "Your organization’s given name, preferably without legal suffixes" ORG_DESCRIPTION_REASON = ( "A few words about your organization (optional). Plain text only" diff --git a/lastuser_core/models/client.py b/lastuser_core/models/client.py index 5bb8520..3493311 100644 --- a/lastuser_core/models/client.py +++ b/lastuser_core/models/client.py @@ -157,10 +157,10 @@ def redirect_uri(self): def host_matches(self, url): netloc = urllib.parse.urlsplit(url or '').netloc if netloc: - return netloc in [ + return netloc in ( urllib.parse.urlsplit(r).netloc - for r in list(self.redirect_uris) + [self.website] - ] + for r in (self.redirect_uris + (self.website,)) + ) return False @property diff --git a/lastuser_core/models/session.py b/lastuser_core/models/session.py index 0c050c4..6d20689 100644 --- a/lastuser_core/models/session.py +++ b/lastuser_core/models/session.py @@ -39,7 +39,7 @@ primary_key=True, ), ) - ) + ), ) diff --git a/lastuser_core/models/user.py b/lastuser_core/models/user.py index c329057..9bb6f75 100644 --- a/lastuser_core/models/user.py +++ b/lastuser_core/models/user.py @@ -674,7 +674,7 @@ def get(cls, uuid): primary_key=True, ), ) - ) + ), ) diff --git a/lastuser_oauth/providers/flask_oauth.py b/lastuser_oauth/providers/flask_oauth.py index aecf6c4..6b0c971 100644 --- a/lastuser_oauth/providers/flask_oauth.py +++ b/lastuser_oauth/providers/flask_oauth.py @@ -8,17 +8,20 @@ :copyright: (c) 2010 by Armin Ronacher. :license: BSD, see LICENSE for more details. """ -import httplib2 from functools import wraps from urllib.parse import urljoin -from flask import request, session, json, redirect, Response -from werkzeug.urls import url_decode, url_encode, url_quote -from werkzeug.http import parse_options_header + +from flask import json, redirect, request, session from werkzeug.datastructures import Headers -import oauth2 +from werkzeug.http import parse_options_header +from werkzeug.urls import url_decode, url_encode, url_quote +import httplib2 +import oauth2 _etree = None + + def get_etree(): """Return an elementtree implementation. Prefers lxml""" global _etree @@ -27,10 +30,10 @@ def get_etree(): from lxml import etree as _etree except ImportError: try: - from xml.etree import cElementTree as _etree + from xml.etree import cElementTree as _etree # noqa: N813 except ImportError: try: - from xml.etree import ElementTree as _etree + from xml.etree import ElementTree as _etree # noqa: N813 except ImportError: raise TypeError('lxml or etree not found') return _etree @@ -60,7 +63,7 @@ def add_query(url, args): return url + ('?' in url and '&' or '?') + url_encode(args) -def encode_request_data(data, format): +def encode_request_data(data, format): # noqa: A002 if format is None: return data, None elif format == 'json': @@ -91,30 +94,35 @@ def status(self): class OAuthClient(oauth2.Client): - def request_new_token(self, uri, callback=None, params={}): if callback is not None: params['oauth_callback'] = callback req = oauth2.Request.from_consumer_and_token( - self.consumer, token=self.token, - http_method='POST', http_url=uri, parameters=params, - is_form_encoded=True) + self.consumer, + token=self.token, + http_method='POST', + http_url=uri, + parameters=params, + is_form_encoded=True, + ) req.sign_request(self.method, self.consumer, self.token) body = req.to_postdata() headers = { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Content-Length': str(len(body)) + 'Content-Type': 'application/x-www-form-urlencoded', + 'Content-Length': str(len(body)), } - return httplib2.Http.request(self, uri, method='POST', - body=body, headers=headers) + return httplib2.Http.request( + self, uri, method='POST', body=body, headers=headers + ) class OAuthException(RuntimeError): """Raised if authorization fails for some reason.""" + message = None - type = None + type = None # noqa: A003 - def __init__(self, message, type=None, data=None): + def __init__(self, message, type=None, data=None): # noqa: A002 #: A helpful error message for debugging self.message = message #: A unique type for this exception if available. @@ -146,8 +154,7 @@ def remote_app(self, name, register=True, **kwargs): """ app = OAuthRemoteApp(self, name, **kwargs) if register: - assert name not in self.remote_apps, \ - 'application already registered' + assert name not in self.remote_apps, 'application already registered' self.remote_apps[name] = app return app @@ -173,13 +180,20 @@ class OAuthRemoteApp(object): to ``'GET'``. """ - def __init__(self, oauth, name, base_url, - request_token_url, - access_token_url, authorize_url, - consumer_key, consumer_secret, - request_token_params=None, - access_token_params=None, - access_token_method='GET'): + def __init__( + self, + oauth, + name, + base_url, + request_token_url, + access_token_url, + authorize_url, + consumer_key, + consumer_secret, + request_token_params=None, + access_token_params=None, + access_token_method='GET', + ): self.oauth = oauth #: the `base_url` all URLs are joined with. self.base_url = base_url @@ -193,8 +207,7 @@ def __init__(self, oauth, name, base_url, self.request_token_params = request_token_params or {} self.access_token_params = access_token_params or {} self.access_token_method = access_token_method - self._consumer = oauth2.Consumer(self.consumer_key, - self.consumer_secret) + self._consumer = oauth2.Consumer(self.consumer_key, self.consumer_secret) self._client = OAuthClient(self._consumer) def status_okay(self, resp): @@ -239,8 +252,16 @@ def make_client(self, token=None): """ return oauth2.Client(self._consumer, self.get_request_token(token)) - def request(self, url, data="", headers=None, format='urlencoded', - method='GET', content_type=None, token=None): + def request( + self, + url, + data="", + headers=None, + format='urlencoded', # noqa: A002 + method='GET', + content_type=None, + token=None, + ): """Sends a request to the remote server with OAuth tokens attached. The `url` is joined with :attr:`base_url` if the URL is relative. @@ -282,9 +303,9 @@ def request(self, url, data="", headers=None, format='urlencoded', data, content_type = encode_request_data(data, format) if content_type is not None: headers['Content-Type'] = content_type - return OAuthResponse(*client.request(url, method=method, - body=data or '', - headers=headers)) + return OAuthResponse( + *client.request(url, method=method, body=data or '', headers=headers) + ) def expand_url(self, url): return urljoin(self.base_url, url) @@ -293,15 +314,18 @@ def generate_request_token(self, callback=None): if callback is not None: callback = urljoin(request.url, callback) resp, content = self._client.request_new_token( - self.expand_url(self.request_token_url), callback, - self.request_token_params) + self.expand_url(self.request_token_url), callback, self.request_token_params + ) if not self.status_okay(resp): - raise OAuthException('Failed to generate request token', - type='token_generation_failed') + raise OAuthException( + 'Failed to generate request token', type='token_generation_failed' + ) data = parse_response(resp, content) if data is None: - raise OAuthException('Invalid token response from ' + self.name, - type='token_generation_failed') + raise OAuthException( + 'Invalid token response from ' + self.name, + type='token_generation_failed', + ) tup = (data['oauth_token'], data['oauth_token_secret']) session[self.name + '_oauthtok'] = tup return tup @@ -330,8 +354,10 @@ def authorize(self, callback=None): """ if self.request_token_url: token = self.generate_request_token(callback)[0] - url = '%s?oauth_token=%s' % (self.expand_url(self.authorize_url), - url_quote(token)) + url = '%s?oauth_token=%s' % ( + self.expand_url(self.authorize_url), + url_quote(token), + ) else: assert callback is not None, 'Callback is required OAuth2' # This is for things like facebook's oauth. Since we need the @@ -371,14 +397,16 @@ def handle_oauth1_response(self): function. """ client = self.make_client() - resp, content = client.request('%s?oauth_verifier=%s' % ( - self.expand_url(self.access_token_url), - request.args['oauth_verifier'] - ), self.access_token_method) + resp, content = client.request( + '%s?oauth_verifier=%s' + % (self.expand_url(self.access_token_url), request.args['oauth_verifier']), + self.access_token_method, + ) data = parse_response(resp, content) if not self.status_okay(resp): - raise OAuthException('Invalid response from ' + self.name, - type='invalid_response', data=data) + raise OAuthException( + 'Invalid response from ' + self.name, type='invalid_response', data=data + ) return data def handle_oauth2_response(self): @@ -387,26 +415,30 @@ def handle_oauth2_response(self): function. """ remote_args = { - 'code': request.args.get('code'), - 'client_id': self.consumer_key, - 'client_secret': self.consumer_secret, - 'redirect_uri': session.get(self.name + '_oauthredir') + 'code': request.args.get('code'), + 'client_id': self.consumer_key, + 'client_secret': self.consumer_secret, + 'redirect_uri': session.get(self.name + '_oauthredir'), } remote_args.update(self.access_token_params) if self.access_token_method == 'POST': - resp, content = self._client.request(self.expand_url(self.access_token_url), - self.access_token_method, - url_encode(remote_args)) + resp, content = self._client.request( + self.expand_url(self.access_token_url), + self.access_token_method, + url_encode(remote_args), + ) elif self.access_token_method == 'GET': url = add_query(self.expand_url(self.access_token_url), remote_args) resp, content = self._client.request(url, self.access_token_method) else: - raise OAuthException('Unsupported access_token_method: ' + - self.access_token_method) + raise OAuthException( + 'Unsupported access_token_method: ' + self.access_token_method + ) data = parse_response(resp, content) if not self.status_okay(resp): - raise OAuthException('Invalid response from ' + self.name, - type='invalid_response', data=data) + raise OAuthException( + 'Invalid response from ' + self.name, type='invalid_response', data=data + ) return data def handle_unknown_response(self): @@ -423,6 +455,7 @@ def authorized_handler(self, f): authorized handler is called, the temporary issued tokens are already destroyed. """ + @wraps(f) def decorated(*args, **kwargs): if 'oauth_verifier' in request.args: @@ -433,4 +466,5 @@ def decorated(*args, **kwargs): data = self.handle_unknown_response() self.free_request_token() return f(*((data,) + args), **kwargs) + return decorated diff --git a/lastuser_oauth/providers/google.py b/lastuser_oauth/providers/google.py index 5423ed1..a58c7ee 100644 --- a/lastuser_oauth/providers/google.py +++ b/lastuser_oauth/providers/google.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- - from flask import redirect, request, session from oauth2client import client diff --git a/lastuser_oauth/providers/openid.py b/lastuser_oauth/providers/openid.py index b6cfed6..3763192 100644 --- a/lastuser_oauth/providers/openid.py +++ b/lastuser_oauth/providers/openid.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- - from flask import Markup, session from baseframe import _, __ diff --git a/lastuser_oauth/providers/twitter.py b/lastuser_oauth/providers/twitter.py index 637824e..477969a 100644 --- a/lastuser_oauth/providers/twitter.py +++ b/lastuser_oauth/providers/twitter.py @@ -6,7 +6,6 @@ from socket import gaierror from ssl import SSLError -from .flask_oauth import OAuth, OAuthException # OAuth 1.0a from tweepy import API as TwitterAPI # NOQA: N811 from tweepy import OAuthHandler as TwitterOAuthHandler from tweepy import TweepError @@ -14,6 +13,8 @@ from baseframe import _ from lastuser_core.registry import LoginCallbackError, LoginInitError, LoginProvider +from .flask_oauth import OAuth, OAuthException # OAuth 1.0a + __all__ = ['TwitterProvider'] diff --git a/lastuser_oauth/views/helpers.py b/lastuser_oauth/views/helpers.py index 9534cc3..bdb21cd 100644 --- a/lastuser_oauth/views/helpers.py +++ b/lastuser_oauth/views/helpers.py @@ -2,8 +2,7 @@ from datetime import timedelta from functools import wraps -from urllib.parse import unquote -from urllib.parse import urlparse +from urllib.parse import unquote, urlparse from flask import Response, current_app, flash, redirect, request, session, url_for import itsdangerous diff --git a/lastuser_oauth/views/login.py b/lastuser_oauth/views/login.py index d51bacf..6b5b418 100644 --- a/lastuser_oauth/views/login.py +++ b/lastuser_oauth/views/login.py @@ -55,7 +55,7 @@ def openid_log(message, level=0): if current_app.debug: - print(message) + print(message) # noqa: T001 oidutil.log = openid_log diff --git a/lastuser_oauth/views/resource.py b/lastuser_oauth/views/resource.py index 76d3f1c..fb3e293 100644 --- a/lastuser_oauth/views/resource.py +++ b/lastuser_oauth/views/resource.py @@ -394,7 +394,8 @@ def sync_resources(): results[resource_name]['actions'][action.name] = {'status': 'deleted'} actions.delete(synchronize_session='fetch') del_resources = Resource.query.filter( - ~Resource.name.in_(list(actions_list.keys())), Resource.client == current_auth.client + ~Resource.name.in_(list(actions_list.keys())), + Resource.client == current_auth.client, ) for resource in del_resources.all(): ResourceAction.query.filter_by(resource=resource).delete( @@ -730,9 +731,7 @@ def resource_email(authtoken, args, files=None): if 'all' in args and getbool(args['all']): return { 'email': str(authtoken.user.email), - 'all': [ - str(email) for email in authtoken.user.emails if not email.private - ], + 'all': [str(email) for email in authtoken.user.emails if not email.private], } else: return {'email': str(authtoken.user.email)} @@ -824,9 +823,7 @@ def resource_organizations_edit(authtoken, args, files=None): @lastuser_oauth.route('/api/1/teams') -@resource_registry.resource( - 'teams', __("Read the list of teams in your organizations") -) +@resource_registry.resource('teams', __("Read the list of teams in your organizations")) def resource_teams(authtoken, args, files=None): """ Return user's organizations' teams. diff --git a/lastuser_ui/views/dashboard.py b/lastuser_ui/views/dashboard.py index ae298ac..a864882 100644 --- a/lastuser_ui/views/dashboard.py +++ b/lastuser_ui/views/dashboard.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from collections import defaultdict -from io import StringIO from functools import wraps +from io import StringIO from flask import abort, current_app, render_template @@ -116,7 +116,7 @@ def dashboard_data_users_by_client(): ) users_by_client = sorted( - list(client_users.values()), key=lambda r: sum(r['counts'].values()), reverse=True + client_users.values(), key=lambda r: sum(r['counts'].values()), reverse=True ) outfile = StringIO() diff --git a/lastuser_ui/views/org.py b/lastuser_ui/views/org.py index b8e0fd5..0d83d53 100644 --- a/lastuser_ui/views/org.py +++ b/lastuser_ui/views/org.py @@ -120,10 +120,7 @@ def new_team(self): team_data_changed.send(team, changes=['new'], user=current_auth.user) return render_redirect(self.obj.url_for('view'), code=303) return render_form( - form=form, - title=_("Create new team"), - formid='new_team', - submit=_("Create"), + form=form, title=_("Create new team"), formid='new_team', submit=_("Create") ) diff --git a/lastuser_ui/views/profile.py b/lastuser_ui/views/profile.py index e30b191..b38ee4f 100644 --- a/lastuser_ui/views/profile.py +++ b/lastuser_ui/views/profile.py @@ -282,9 +282,7 @@ def remove_phone(number): message=_("Remove phone number {phone} from your account?").format( phone=userphone.phone ), - success=_("You have removed your number {phone}").format( - phone=userphone.phone - ), + success=_("You have removed your number {phone}").format(phone=userphone.phone), next=url_for('.account'), delete_text=_("Remove"), ) diff --git a/migrations/env.py b/migrations/env.py index a3519b6..4bab45e 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -81,7 +81,7 @@ def process_revision_directives(context, revision, directives): connection=connection, target_metadata=target_metadata, process_revision_directives=process_revision_directives, - **current_app.extensions['migrate'].configure_args + **current_app.extensions['migrate'].configure_args, ) try: diff --git a/pyproject.toml b/pyproject.toml index 60cb1e4..18a0a99 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ [tool.black] line-length = 88 -target_version = ['py27'] +target_version = ['py37'] skip-string-normalization = true include = '\.pyi?$' exclude = ''' diff --git a/tests/unit/lastuser_core/fixtures.py b/tests/unit/lastuser_core/fixtures.py index 5c75621..e3444ab 100644 --- a/tests/unit/lastuser_core/fixtures.py +++ b/tests/unit/lastuser_core/fixtures.py @@ -90,9 +90,7 @@ def make_fixtures(self): db.session.add(user_client_permissions) self.user_client_permissions = user_client_permissions - resource = Resource( - name="test_resource", title="Test Resource", client=client - ) + resource = Resource(name="test_resource", title="Test Resource", client=client) db.session.add(resource) self.resource = resource diff --git a/tests/unit/lastuser_core/test_model_user_Organization.py b/tests/unit/lastuser_core/test_model_user_Organization.py index 4806fc3..1ba2d73 100644 --- a/tests/unit/lastuser_core/test_model_user_Organization.py +++ b/tests/unit/lastuser_core/test_model_user_Organization.py @@ -67,15 +67,15 @@ def test_organization_get(self): # scenario 3: when username is passed get_by_name = models.Organization.get(name=name) self.assertIsInstance(get_by_name, models.Organization) - assert ''.format( - name=name, title=title - ) in repr(get_by_name) + assert ''.format(name=name, title=title) in repr( + get_by_name + ) # scenario 4: when defercols is set to True get_by_name_with_defercols = models.Organization.get(name=name, defercols=True) self.assertIsInstance(get_by_name_with_defercols, models.Organization) - assert ''.format( - name=name, title=title - ) in repr(get_by_name_with_defercols) + assert ''.format(name=name, title=title) in repr( + get_by_name_with_defercols + ) def test_organization_all(self): """ diff --git a/tests/unit/lastuser_core/test_model_user_UserExternalId.py b/tests/unit/lastuser_core/test_model_user_UserExternalId.py index 84e7e73..24cdfa8 100644 --- a/tests/unit/lastuser_core/test_model_user_UserExternalId.py +++ b/tests/unit/lastuser_core/test_model_user_UserExternalId.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- - from os import environ from lastuserapp import db diff --git a/tests/unit/lastuser_core/test_models.py b/tests/unit/lastuser_core/test_models.py index 12150da..3888638 100644 --- a/tests/unit/lastuser_core/test_models.py +++ b/tests/unit/lastuser_core/test_models.py @@ -28,9 +28,7 @@ def test_merge_users(self): tyrion = models.User(username='tyrion', fullname="Tyrion Lannister") db.session.add(tyrion) db.session.commit() - subramanian = models.User( - username='subramanian', fullname="Tyrion Subramanian" - ) + subramanian = models.User(username='subramanian', fullname="Tyrion Subramanian") db.session.add(subramanian) db.session.commit() merged = models.merge_users(subramanian, tyrion) diff --git a/tests/unit/lastuser_core/test_utils.py b/tests/unit/lastuser_core/test_utils.py index 491f9f5..15984a3 100644 --- a/tests/unit/lastuser_core/test_utils.py +++ b/tests/unit/lastuser_core/test_utils.py @@ -2,12 +2,7 @@ import unittest -from lastuser_core.utils import ( - make_redirect_url, - mask_email, - strip_phone, - valid_phone, -) +from lastuser_core.utils import make_redirect_url, mask_email, strip_phone, valid_phone class FlaskrTestCase(unittest.TestCase): From 196a99c199767ed9245f420e7bb5db77d252aaf8 Mon Sep 17 00:00:00 2001 From: Bibhas Date: Fri, 14 Feb 2020 17:37:21 +0530 Subject: [PATCH 05/10] fixed unit tests --- lastuser_core/models/client.py | 7 +++- lastuser_core/models/user.py | 4 +- tests/unit/lastuser_core/fixtures.py | 4 +- .../test_model_client_AuthToken.py | 12 +++--- .../lastuser_core/test_model_client_Client.py | 8 ++-- .../test_model_client_Permission.py | 2 +- .../test_model_client_ResourceAction.py | 2 +- .../test_model_user_Organization.py | 33 ++++++--------- .../lastuser_core/test_model_user_Team.py | 7 ++-- .../lastuser_core/test_model_user_User.py | 40 +++++++++---------- .../test_model_user_UserEmailClaim.py | 4 +- .../test_model_user_UserPhoneClaim.py | 4 +- .../test_registry_LoginProviderRegistry.py | 2 +- .../lastuser_core/test_session_UserSession.py | 2 +- 14 files changed, 62 insertions(+), 69 deletions(-) diff --git a/lastuser_core/models/client.py b/lastuser_core/models/client.py index 3493311..42ad3f9 100644 --- a/lastuser_core/models/client.py +++ b/lastuser_core/models/client.py @@ -256,7 +256,10 @@ class ClientCredential(BaseMixin, db.Model): accessed_at = db.Column(db.TIMESTAMP(timezone=True), nullable=True) def secret_is(self, candidate): - return self.secret_hash == 'sha256$' + sha256(candidate).hexdigest() + return ( + self.secret_hash + == 'sha256$' + sha256(candidate.encode('utf-8')).hexdigest() + ) @classmethod def get(cls, name): @@ -273,7 +276,7 @@ def new(cls, client): cred = cls(client=client, name=buid()) db.session.add(cred) secret = newsecret() - cred.secret_hash = 'sha256$' + sha256(secret).hexdigest() + cred.secret_hash = 'sha256$' + sha256(secret.encode('utf-8')).hexdigest() return cred, secret diff --git a/lastuser_core/models/user.py b/lastuser_core/models/user.py index 9bb6f75..266552e 100644 --- a/lastuser_core/models/user.py +++ b/lastuser_core/models/user.py @@ -310,7 +310,9 @@ def _set_password(self, password): if password is None: self.pw_hash = None else: - self.pw_hash = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()) + self.pw_hash = bcrypt.hashpw( + password.encode('utf-8'), bcrypt.gensalt() + ).decode('utf-8') self.pw_set_at = db.func.utcnow() # Expire passwords after one year. TODO: make this configurable self.pw_expires_at = self.pw_set_at + timedelta(days=365) diff --git a/tests/unit/lastuser_core/fixtures.py b/tests/unit/lastuser_core/fixtures.py index e3444ab..963daca 100644 --- a/tests/unit/lastuser_core/fixtures.py +++ b/tests/unit/lastuser_core/fixtures.py @@ -37,9 +37,9 @@ def make_fixtures(self): self.nameless = nameless crusoe_email = UserEmail( - email="crusoe@keepballin.ca", primary=True, user=crusoe + email="crusoe@keepballin.ca", user=crusoe, primary=True ) - crusoe_phone = UserPhone(phone="+8080808080", primary=True, user=crusoe) + crusoe_phone = UserPhone(phone="+8080808080", user=crusoe, primary=True) oakley_email = UserEmail(email="huh@keepballin.ca", user=oakley) db.session.add_all([crusoe_email, crusoe_phone, oakley_email]) self.crusoe_email = crusoe_email diff --git a/tests/unit/lastuser_core/test_model_client_AuthToken.py b/tests/unit/lastuser_core/test_model_client_AuthToken.py index 53e0791..d052bbd 100644 --- a/tests/unit/lastuser_core/test_model_client_AuthToken.py +++ b/tests/unit/lastuser_core/test_model_client_AuthToken.py @@ -128,14 +128,14 @@ def test_authtoken_all(self): result1 = models.AuthToken.all(pottermania.owners.users) self.assertIsInstance(result1, list) self.assertIsInstance(result1[0], models.AuthToken) - self.assertItemsEqual(result1, [herminone_token]) + self.assertCountEqual(result1, [herminone_token]) # scenario 1 and count > 1 result2 = models.AuthToken.all(pottermania.members.users) self.assertIsInstance(result2, list) for each in result2: self.assertIsInstance(each, models.AuthToken) - self.assertItemsEqual( + self.assertCountEqual( result2, [herminone_token, alastor_token, greyback_token, myrtle_token] ) @@ -151,14 +151,14 @@ def test_authtoken_all(self): result3 = models.AuthToken.all([lily]) self.assertIsInstance(result3, list) self.assertIsInstance(result3[0], models.AuthToken) - self.assertItemsEqual(result3, [lily_token]) + self.assertCountEqual(result3, [lily_token]) # scenario 2 and count > 1 result4 = models.AuthToken.all([lily, cho]) self.assertIsInstance(result4, list) for each in result4: self.assertIsInstance(each, models.AuthToken) - self.assertItemsEqual(result4, [lily_token, cho_token]) + self.assertCountEqual(result4, [lily_token, cho_token]) # scenario 5: When user instances passed don't have any AuthToken against them oakley = self.fixtures.oakley @@ -209,7 +209,7 @@ def test_authtoken_user(self): # # Scenario: When only one user has authtokens associated with them # models.AuthToken.migrate_user(piglet, naughtymonkey) # scope_received_piglet = models.AuthToken.get(token).scope - # self.assertItemsEqual(scope_received_piglet, tuple(scope_piglet)) + # self.assertCountEqual(scope_received_piglet, tuple(scope_piglet)) # # # Scenario: There's a existing token for newuser with the same client, # # then we expect to: newtoken to have extended scope @@ -220,7 +220,7 @@ def test_authtoken_user(self): # models.AuthToken.migrate_user(piglet, piggles) # scope_received = models.AuthToken.get(another_auth_token.token).scope # scope_expected = tuple(set(scope_piglet + scope_piggles)) - # self.assertItemsEqual(scope_received, scope_expected) + # self.assertCountEqual(scope_received, scope_expected) def test_authtoken_algorithm(self): """ diff --git a/tests/unit/lastuser_core/test_model_client_Client.py b/tests/unit/lastuser_core/test_model_client_Client.py index 6ba6f69..b2239ff 100644 --- a/tests/unit/lastuser_core/test_model_client_Client.py +++ b/tests/unit/lastuser_core/test_model_client_Client.py @@ -67,7 +67,7 @@ def test_client_permissions(self): self.assertIsInstance(result, set) for each in result: permissions_received.append(each) - self.assertItemsEqual(permissions_expected_to_be_added, permissions_received) + self.assertCountEqual(permissions_expected_to_be_added, permissions_received) def test_client_authtoken_for(self): """ @@ -83,7 +83,7 @@ def test_client_authtoken_for(self): result = client.authtoken_for(user=crusoe) self.assertEqual(client_token, result) self.assertIsInstance(result, models.AuthToken) - assert "Crusoe Celebrity Dachshund" in repr(result) + assert result.user == crusoe # scenario 2: for a client that has confidential=False varys = models.User(username='varys', fullname='Lord Varys') @@ -112,7 +112,7 @@ def test_client_authtoken_for(self): db.session.commit() result = house_lannisters.authtoken_for(varys, user_session=varys_session) self.assertIsInstance(result, models.AuthToken) - assert "Lord Varys" in repr(result) + assert "Lord Varys" == result.user.fullname def test_client_orgs_with_team_access(self): """ @@ -122,7 +122,7 @@ def test_client_orgs_with_team_access(self): client = self.fixtures.client result = client.orgs_with_team_access() self.assertIsInstance(result, list) - self.assertItemsEqual(result, [batdog]) + self.assertCountEqual(result, [batdog]) def test_client_get(self): """ diff --git a/tests/unit/lastuser_core/test_model_client_Permission.py b/tests/unit/lastuser_core/test_model_client_Permission.py index 891318a..47c264a 100644 --- a/tests/unit/lastuser_core/test_model_client_Permission.py +++ b/tests/unit/lastuser_core/test_model_client_Permission.py @@ -81,4 +81,4 @@ def test_permission_permissions(self): permissions_received = [] for each in result: permissions_received.append(each) - self.assertItemsEqual(permissions_expected_to_be_added, permissions_received) + self.assertCountEqual(permissions_expected_to_be_added, permissions_received) diff --git a/tests/unit/lastuser_core/test_model_client_ResourceAction.py b/tests/unit/lastuser_core/test_model_client_ResourceAction.py index b8f7458..3291679 100644 --- a/tests/unit/lastuser_core/test_model_client_ResourceAction.py +++ b/tests/unit/lastuser_core/test_model_client_ResourceAction.py @@ -22,7 +22,7 @@ def test_resourceaction_permissions(self): expected_permissions = ['edit', 'delete'] received_permissions = resource_action.permissions(crusoe) self.assertIsInstance(received_permissions, set) - self.assertItemsEqual(received_permissions, expected_permissions) + self.assertCountEqual(received_permissions, expected_permissions) def test_resourceaction_get(self): """ diff --git a/tests/unit/lastuser_core/test_model_user_Organization.py b/tests/unit/lastuser_core/test_model_user_Organization.py index 1ba2d73..13b6f69 100644 --- a/tests/unit/lastuser_core/test_model_user_Organization.py +++ b/tests/unit/lastuser_core/test_model_user_Organization.py @@ -39,12 +39,8 @@ def test_organization_make_teams(self): dachsunited.owners.users.append(crusoe) dachsunited.members.users.append(oakley) dachsunited.members.users.append(piglet) - assert ''.format( - name=name, title=title - ) in repr(dachsunited.owners) - assert ''.format( - name=name, title=title - ) in repr(dachsunited.members) + assert title == dachsunited.owners.org.title + assert title == dachsunited.members.org.title def test_organization_get(self): """ @@ -62,20 +58,15 @@ def test_organization_get(self): buid = spew.buid get_by_buid = models.Organization.get(buid=buid) self.assertIsInstance(get_by_buid, models.Organization) - assert ''.format(title=title) in repr(get_by_buid) + assert title == get_by_buid.title # scenario 3: when username is passed get_by_name = models.Organization.get(name=name) self.assertIsInstance(get_by_name, models.Organization) - assert ''.format(name=name, title=title) in repr( - get_by_name - ) + assert title == get_by_name.title # scenario 4: when defercols is set to True get_by_name_with_defercols = models.Organization.get(name=name, defercols=True) self.assertIsInstance(get_by_name_with_defercols, models.Organization) - assert ''.format(name=name, title=title) in repr( - get_by_name_with_defercols - ) + assert title == get_by_name_with_defercols.title def test_organization_all(self): """ @@ -93,20 +84,20 @@ def test_organization_all(self): orgids = [gryffindor.buid, ravenclaw.buid] all_by_buids = models.Organization.all(buids=orgids) self.assertIsInstance(all_by_buids, list) - self.assertItemsEqual(all_by_buids, orglist) + self.assertCountEqual(all_by_buids, orglist) # scenario 3: when org names are passed names = [gryffindor.name, ravenclaw.name] all_by_names = models.Organization.all(names=names) self.assertIsInstance(all_by_names, list) - self.assertItemsEqual(all_by_names, orglist) + self.assertCountEqual(all_by_names, orglist) # scenario 4: when defercols is set to True for names all_by_names_with_defercols = models.Organization.all(names=names) self.assertIsInstance(all_by_names_with_defercols, list) - self.assertItemsEqual(all_by_names_with_defercols, orglist) + self.assertCountEqual(all_by_names_with_defercols, orglist) # scenario 5: when defercols is set to True for buids all_by_buids_with_defercols = models.Organization.all(buids=orgids) self.assertIsInstance(all_by_buids_with_defercols, list) - self.assertItemsEqual(all_by_buids_with_defercols, orglist) + self.assertCountEqual(all_by_buids_with_defercols, orglist) def test_organization_valid_name(self): """ @@ -152,7 +143,7 @@ def test_organization_permissions(self): valid_permissions_received = [] for each in crusoe_query: valid_permissions_received.append(each) - self.assertItemsEqual(permissions_expected, valid_permissions_received) + self.assertCountEqual(permissions_expected, valid_permissions_received) # scenario 2: if user is not owner oakley_permission = models.Permission(name="huh", title="Huh!?", user=oakley) perms = oakley_permission.permissions(user=oakley) @@ -179,7 +170,7 @@ def test_organization_available_permissions(self): db.session.commit() org_with_permissions = specialdachs.available_permissions() self.assertIsInstance(org_with_permissions, list) - self.assertItemsEqual(org_with_permissions, [netizens]) + self.assertCountEqual(org_with_permissions, [netizens]) def test_organization_name(self): """ @@ -200,4 +191,4 @@ def test_organization_clients_with_team_access(self): """ client = self.fixtures.client batdog = self.fixtures.batdog - self.assertItemsEqual(batdog.clients_with_team_access(), [client]) + self.assertCountEqual(batdog.clients_with_team_access(), [client]) diff --git a/tests/unit/lastuser_core/test_model_user_Team.py b/tests/unit/lastuser_core/test_model_user_Team.py index 3406e18..04c0fec 100644 --- a/tests/unit/lastuser_core/test_model_user_Team.py +++ b/tests/unit/lastuser_core/test_model_user_Team.py @@ -13,9 +13,8 @@ def test_team_get(self): dachshunds = self.fixtures.dachshunds dachshunds_buid = dachshunds.buid result_with_buid = models.Team.get(buid=dachshunds_buid) - assert ''.format( - team=dachshunds.title, org=repr(dachshunds.org)[1:-1] - ) in repr(result_with_buid) + assert dachshunds.title == result_with_buid.title + assert dachshunds.org == result_with_buid.org with self.assertRaises(TypeError): models.Team.get() @@ -41,7 +40,7 @@ def test_team_permissions(self): permissions_received = [] for each in result: permissions_received.append(each) - self.assertItemsEqual(permissions_expected, permissions_received) + self.assertCountEqual(permissions_expected, permissions_received) def test_team_migrate_user(self): """ diff --git a/tests/unit/lastuser_core/test_model_user_User.py b/tests/unit/lastuser_core/test_model_user_User.py index 3e5a9ef..0c065c1 100644 --- a/tests/unit/lastuser_core/test_model_user_User.py +++ b/tests/unit/lastuser_core/test_model_user_User.py @@ -101,7 +101,7 @@ def test_user_organization_owned(self): batdog = self.fixtures.batdog result = crusoe.organizations_owned() self.assertIsInstance(result, list) - self.assertItemsEqual(result, [batdog]) + self.assertCountEqual(result, [batdog]) def test_user_organizations_owned_ids(self): """ @@ -111,7 +111,7 @@ def test_user_organizations_owned_ids(self): batdog = self.fixtures.batdog result = crusoe.organizations_owned_ids() self.assertIsInstance(result, list) - self.assertItemsEqual(result, [batdog.id]) + self.assertCountEqual(result, [batdog.id]) def test_user_organizations(self): """ @@ -122,7 +122,7 @@ def test_user_organizations(self): specialdachs = self.fixtures.specialdachs result = oakley.organizations() self.assertIsInstance(result, list) - self.assertItemsEqual(result, [batdog, specialdachs]) + self.assertCountEqual(result, [batdog, specialdachs]) def test_user_organizations_memberof(self): """ @@ -132,7 +132,7 @@ def test_user_organizations_memberof(self): batdog = self.fixtures.batdog result = oakley.organizations_memberof() self.assertIsInstance(result, list) - self.assertItemsEqual(result, [batdog]) + self.assertCountEqual(result, [batdog]) def test_user_organizations_memberof_ids(self): """ @@ -142,7 +142,7 @@ def test_user_organizations_memberof_ids(self): batdog = self.fixtures.batdog result = oakley.organizations_memberof_ids() self.assertIsInstance(result, list) - self.assertItemsEqual(result, [batdog.id]) + self.assertCountEqual(result, [batdog.id]) def test_user_available_permissions(self): """ @@ -153,7 +153,7 @@ def test_user_available_permissions(self): bdfl = self.fixtures.bdfl result = crusoe.available_permissions() self.assertIsInstance(result, list) - self.assertItemsEqual(result, [bdfl]) + self.assertCountEqual(result, [bdfl]) self.assertEqual(result[0].owner, crusoe) self.assertEqual(result[0].title, bdfl.title) @@ -195,7 +195,7 @@ def test_user_del_email(self): """ mr_jones = models.User(username='mrjones') mr_jones_primary_email = models.UserEmail( - email='mrjones@animalfarm.co.uk', primary=True, user=mr_jones + email='mrjones@animalfarm.co.uk', user=mr_jones, primary=True ) mr_jones_secondary_email = models.UserEmail( email='jones@animalfarm.co.uk', user=mr_jones @@ -218,7 +218,7 @@ def test_user_del_email(self): db.session.commit() result1 = mr_jones.emails self.assertIsInstance(result1, list) - self.assertItemsEqual(result1, [mr_jones_secondary_email, mr_jones_spare_email]) + self.assertCountEqual(result1, [mr_jones_secondary_email, mr_jones_spare_email]) self.assertTrue(mr_jones_secondary_email.primary) # scenario 2: when email requested to be delete is not primary spare_email = mr_jones_spare_email.email @@ -226,7 +226,7 @@ def test_user_del_email(self): db.session.commit() result2 = mr_jones.emails self.assertIsInstance(result2, list) - self.assertItemsEqual(result2, [mr_jones_secondary_email]) + self.assertCountEqual(result2, [mr_jones_secondary_email]) self.assertTrue(mr_jones_secondary_email.primary) def test_user_phone(self): @@ -301,8 +301,8 @@ def test_user_clients_with_team_access(self): client=enforcers, user=marcus, scope='teams', validity=0 ) enforcers_auth_token - self.assertItemsEqual(aro.clients_with_team_access(), [volterra]) - self.assertItemsEqual(marcus.clients_with_team_access(), [enforcers]) + self.assertCountEqual(aro.clients_with_team_access(), [volterra]) + self.assertCountEqual(marcus.clients_with_team_access(), [enforcers]) self.assertEqual(jane.clients_with_team_access(), []) def test_user_password_has_expired(self): @@ -363,11 +363,11 @@ def test_user_autocomplete(self): for each in result: self.assertIsInstance(each, models.User) query_for_oakley = models.User.autocomplete(queries[0]) - self.assertItemsEqual(query_for_oakley, [oakley]) + self.assertCountEqual(query_for_oakley, [oakley]) query_for_piglet = models.User.autocomplete(queries[1]) - self.assertItemsEqual(query_for_piglet, [piglet]) + self.assertCountEqual(query_for_piglet, [piglet]) query_for_crusoe = models.User.autocomplete(queries[2]) - self.assertItemsEqual(query_for_crusoe, [crusoe]) + self.assertCountEqual(query_for_crusoe, [crusoe]) def test_user_merged_user(self): """ @@ -387,9 +387,7 @@ def test_user_merged_user(self): self.assertEqual(crusoe2.status, 2) self.assertEqual(merged_user.username, "crusoe") self.assertIsInstance(merged_user.oldids, InstrumentedList) - assert 'of User crusoe "Crusoe Celebrity Dachshund">' in repr( - merged_user.oldids - ) + self.assertCountEqual(crusoe.oldids, merged_user.oldids) def test_user_get(self): """ @@ -447,24 +445,24 @@ def test_user_all(self): buids=[crusoe.buid], usernames=[oakley.username] ) self.assertIsInstance(lookup_by_both, list) - self.assertItemsEqual(lookup_by_both, expected_result) + self.assertCountEqual(lookup_by_both, expected_result) # scenario 3: when only buids are passed lookup_by_buids = models.User.all(buids=[crusoe.buid, oakley.buid]) self.assertIsInstance(lookup_by_buids, list) - self.assertItemsEqual(lookup_by_buids, expected_result) + self.assertCountEqual(lookup_by_buids, expected_result) # scenario 4: when only usernames are passed lookup_by_usernames = models.User.all( usernames=[crusoe.username, oakley.username] ) self.assertIsInstance(lookup_by_usernames, list) - self.assertItemsEqual(lookup_by_usernames, expected_result) + self.assertCountEqual(lookup_by_usernames, expected_result) # scenario 5: when defercols is set to True lookup_by_usernames_defercols = models.User.all( usernames=[crusoe.username, oakley.username], defercols=True ) lookup_by_usernames_defercols self.assertIsInstance(lookup_by_usernames, list) - self.assertItemsEqual(lookup_by_usernames, expected_result) + self.assertCountEqual(lookup_by_usernames, expected_result) # scenario 6: when user.status is active hannibal = models.User(username='hannibal') hannibal.status = models.USER_STATUS.ACTIVE diff --git a/tests/unit/lastuser_core/test_model_user_UserEmailClaim.py b/tests/unit/lastuser_core/test_model_user_UserEmailClaim.py index 56512f4..2a16acf 100644 --- a/tests/unit/lastuser_core/test_model_user_UserEmailClaim.py +++ b/tests/unit/lastuser_core/test_model_user_UserEmailClaim.py @@ -37,7 +37,7 @@ def test_useremailclaim_permissions(self): permissions_received = [] for each in result: permissions_received.append(each) - self.assertItemsEqual(permissions_expected, permissions_received) + self.assertCountEqual(permissions_expected, permissions_received) def test_useremailclaim_get(self): """ @@ -68,7 +68,7 @@ def test_useremailclaim_all(self): db.session.commit() result = models.UserEmailClaim.all(email) self.assertIsInstance(result, list) - self.assertItemsEqual(result, [claim_by_gail, claim_by_peeta]) + self.assertCountEqual(result, [claim_by_gail, claim_by_peeta]) def test_useremailclaim_email(self): """ diff --git a/tests/unit/lastuser_core/test_model_user_UserPhoneClaim.py b/tests/unit/lastuser_core/test_model_user_UserPhoneClaim.py index 393c6d0..fdb0a40 100644 --- a/tests/unit/lastuser_core/test_model_user_UserPhoneClaim.py +++ b/tests/unit/lastuser_core/test_model_user_UserPhoneClaim.py @@ -30,7 +30,7 @@ def test_userphoneclaim_all(self): db.session.commit() result = models.UserPhoneClaim.all(phone) self.assertIsInstance(result, list) - self.assertItemsEqual(result, [claim_by_crusoe, claim_by_oakley]) + self.assertCountEqual(result, [claim_by_crusoe, claim_by_oakley]) def test_userphoneclaim_get(self): """ @@ -75,4 +75,4 @@ def test_userphoneclaim_permissions(self): permissions_received = [] for each in result: permissions_received.append(each) - self.assertItemsEqual(permissions_expected, permissions_received) + self.assertCountEqual(permissions_expected, permissions_received) diff --git a/tests/unit/lastuser_core/test_registry_LoginProviderRegistry.py b/tests/unit/lastuser_core/test_registry_LoginProviderRegistry.py index 03a0444..9d0668e 100644 --- a/tests/unit/lastuser_core/test_registry_LoginProviderRegistry.py +++ b/tests/unit/lastuser_core/test_registry_LoginProviderRegistry.py @@ -32,4 +32,4 @@ def test_loginproviderregistry(self): if app.config.get('OAUTH_GITHUB_KEY') and app.config.get('OAUTH_GITHUB_SECRET'): expected_login_providers.append('github') self.assertIsInstance(login_registry, LoginProviderRegistry) - self.assertItemsEqual(expected_login_providers, list(login_registry.keys())) + self.assertCountEqual(expected_login_providers, list(login_registry.keys())) diff --git a/tests/unit/lastuser_core/test_session_UserSession.py b/tests/unit/lastuser_core/test_session_UserSession.py index 7df3e11..b49679c 100644 --- a/tests/unit/lastuser_core/test_session_UserSession.py +++ b/tests/unit/lastuser_core/test_session_UserSession.py @@ -74,7 +74,7 @@ def test_usersession_active_sessions(self): accessed_at=utcnow(), ) self.assertIsInstance(piglet.active_sessions.all(), list) - self.assertItemsEqual(piglet.active_sessions.all(), [piglet_session]) + self.assertCountEqual(piglet.active_sessions.all(), [piglet_session]) def test_usersession_authenticate(self): """Test to verify authenticate method on UserSession""" From 15111d4d6d3cd76ba49aaab7ebc72057e64b0d3f Mon Sep 17 00:00:00 2001 From: Bibhas Date: Tue, 18 Feb 2020 01:25:59 +0530 Subject: [PATCH 06/10] ignoring behave tests --- runtests.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/runtests.sh b/runtests.sh index 3bec107..19b024b 100755 --- a/runtests.sh +++ b/runtests.sh @@ -5,5 +5,9 @@ if [ -f secrets.test ]; then source ./secrets.test fi coverage run -m pytest "$@" -coverage run -a -m behave +# behave test flow is broken because our registration flow changed. +# also, we're using cypress for E2E tests on funnel, so better to replace +# the E2E tests using cypress from here on. Fixing the behave tests is +# time consuming and not worth the effort at this point. +# coverage run -a -m behave coverage report -m From 891e3516849eb4efe268b2081d8af5f55010918d Mon Sep 17 00:00:00 2001 From: Bibhas Date: Tue, 18 Feb 2020 16:47:29 +0530 Subject: [PATCH 07/10] moving travis to 3.7 --- .travis.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9858622..a3ee22c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,11 @@ language: python python: - - "2.7" + - "3.7" services: - redis-server - postgresql install: + - pip install git+https://github.com/hasgeek/flask-babelhg/ - pip install -r requirements.txt - pip install -r test_requirements.txt before_script: @@ -15,6 +16,3 @@ after_success: - coveralls notifications: email: false - slack: - - hasgeek:HDCoMDj3T4ICB59qFFVorCG8 - - friendsofhasgeek:3bLViYSzhfaThJovFYCVD3fX From ffbe84251a5f7c43d5bfa096ec59be9af0d43a8c Mon Sep 17 00:00:00 2001 From: Bibhas Date: Tue, 18 Feb 2020 17:15:04 +0530 Subject: [PATCH 08/10] flask-wtf needs to be bumped --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f6af4f1..a0c39b6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ Flask-OAuth==0.12 pytz==2019.3 bcrypt>=2.0.0 ordereddict==1.1 -Flask-WTF==0.14.2 +Flask-WTF==0.14.3 requests==2.22.0 blinker==1.4 Flask-RQ2==18.3 From ad0d122f3b962d8a1e3cf08c2a122fc57be51f9c Mon Sep 17 00:00:00 2001 From: Bibhas Date: Tue, 18 Feb 2020 20:59:41 +0530 Subject: [PATCH 09/10] cleaned up lists --- lastuser_core/utils.py | 2 +- lastuser_oauth/views/account.py | 2 +- lastuser_oauth/views/login.py | 2 +- lastuser_oauth/views/notify.py | 2 +- lastuser_ui/views/profile.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lastuser_core/utils.py b/lastuser_core/utils.py index a2d1966..8136b82 100644 --- a/lastuser_core/utils.py +++ b/lastuser_core/utils.py @@ -23,7 +23,7 @@ def make_redirect_url(url, use_fragment=False, **params): queryparts = urllib.parse.parse_qsl( urlparts[4] if use_fragment else urlparts[3], keep_blank_values=True ) - queryparts.extend([(k, v) for k, v in list(params.items()) if v is not None]) + queryparts.extend([(k, v) for k, v in params.items() if v is not None]) queryparts = [ ( key.encode('utf-8') if isinstance(key, str) else key, diff --git a/lastuser_oauth/views/account.py b/lastuser_oauth/views/account.py index e115053..983190c 100644 --- a/lastuser_oauth/views/account.py +++ b/lastuser_oauth/views/account.py @@ -98,7 +98,7 @@ def get_user_extid(service, userdata): else: # Cross-check with all other instances of the same LoginProvider (if we don't have a user) # This is (for eg) for when we have two Twitter services with different access levels. - for other_service, other_provider in list(login_registry.items()): + for other_service, other_provider in login_registry.items(): if ( other_service != service and other_provider.__class__ == provider.__class__ diff --git a/lastuser_oauth/views/login.py b/lastuser_oauth/views/login.py index 6b5b418..62436b1 100644 --- a/lastuser_oauth/views/login.py +++ b/lastuser_oauth/views/login.py @@ -70,7 +70,7 @@ def login(): loginform = LoginForm() service_forms = {} - for service, provider in list(login_registry.items()): + for service, provider in login_registry.items(): if provider.at_login and provider.form is not None: service_forms[service] = provider.get_form() diff --git a/lastuser_oauth/views/notify.py b/lastuser_oauth/views/notify.py index 918b1bb..037ffa1 100644 --- a/lastuser_oauth/views/notify.py +++ b/lastuser_oauth/views/notify.py @@ -119,7 +119,7 @@ def notify_org_data_changed(org, user, changes, team=None): continue client_users.setdefault(token.client, []).append(token.user) # Now we have a list of clients to notify and a list of users to notify them with - for client, users in list(client_users.items()): + for client, users in client_users.items(): if user is not None and user in users: notify_user = user else: diff --git a/lastuser_ui/views/profile.py b/lastuser_ui/views/profile.py index b38ee4f..3ecbba5 100644 --- a/lastuser_ui/views/profile.py +++ b/lastuser_ui/views/profile.py @@ -48,7 +48,7 @@ def account(): primary_email_form = EmailPrimaryForm() primary_phone_form = PhonePrimaryForm() service_forms = {} - for service, provider in list(login_registry.items()): + for service, provider in login_registry.items(): if provider.at_login and provider.form is not None: service_forms[service] = provider.get_form() return render_template( From 84f74635a983dfb101944e2c5f322ea8198878e0 Mon Sep 17 00:00:00 2001 From: Bibhas Date: Thu, 20 Feb 2020 16:21:32 +0530 Subject: [PATCH 10/10] linting fixes --- lastuser_core/models/user.py | 22 +++++----------------- lastuser_oauth/providers/flask_oauth.py | 3 --- lastuser_oauth/views/login.py | 1 + runserver.py | 2 +- runtests.sh | 2 +- runtestserver.py | 2 +- 6 files changed, 9 insertions(+), 23 deletions(-) diff --git a/lastuser_core/models/user.py b/lastuser_core/models/user.py index 266552e..de59f2f 100644 --- a/lastuser_core/models/user.py +++ b/lastuser_core/models/user.py @@ -312,7 +312,7 @@ def _set_password(self, password): else: self.pw_hash = bcrypt.hashpw( password.encode('utf-8'), bcrypt.gensalt() - ).decode('utf-8') + ).decode('ascii') self.pw_set_at = db.func.utcnow() # Expire passwords after one year. TODO: make this configurable self.pw_expires_at = self.pw_set_at + timedelta(days=365) @@ -958,11 +958,8 @@ def __repr__(self): email=self.email, user=repr(self.user)[1:-1] ) - def __unicode__(self): - return str(self.email) - def __str__(self): - return str(self.__unicode__()) + return self.email @property def primary(self): @@ -1029,11 +1026,8 @@ def __repr__(self): email=self.email, user=repr(self.user)[1:-1] ) - def __unicode__(self): - return str(self.email) - def __str__(self): - return str(self.__unicode__()) + return self.email def permissions(self, user, inherited=None): perms = super(UserEmailClaim, self).permissions(user, inherited) @@ -1098,11 +1092,8 @@ def __repr__(self): phone=self.phone, user=repr(self.user)[1:-1] ) - def __unicode__(self): - return str(self.phone) - def __str__(self): - return str(self.__unicode__()) + return self.phone def parsed(self): return phonenumbers.parse(self._phone) @@ -1168,11 +1159,8 @@ def __repr__(self): phone=self.phone, user=repr(self.user)[1:-1] ) - def __unicode__(self): - return str(self.phone) - def __str__(self): - return str(self.__unicode__()) + return self.phone def parsed(self): return phonenumbers.parse(self._phone) diff --git a/lastuser_oauth/providers/flask_oauth.py b/lastuser_oauth/providers/flask_oauth.py index 6b0c971..ed9175c 100644 --- a/lastuser_oauth/providers/flask_oauth.py +++ b/lastuser_oauth/providers/flask_oauth.py @@ -132,9 +132,6 @@ def __init__(self, message, type=None, data=None): # noqa: A002 self.data = data def __str__(self): - return self.message.encode('utf-8') - - def __unicode__(self): return self.message diff --git a/lastuser_oauth/views/login.py b/lastuser_oauth/views/login.py index 62436b1..ed7bfca 100644 --- a/lastuser_oauth/views/login.py +++ b/lastuser_oauth/views/login.py @@ -54,6 +54,7 @@ def openid_log(message, level=0): + # FIXME: deprecate this along with Flask-OAuth if current_app.debug: print(message) # noqa: T001 diff --git a/runserver.py b/runserver.py index 2e44837..f169bd5 100755 --- a/runserver.py +++ b/runserver.py @@ -1,5 +1,5 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from lastuserapp import app # isort:skip +from lastuserapp import app app.run('0.0.0.0', 7000) diff --git a/runtests.sh b/runtests.sh index 19b024b..10ac073 100755 --- a/runtests.sh +++ b/runtests.sh @@ -5,7 +5,7 @@ if [ -f secrets.test ]; then source ./secrets.test fi coverage run -m pytest "$@" -# behave test flow is broken because our registration flow changed. +# FIXME: behave test flow is broken because our registration flow changed. # also, we're using cypress for E2E tests on funnel, so better to replace # the E2E tests using cypress from here on. Fixing the behave tests is # time consuming and not worth the effort at this point. diff --git a/runtestserver.py b/runtestserver.py index 6598882..a956332 100644 --- a/runtestserver.py +++ b/runtestserver.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- from lastuser_core.models import Client, Organization, Permission, User # isort:skip -from lastuserapp import app, db # isort:skip +from lastuserapp import app, db # incase data exists from previously run tests db.drop_all()