PKz:Jyttplugs_auth/decorators.pyfrom plugs_auth.settings import plugs_auth_settings as settings def dynamicviewset(viewset): """ The activate route only makes sense if user activation is required, remove the route if activation is turned off """ if not settings['REQUIRE_ACTIVATION'] and hasattr(viewset, 'activate'): delattr(viewset, 'activate') return viewset PKz:Js S plugs_auth/views.py""" Plugs Auth Views """ from django.contrib.auth import get_user_model from django.shortcuts import get_object_or_404 from rest_framework import permissions from rest_framework.decorators import list_route from rest_framework.response import Response from plugs_core.viewsets import CreateUpdateReadViewSet from plugs_auth.serializers import ResetSerializer, SetSerializer from plugs_auth import utils from plugs_auth.decorators import dynamicviewset @dynamicviewset class PlugsUserViewSet(CreateUpdateReadViewSet): """ Use this class as a base class for a user viewset, this class provides activate, reset_password, set_password, resend_verification_email and populates the user object with the language using user submited data, accept-language header or project settings """ def perform_create(self, serializer): serializer.validated_data['language'] = utils.get_language_code(self.request, serializer) serializer.save() @list_route(methods=['GET'], permission_classes=[permissions.AllowAny]) def activate(self, request): kwargs = {'token': request.query_params.get('token'), 'is_active': False} user = get_object_or_404(get_user_model(), **kwargs) user.is_active = True user.save() user.send_account_activated_email() return Response(data={"message": "Activated"}) @list_route(methods=['POST'], permission_classes=[permissions.AllowAny]) def reset_password(self, request): """ Starts the reset password process by sending an email """ serializer = ResetSerializer(data=request.data) serializer.is_valid(raise_exception=True) user = get_object_or_404(get_user_model(), **serializer.data) user.set_token() user.send_reset_password_email() user.save() return Response(data={"message": "Email Sent"}) @list_route(methods=['POST'], permission_classes=[permissions.AllowAny]) def set_password(self, request): """ Sets a new password after a reset password request """ serializer = SetSerializer(data=request.data) serializer.is_valid(raise_exception=True) data = serializer.data password = data.pop('password') user = get_object_or_404(get_user_model(), **data) user.password = password user.is_active = True # in case the user was inactive user.set_token() user.save() return Response(data={"message": "New password set"}) @list_route(methods=['POST'], permission_classes=[permissions.AllowAny]) def resend_verification_email(self, request): """ Resends the verification email to a user """ kwargs = {'email': request.data.get('email'), 'is_active': False} user = get_object_or_404(get_user_model(), **kwargs) user.send_activation_email() return Response(data={"message": "Email sent"}) PK6Iw?z z plugs_auth/utils.py""" Plugs Auth Utils """ from django.conf import settings def parse_accept_language(accept_header): """ Taken from: https://siongui.github.io/2012/10/11/python-parse-accept-language-in-http-request-header/ """ languages = accept_header.split(",") locale_q_pairs = [] for language in languages: if language.split(";")[0] == language: # no q => q = 1 locale_q_pairs.append((language.strip(), "1")) else: locale = language.split(";")[0].strip() q = language.split(";")[1].split("=")[1] locale_q_pairs.append((locale, q)) return locale_q_pairs def get_languages_list(): """ Get the list of project supported languages """ return [language[0] for language in settings.LANGUAGES] def is_supported_language(language): """ Given a language check if it belongs to the supported list """ return language in get_languages_list() def language_from_header(header): """ Split the accept language header and check if a language preference is available in the settings """ preferences = parse_accept_language(header) languages = get_languages_list() for preference in preferences: # iterate over the languages setting and return the first match if is_supported_language(preference[0]): return preference[0] def get_language_code(request, serializer): """ Check request and provided data to define the user language """ # first check if user provided a valid language_code language_code = serializer.validated_data.get('language') if is_supported_language('language_code'): return language_code # second check if is possible to determine the language from the # request headers try: accept_header = request.META['HTTP_ACCEPT_LANGUAGE'] language_code = language_from_header(accept_header) # third, set the user language using the settings except KeyError: # in case the Locale Middleware is not available, use the language # set in the settings, the Django default is en-US # more information on the format used in the settings # http://www.i18nguy.com/unicode/language-identifiers.html # for now we are only using the language part of the code language_code = settings.LANGUAGE_CODE.split('-')[0] return language_code PKUI &85plugs_auth/serializers.py""" Custom authentication serializers """ from rest_framework import serializers class ResetSerializer(serializers.Serializer): """ Custom serializer to use with reset_password api view """ email = serializers.EmailField() class SetSerializer(serializers.Serializer): """ Custom serializer to use with set_password api view """ email = serializers.EmailField() password = serializers.CharField() token = serializers.CharField() PKz:J{M.FFplugs_auth/managers.py""" Plugs Authentication Managers """ from plugs_auth.settings import plugs_auth_settings as settings from django.contrib.auth.models import BaseUserManager class PlugsAuthManager(BaseUserManager): """ Custom manager, the parent class provides some utils to manage users, like normalize_email and make_random_password """ def _create_user(self, email, password, **extra_fields): """ Creates and saves a User with the given username, email and password. """ email = self.normalize_email(email) user = self.model(email=email, **extra_fields) user.set_password(password) user.save(using=self._db) return user def create(self, email, password=None, silent=False, **extra_fields): if silent: print('Silent has been deprecated') extra_fields.setdefault('is_staff', False) extra_fields.setdefault('is_superuser', False) user = self._create_user(email, password, **extra_fields) if settings['REQUIRE_ACTIVATION']: user.send_activation_email() else: user.is_active=True return user def create_superuser(self, email, password, **extra_fields): """ This method is provided to enable createsuperuser command a superuser is automatically made staff and active """ extra_fields.setdefault('is_active', True) extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) if extra_fields.get('is_staff') is not True: raise ValueError('Superuser must have is_staff=True.') if extra_fields.get('is_superuser') is not True: raise ValueError('Superuser must have is_superuser=True.') return self._create_user(email, password, **extra_fields) PK6I9 plugs_auth/models.py""" Plugs Base Auth Model """ from django.db import models from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin from plugs_core import utils from plugs_mail import utils as mail_utils from plugs_auth import emails from plugs_auth.managers import PlugsAuthManager class PlugsAuthModel(AbstractBaseUser, PermissionsMixin): """ Member model """ email = models.EmailField(unique=True) is_active = models.BooleanField(default=False) is_staff = models.BooleanField(default=False) token = models.CharField(max_length=24, null=False, unique=True) language = models.CharField(max_length=2, default='en') objects = PlugsAuthManager() # the field used to authenticate a user USERNAME_FIELD = 'email' def __init__(self, *args, **kwargs): """ Overring init to store original password """ super(PlugsAuthModel, self).__init__(*args, **kwargs) self.__original_password = self.password @property def username(self): """ The field used to authenticate a user """ return self.USERNAME_FIELD def set_token(self): """ Set a unique verified token """ params = {'length': 24} queryset = self.__class__.objects self.token = utils.get_db_distinct(queryset, 'token', utils.random_string, **params) def send_reset_password_email(self): """ Send email to user with reset password link """ mail_utils.to_email(emails.ResetPassword, self.email, self.language, **{'user': self}) def send_activation_email(self): """ Send email to user with activation details """ mail_utils.to_email(emails.ActivateAccount, self.email, self.language, **{'user': self}) def send_account_activated_email(self): """ Send email to user saying account has been activated """ mail_utils.to_email(emails.AccountActivated, self.email, self.language, **{'user': self}) def save(self, *args, **kwargs): """ Override save method """ if self.pk: # original password differs from new password if self.password != self.__original_password: self.set_password(self.password) else: self.set_token() super(PlugsAuthModel, self).save(*args, **kwargs) # we can mark fields as abstract to demand subclass to implement them class Meta: abstract = True PK{:J0vplugs_auth/__init__.py__version__ = '0.1.6' PK}TIplugs_auth/admin.py# PKȎI{$$plugs_auth/emails.py""" Email Template Definition """ from urllib.parse import urlencode from plugs_mail.mail import PlugsMail from plugs_auth.settings import plugs_auth_settings as settings class ActivateAccount(PlugsMail): """ Email sent to user after registration with link to activate his account """ template = 'ACTIVATE_ACCOUNT' context = ('User', ) description = 'Email sent to user after registration with link to activate his account' def get_extra_context(self): user = self.context_data.get('user') params = '?' + urlencode({ 'token': user.token }) activate_uri = settings['SITE_ACTIVATE_VIEW'] + params return {'activate_uri': activate_uri} class ResetPassword(PlugsMail): """ Email sent to user with reset password link """ template = 'RESET_PASSWORD' context = ('User', ) description = 'Email sent to user with reset password link' def get_extra_context(self): """ Adds reset_password_uri as extra context """ user = self.context_data.get('user') params = '?' + urlencode({ 'email': user.email, 'token': user.token }) reset_password_uri = settings['SITE_RESET_VIEW'] + params return {'reset_password_uri': reset_password_uri} class AccountActivated(PlugsMail): """ Email sent to user after succesful account activation """ template = 'ACCOUNT_ACTIVATED' context = ('User', ) description = 'Email sent to user after succesful account activation' PKz:J{splugs_auth/settings.py""" Plugs Auth Settings """ from django.conf import settings from django.core.exceptions import ImproperlyConfigured MANDATORY_SETTINGS = ['RESET_VIEW'] PROJECT_SETTINGS = getattr(settings, 'PLUGS_AUTH', {}) for setting in MANDATORY_SETTINGS: try: PROJECT_SETTINGS[setting] except KeyError: raise ImproperlyConfigured('Missing setting: PLUGS_AUTH[\'{0}\']'.format(setting)) DEFAULTS = { 'USER_ENDPOINT': 'users', 'REQUIRE_ACTIVATION': True } for setting in DEFAULTS.keys(): if setting not in PROJECT_SETTINGS: PROJECT_SETTINGS[setting] = DEFAULTS[setting] # conditional settings, only required if something, something... if PROJECT_SETTINGS['REQUIRE_ACTIVATION'] and 'ACTIVATE_VIEW' not in PROJECT_SETTINGS: raise ImproperlyConfigured('Missing ACTIVATE_VIEW. This setting is required if REQUIRE_ACTIVATION is True') plugs_auth_settings = PROJECT_SETTINGS PK}TIi;plugs_auth/runtests.py#!/usr/bin/env python import os import sys import django from django.conf import settings from django.test.utils import get_runner if __name__ == "__main__": os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.test_settings' django.setup() TestRunner = get_runner(settings) test_runner = TestRunner() failures = test_runner.run_tests(["tests"]) sys.exit(bool(failures)) PK}TIRKBB!plugs_auth/tests/test_settings.pySECRET_KEY = 'afakesecret' INSTALLED_APPS = [ "plugs_auth", ] PK}TI@Cplugs_auth/tests/test_models.py""" Testing Models """ from django.contrib.auth import get_user_model from plugs_core.testcases import PlugsAPITestCase model = get_user_model() class TestModels(PlugsAPITestCase): """ Testing Models """ def test_superuser_can_login_with_new_account(self): """ Ensures superuser is created and can login """ data = { 'email': 'joe@somewhere.org', 'password': 'longandhardpass' } user = model.objects.create_superuser(**data) # created password should be unusable self.assertTrue(user.has_usable_password()) self.assertLogin(data['email'], data['password']) PKjUIplugs_auth/tests/test_views.py""" Testing Users Endpoint """ from django.contrib.auth import get_user_model from django.core.urlresolvers import reverse from rest_framework.test import APITestCase from plugs_core import utils from plugs_core.testcases import PlugsAPITestCase from plugs_auth.tests.factories import UserFactory model = get_user_model() class TestViews(PlugsAPITestCase): """ Testing Views """ def test_guest_can_activate_account(self): """ Ensures guest can activate account """ # setup # user = UserFactory(is_active=True) user = UserFactory(is_active=False, first_name='Joe') # @FIX url pattern not correct url = reverse('activate-user') + '?token=' + user.token # exercise response = self.client.get(url) # assert self.assert200(response) self.assertEqual(model.objects.get(pk=user.pk).is_active, True) self.assertEqual(response.data, { "message": "Activated"}) def test_guest_can_start_reset_password_process(self): """ Ensures guest can start reset password process """ # setup user = UserFactory(is_active=True) # exercise url = reverse('reset-password') data = {'email': user.email} response = self.client.post(url, data) self.assert200(response) # assert validation token has been refreshed new_token = model.objects.get(pk=user.pk).token self.assertNotEqual(user.token, new_token) def test_guest_can_set_new_password(self): """ Ensures guest can set new password """ # setup user = UserFactory(is_active=True) # exercise data = { 'email': user.email, 'token': user.token, 'password': 'newpassword' } self.client.post(reverse('set-password'), data) self.assertLogin(user.email, 'newpassword') def test_inactive_user_can_reset_password_and_login(self): """ Ensures inactive user can reset password and login """ user = UserFactory(is_active=False) # exercise data = {'email': user.email} response = self.client.post(reverse('reset-password'), data) self.assert200(response) user.refresh_from_db() # exercise data = { 'email': user.email, 'token': user.token, 'password': 'newpassword' } response = self.client.post(reverse('set-password'), data) self.assert200(response) user.refresh_from_db() # assert self.assert200(response) self.assertLogin(user.email, 'newpassword') self.assertEqual(user.is_active, True) def test_guest_cannot_set_new_password_without_token(self): """ Ensures guest cannot set new password without token """ # setup user = UserFactory(is_active=True) # exercise data = { 'email': user.email, 'password': 'newpassword' } response = self.client.post(reverse('set-password'), data) self.assert400(response) self.assertCannotLogin(user.email, 'newpassword') def test_guest_cannot_set_new_password_with_invalid_token(self): """ Ensures guest cannot set new password with invalid token """ # setup user = UserFactory(is_active=True) # exercise data = { 'email': user.email, 'password': 'newpassword', 'token': 'xxx' } response = self.client.post(reverse('set-password'), data) self.assert404(response) self.assertCannotLogin(user.email, 'newpassword') PK}TIplugs_auth/tests/__init__.pyPK}TIrݨ plugs_auth/tests/test_mails.py""" Test Emails """ from django.core.urlresolvers import reverse from plugs_core.testcases import PlugsAPITestCase from plugs_core import utils from plugs_mail.management.commands import load_email_templates from plugs_auth.tests.factories import UserFactory from plugs_auth.settings import plugs_auth_settings class MailTestsBoy(PlugsAPITestCase): def setUp(self): """ Creates email templates """ # uses the load email templates command to # auto populate our test database with email # templates command = load_email_templates.Command() command.handle() def test_email_reset_password_sent_to_user(self): """ Ensures reset password email is sent to user """ # setup user = UserFactory(is_active=False) # exercise data = {'email': user.email} response = self.client.post(reverse('reset-password'), data) self.assert200(response) self.assertEmailCount('Perdeste a tua password?', 1) self.assertEmailTo('Perdeste a tua password?', data.get('email')) def test_email_account_activated_sent_to_user(self): """ Ensures account activated email is sent to user """ # setup user = UserFactory(is_active=False) # @FIX url pattern not correct url = reverse('activate-user') + '?token=' + user.token response = self.client.get(url) # assert self.assert200(response) self.assertEmailCount('Conta ativada com sucesso', 1) self.assertEmailTo('Conta ativada com sucesso', user.email) def test_email_resent_verification_email(self): """ Ensures user receives a new verification email """ user = UserFactory(is_active=False) self.assertEmailCount('Ativa a tua conta', 1) url = reverse('resend-verification') data = {'email': user.email} response = self.client.post(url, data) self.assertEmailCount('Ativa a tua conta', 2) def test_email_resent_verification_email_not_sent_if_user_active(self): """ Ensures user does not receive a new verification email if already active """ user = UserFactory(is_active=True) self.assertEmailCount('Ativa a tua conta', 1) url = reverse('resend-verification') data = {'email': user.email} response = self.client.post(url, data) self.assertEmailCount('Ativa a tua conta', 1) PK}TI7vvplugs_auth/tests/factories.py""" Factory Boy Factory Definition """ from django.contrib.auth import get_user_model from factory.django import DjangoModelFactory as Factory from factory import LazyAttribute, Sequence, SubFactory model = get_user_model() class UserFactory(Factory): """ Base User Factory """ email = LazyAttribute(lambda m: '{0}@example.com'.format(m.first_name)) first_name = Sequence(lambda n: 'User{0}'.format(n)) last_name = 'Smith' token = Sequence(lambda n: 'Validation{0}'.format(n)) # pylint: disable=R0903 class Meta: """ Metaclass Definition """ model = model PK}TI plugs_auth/templates/__init__.pyPKȎI%tAA4plugs_auth/templates/emails/activate_account_pt.htmlAtiva a tua conta {% extends "base.html" %} {% load emailtags %} {% block content %}

Olá {{user.first_name}},

A tua conta foi criada com sucesso. Para começares a usar precisas de confirmar o teu email. Para isso basta clicar no link seguinte:

{% button activate_uri "ativar conta" %} {% endblock %} PKȎI=w""4plugs_auth/templates/emails/activate_account_en.htmlActivate account {% extends "base.html" %} {% load emailtags %} {% block content %}

Hello {{user.first_name}},

Your account was successfully created.

Please confirm your email by clicking the link bellow:

{% button activate_uri "activate account" %} {% endblock %} PKȎI<5plugs_auth/templates/emails/account_activated_pt.htmlConta ativada com sucesso {% extends "base.html" %} {% block content %}

Olá, {{user.first_name}}

A tua conta foi ativada com sucesso.

{% endblock %} PKȎI3Soo2plugs_auth/templates/emails/reset_password_pt.htmlPerdeste a tua password? {% extends "base.html" %} {% load emailtags %} {% block content %}

Olá {{user.first_name}},

Recebemos um pedido de mudança de password da conta associada a este email.

Para mudares a password basta clicar no botão em baixo e seguir as instruções

{% button reset_password_uri "alterar password" %} {% endblock %} PKȎI"腜5plugs_auth/templates/emails/account_activated_en.htmlAccount successfully activated {% extends "base.html" %} {% block content %}

Hello, {{user.first_name}}

Your account was successfully activated.

Feel free to login and enjoy our offers.

{% endblock %} PK}TI'plugs_auth/templates/emails/__init__.pyPKȎI.Z2plugs_auth/templates/emails/reset_password_en.htmlLost your password? {% extends "base.html" %} {% load emailtags %} {% block content %}

Hello {{user.first_name}},

We received a request to reset the password of the account associated with this email.

To change your password just click below and follow the instructions.

If you didn't make such request, please ignore this email.

{% button reset_password_uri "change password" %} {% endblock %} PK{:J1mm*plugs_auth-0.1.6.dist-info/DESCRIPTION.rst============================= Plugs Auth ============================= .. image:: https://badge.fury.io/py/plugs-auth.png :target: https://badge.fury.io/py/plugs-auth .. image:: https://travis-ci.org/ricardolobo/plugs-auth.png?branch=master :target: https://travis-ci.org/ricardolobo/plugs-auth Your project description goes here Documentation ------------- The full documentation is at https://plugs-auth.readthedocs.io. Quickstart ---------- Install Plugs Auth:: pip install plugs-auth Add it to your `INSTALLED_APPS`: .. code-block:: python INSTALLED_APPS = ( ... 'plugs_auth.apps.PlugsAuthConfig', ... ) Add Plugs Auth's URL patterns: .. code-block:: python from plugs_auth import urls as plugs_auth_urls urlpatterns = [ ... url(r'^', include(plugs_auth_urls)), ... ] Features -------- * TODO Running Tests ------------- Does the code actually work? :: source /bin/activate (myenv) $ pip install tox (myenv) $ tox Credits ------- Tools used in rendering this package: * Cookiecutter_ * `cookiecutter-djangopackage`_ .. _Cookiecutter: https://github.com/audreyr/cookiecutter .. _`cookiecutter-djangopackage`: https://github.com/pydanny/cookiecutter-djangopackage History ------- 0.1.0 (2017-01-26) ++++++++++++++++++ * First release on PyPI. PK{:JF3z(plugs_auth-0.1.6.dist-info/metadata.json{"classifiers": ["Development Status :: 3 - Alpha", "Framework :: Django", "Framework :: Django :: 1.9", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5"], "extensions": {"python.details": {"contacts": [{"email": "ricardolobo@soloweb.pt", "name": "Ricardo Lobo", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/ricardolobo/plugs-auth"}}}, "extras": [], "generator": "bdist_wheel (0.26.0)", "keywords": ["plugs-auth"], "license": "MIT", "metadata_version": "2.0", "name": "plugs-auth", "run_requires": [{"requires": ["plugs-core (>=0.1.0)", "plugs-mail (>=0.1.0)"]}], "summary": "Your project description goes here", "version": "0.1.6"}PK{:J# (plugs_auth-0.1.6.dist-info/top_level.txtplugs_auth PK{:Jndnn plugs_auth-0.1.6.dist-info/WHEELWheel-Version: 1.0 Generator: bdist_wheel (0.26.0) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any PK{:J>#plugs_auth-0.1.6.dist-info/METADATAMetadata-Version: 2.0 Name: plugs-auth Version: 0.1.6 Summary: Your project description goes here Home-page: https://github.com/ricardolobo/plugs-auth Author: Ricardo Lobo Author-email: ricardolobo@soloweb.pt License: MIT Keywords: plugs-auth Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Framework :: Django Classifier: Framework :: Django :: 1.9 Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Natural Language :: English Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Requires-Dist: plugs-core (>=0.1.0) Requires-Dist: plugs-mail (>=0.1.0) ============================= Plugs Auth ============================= .. image:: https://badge.fury.io/py/plugs-auth.png :target: https://badge.fury.io/py/plugs-auth .. image:: https://travis-ci.org/ricardolobo/plugs-auth.png?branch=master :target: https://travis-ci.org/ricardolobo/plugs-auth Your project description goes here Documentation ------------- The full documentation is at https://plugs-auth.readthedocs.io. Quickstart ---------- Install Plugs Auth:: pip install plugs-auth Add it to your `INSTALLED_APPS`: .. code-block:: python INSTALLED_APPS = ( ... 'plugs_auth.apps.PlugsAuthConfig', ... ) Add Plugs Auth's URL patterns: .. code-block:: python from plugs_auth import urls as plugs_auth_urls urlpatterns = [ ... url(r'^', include(plugs_auth_urls)), ... ] Features -------- * TODO Running Tests ------------- Does the code actually work? :: source /bin/activate (myenv) $ pip install tox (myenv) $ tox Credits ------- Tools used in rendering this package: * Cookiecutter_ * `cookiecutter-djangopackage`_ .. _Cookiecutter: https://github.com/audreyr/cookiecutter .. _`cookiecutter-djangopackage`: https://github.com/pydanny/cookiecutter-djangopackage History ------- 0.1.0 (2017-01-26) ++++++++++++++++++ * First release on PyPI. PK{:JԊ !plugs_auth-0.1.6.dist-info/RECORDplugs_auth/__init__.py,sha256=gW5NUxwGdPsiQjn0cOuuQT11pfthByI5DITDg_HMhLQ,22 plugs_auth/admin.py,sha256=MsSFjiLMLJZ7QhUPpVBWKiyDnCzryquRyr329NoCACI,2 plugs_auth/decorators.py,sha256=vD2-h5_rOCkRVoCkkg-ffAsheUc6dOz0Mjw9I5kUFRU,372 plugs_auth/emails.py,sha256=d30rjYDz3PexSzleRx3RfXdasbDgSGL06dwbm3jHijg,1572 plugs_auth/managers.py,sha256=YbAceT4da5-nCv9tNXzLQr7wyN8QAeGtBDpHrfW8ZEM,1862 plugs_auth/models.py,sha256=L_xi7y7g6hcJj5RjcTtYD9KcH2_Zgzwx8bP2pbaz-BY,2530 plugs_auth/runtests.py,sha256=x9CYKK30PzZ6V9DpJSqxT95606k5qgdR7FWPqOz3B6E,390 plugs_auth/serializers.py,sha256=eE0jzshfo6OXKHOFeek9XuCr2-CMYZlExD-UxG2TdX4,473 plugs_auth/settings.py,sha256=r-o8N2zIv5isT54XkyqG0AeRI9n9M0WqmJivQmB0YvQ,911 plugs_auth/utils.py,sha256=6b46k_u0rjm1hPBKUkS36sftr2EU4kct7EHFC4MTqWg,2426 plugs_auth/views.py,sha256=0bS5FMYpfTPrD4DJ1zdF-7NP11lcn81Nqs29gLQ410Y,2971 plugs_auth/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 plugs_auth/templates/emails/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 plugs_auth/templates/emails/account_activated_en.html,sha256=-KB_poITFTnlKOFY4_4rOxT-HyUgAZdO8oSwZAdMQHk,225 plugs_auth/templates/emails/account_activated_pt.html,sha256=IfQo4ZFt0Ksiof6vrR2dmREzg_RJRtfOCZmizqlEG8k,167 plugs_auth/templates/emails/activate_account_en.html,sha256=WFvLJasayroYG0fE1ln3xCgrRj8ilTMBZIPvdqLsZfY,290 plugs_auth/templates/emails/activate_account_pt.html,sha256=2QI7_PnziQro6jlv8NorLGmPV69c_9NKNqUVFPAMTk0,321 plugs_auth/templates/emails/reset_password_en.html,sha256=TN5Geo55Q-zwuGvnpv34VFpQtxkG27Ve1DhULxa-u7U,427 plugs_auth/templates/emails/reset_password_pt.html,sha256=qfZglxiMB1um7PUlRR9Oqm83b3qXyhifkJZ2QZYKScI,367 plugs_auth/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 plugs_auth/tests/factories.py,sha256=QarwEHdbZl13qdO3bZ1bR0ZVOzl78JoyiPHFRAouUTQ,630 plugs_auth/tests/test_mails.py,sha256=KbOEvYhvAjkhFkdgqo3YL-A9kFrm7mgpPbx9SyOa0Qs,2552 plugs_auth/tests/test_models.py,sha256=67MocP2lsNfDhYGLermXBglVBFkUXLvAIzfet7MKesM,675 plugs_auth/tests/test_settings.py,sha256=vuNwBybgYLB09qrjR4Lg5lZpghUjDzyszt3dyTvig7A,66 plugs_auth/tests/test_views.py,sha256=Q0rKweDnQqxwvFp9hNTdnWU4tz2wI81dLZSAaux_I74,3787 plugs_auth-0.1.6.dist-info/DESCRIPTION.rst,sha256=_WQmu1cDDByxvXV5WFOaKZW9nvPf7RsfIxIRJg5fYN0,1389 plugs_auth-0.1.6.dist-info/METADATA,sha256=f5LnNf-zxb2PwPFrib6KYgK5Fh0rzzrFowZiAMx6Pb4,2219 plugs_auth-0.1.6.dist-info/RECORD,, plugs_auth-0.1.6.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 plugs_auth-0.1.6.dist-info/metadata.json,sha256=NubF8pBcv4XIAchLGK3sYG9xOn0rfggNWJcm0otpfdU,965 plugs_auth-0.1.6.dist-info/top_level.txt,sha256=yRXiXgDQN1rJHKhkyEMX509D8GLu3FyzlslyayYUooA,11 PKz:Jyttplugs_auth/decorators.pyPKz:Js S plugs_auth/views.pyPK6Iw?z z v plugs_auth/utils.pyPKUI &85!plugs_auth/serializers.pyPKz:J{M.FF1plugs_auth/managers.pyPK6I9  plugs_auth/models.pyPK{:J0v*plugs_auth/__init__.pyPK}TI +plugs_auth/admin.pyPKȎI{$$<+plugs_auth/emails.pyPKz:J{s1plugs_auth/settings.pyPK}TIi;U5plugs_auth/runtests.pyPK}TIRKBB!7plugs_auth/tests/test_settings.pyPK}TI@C7plugs_auth/tests/test_models.pyPKjUIp:plugs_auth/tests/test_views.pyPK}TIwIplugs_auth/tests/__init__.pyPK}TIrݨ Iplugs_auth/tests/test_mails.pyPK}TI7vvSplugs_auth/tests/factories.pyPK}TI Vplugs_auth/templates/__init__.pyPKȎI%tAA4Vplugs_auth/templates/emails/activate_account_pt.htmlPKȎI=w""4gXplugs_auth/templates/emails/activate_account_en.htmlPKȎI<5Yplugs_auth/templates/emails/account_activated_pt.htmlPKȎI3Soo2Zplugs_auth/templates/emails/reset_password_pt.htmlPKȎI"腜5\plugs_auth/templates/emails/account_activated_en.htmlPK}TI']plugs_auth/templates/emails/__init__.pyPKȎI.Z2 ^plugs_auth/templates/emails/reset_password_en.htmlPK{:J1mm*`plugs_auth-0.1.6.dist-info/DESCRIPTION.rstPK{:JF3z(eplugs_auth-0.1.6.dist-info/metadata.jsonPK{:J# (iplugs_auth-0.1.6.dist-info/top_level.txtPK{:Jndnn jplugs_auth-0.1.6.dist-info/WHEELPK{:J>#jplugs_auth-0.1.6.dist-info/METADATAPK{:JԊ !splugs_auth-0.1.6.dist-info/RECORDPK ~