OAuth2Facebook( client_id=settings.OAUTH2FACEBOOK_CLIENT_ID, client_secret=settings.OAUTH2FACEBOOK_CLIENT_SECRET, callback_url="auth/plugin/oauth2facebook/callback", )) if settings.OAUTH2OKTA_CLIENT_ID: from py4web.utils.auth_plugins.oauth2okta import OAuth2Okta # TESTED auth.register_plugin( OAuth2Okta( client_id=settings.OAUTH2OKTA_CLIENT_ID, client_secret=settings.OAUTH2OKTA_CLIENT_SECRET, callback_url="auth/plugin/oauth2okta/callback", )) if settings.USE_CELERY: from celery import Celery # to use from . common import scheduled and then use it accoding to celery docs # examples in tasks.py scheduler = Celery("apps.%s.tasks" % settings.APP_NAME, broker=settings.CELERY_BROKER) # we enable auth, which requres sessions, T, db and we make T available to # the template, although we recommend client-side translations instead auth.enable(uses=(session, T, db), env=dict(T=T)) unauthenticated = ActionFactory(db, session, T, flash, auth) authenticated = ActionFactory(db, session, T, flash, auth.user)
if auth.db: groups = Tags(db.auth_user, 'groups') if settings.USE_PAM: from py4web.utils.auth_plugins.pam_plugin import PamPlugin auth.register_plugin(PamPlugin()) if settings.USE_LDAP: from py4web.utils.auth_plugins.ldap_plugin import LDAPPlugin auth.register_plugin(LDAPPlugin(**settings.LDAP_SETTINGS)) if settings.OAUTH2GOOGLE_CLIENT_ID: from py4web.utils.auth_plugins.oauth2google import OAuth2Google # TESTED auth.register_plugin( OAuth2Google(client_id=settings.OAUTH2GOOGLE_CLIENT_ID, client_secret=settings.OAUTH2GOOGLE_CLIENT_SECRET, callback_url='auth/plugin/oauth2google/callback')) if settings.OAUTH2FACEBOOK_CLIENT_ID: from py4web.utils.auth_plugins.oauth2facebook import OAuth2Facebook # UNTESTED auth.register_plugin( OAuth2Facebook(client_id=settings.OAUTH2FACEBOOK_CLIENT_ID, client_secret=settings.OAUTH2FACEBOOK_CLIENT_SECRET, callback_url='auth/plugin/oauth2google/callback')) auth.enable() unauthenticated = ActionFactory(db, session, T, auth) authenticated = ActionFactory(db, session, T, auth.user) signed_url = URLSigner(session)
class TestAuth(unittest.TestCase): def setUp(self): os.environ['PY4WEB_APPS_FOLDER'] = 'apps' self.db = DAL('sqlite:memory') self.session = Session(secret="a", expiration=10) self.session.local.data = {} self.auth = Auth(self.session, self.db, define_tables=True) self.auth.enable() request.app_name = '_scaffold' def test_register_invalid(self): body = {'email': '*****@*****.**'} self.assertEqual( self.auth.action('api/register', 'POST', {}, body), { 'id': None, 'errors': { 'username': '******', 'password': '******', 'first_name': 'Enter a value', 'last_name': 'Enter a value' }, 'status': 'error', 'message': 'validation errors', 'code': 401 }) def test_register(self): body = { 'username': '******', 'email': '*****@*****.**', 'password': '******', 'first_name': 'Pinco', 'last_name': 'Pallino' } self.assertEqual(self.auth.action('api/register', 'POST', {}, body), { 'id': 1, 'status': 'success', 'code': 200 }) user = self.db.auth_user[1] self.assertTrue(user.action_token.startswith('pending-registration')) self.assertEqual(self.auth.get_user(), {}) body = {'email': '*****@*****.**', 'password': '******'} self.assertTrue(self.auth.action('api/login', 'POST', {}, body), { 'status': 'error', 'message': 'Registration is pending', 'code': 400 }) token = user.action_token[len('pending-registration') + 1:] try: self.auth.action('verify_email', 'GET', {'token': token}, {}) assert False, 'email not verified' except HTTP: pass user = self.db.auth_user[1] self.assertTrue(user.action_token == None) self.assertEqual(self.auth.action('api/login', 'POST', {}, body), { 'status': 'error', 'message': 'Invalid Credentials', 'code': 400 }) body = {'email': '*****@*****.**', 'password': '******'} self.assertEqual( self.auth.action('api/login', 'POST', {}, body), { 'user': { 'id': 1, 'username': '******', 'email': '*****@*****.**', 'first_name': 'Pinco', 'last_name': 'Pallino', }, 'status': 'success', 'code': 200 }) body = { 'email': 'ppallino', # can login with both email and username 'password': '******' } self.assertEqual( self.auth.action('api/login', 'POST', {}, body), { 'user': { 'id': 1, 'username': '******', 'email': '*****@*****.**', 'first_name': 'Pinco', 'last_name': 'Pallino', }, 'status': 'success', 'code': 200 }) body = {'email': '*****@*****.**'} self.assertEqual( self.auth.action('api/request_reset_password', 'POST', {}, body), { 'status': 'success', 'code': 200 }) body = {'token': 'junk', 'new_password': '******'} self.assertTrue( self.auth.action('api/reset_password', 'POST', {}, body), { 'status': 'error', 'message': 'invalid token, request expired', 'code': 400 }) body = { 'token': self.auth._link.split('?token=')[1], 'new_password': '******' } self.assertTrue( self.auth.action('api/reset_password', 'POST', {}, body), { 'status': 'success', 'code': 200 }) self.assertEqual( self.auth.get_user(), { 'id': 1, 'username': '******', 'email': '*****@*****.**', 'first_name': 'Pinco', 'last_name': 'Pallino' }) body = {} self.assertEqual( self.auth.action('api/change_password', 'POST', {}, body), { 'errors': { 'password': '******' }, 'status': 'error', 'message': 'validation errors', 'code': 401 }) body = {'password': '******', 'new_password': '******'} self.assertEqual( self.auth.action('api/change_password', 'POST', {}, body), { 'updated': 1, 'status': 'success', 'code': 200 }) body = {'password': '******', 'new_email': '*****@*****.**'} self.assertEqual( self.auth.action('api/change_email', 'POST', {}, body), { 'updated': 1, 'status': 'success', 'code': 200 }) body = {'first_name': 'Max', 'last_name': 'Powers', 'password': '******'} self.assertEqual( self.auth.action('api/profile', 'POST', {}, body), { 'errors': { 'password': '******' }, 'status': 'error', 'message': 'validation errors', 'code': 401 }) body = {'first_name': 'Max', 'last_name': 'Powers'} self.assertEqual(self.auth.action('api/profile', 'POST', {}, body), { 'updated': 1, 'status': 'success', 'code': 200 })
class TestAuth(unittest.TestCase): def setUp(self): os.environ["PY4WEB_APPS_FOLDER"] = "apps" self.db = DAL("sqlite:memory") self.session = Session(secret="a", expiration=10) self.session.local.data = {} self.auth = Auth(self.session, self.db, define_tables=True) self.auth.enable() request.app_name = "_scaffold" def test_register_invalid(self): body = {"email": "*****@*****.**"} self.assertEqual( self.auth.action("api/register", "POST", {}, body), { "id": None, "errors": { "username": "******", "password": "******", "first_name": "Enter a value", "last_name": "Enter a value", }, "status": "error", "message": "validation errors", "code": 401, }, ) def test_register(self): body = { "username": "******", "email": "*****@*****.**", "password": "******", "first_name": "Pinco", "last_name": "Pallino", } self.assertEqual( self.auth.action("api/register", "POST", {}, body), { "id": 1, "status": "success", "code": 200 }, ) user = self.db.auth_user[1] self.assertTrue(user.action_token.startswith("pending-registration")) self.assertEqual(self.auth.get_user(), {}) body = {"email": "*****@*****.**", "password": "******"} self.assertTrue( self.auth.action("api/login", "POST", {}, body), { "status": "error", "message": "Registration is pending", "code": 400 }, ) token = user.action_token[len("pending-registration") + 1:] try: self.auth.action("verify_email", "GET", {"token": token}, {}) assert False, "email not verified" except HTTP: pass user = self.db.auth_user[1] self.assertTrue(user.action_token == None) self.assertEqual( self.auth.action("api/login", "POST", {}, body), { "status": "error", "message": "Invalid Credentials", "code": 400 }, ) body = {"email": "*****@*****.**", "password": "******"} self.assertEqual( self.auth.action("api/login", "POST", {}, body), { "user": { "id": 1, "username": "******", "email": "*****@*****.**", "first_name": "Pinco", "last_name": "Pallino", }, "status": "success", "code": 200, }, ) body = { "email": "ppallino", # can login with both email and username "password": "******", } self.assertEqual( self.auth.action("api/login", "POST", {}, body), { "user": { "id": 1, "username": "******", "email": "*****@*****.**", "first_name": "Pinco", "last_name": "Pallino", }, "status": "success", "code": 200, }, ) body = {"email": "*****@*****.**"} self.assertEqual( self.auth.action("api/request_reset_password", "POST", {}, body), { "status": "success", "code": 200 }, ) body = {"token": "junk", "new_password": "******"} self.assertTrue( self.auth.action("api/reset_password", "POST", {}, body), { "status": "error", "message": "invalid token, request expired", "code": 400, }, ) body = { "token": self.auth._link.split("?token=")[1], "new_password": "******", } self.assertTrue( self.auth.action("api/reset_password", "POST", {}, body), { "status": "success", "code": 200 }, ) self.assertEqual( self.auth.get_user(), { "id": 1, "username": "******", "email": "*****@*****.**", "first_name": "Pinco", "last_name": "Pallino", }, ) body = {} self.assertEqual( self.auth.action("api/change_password", "POST", {}, body), { "errors": { "password": "******" }, "status": "error", "message": "validation errors", "code": 401, }, ) body = {"password": "******", "new_password": "******"} self.assertEqual( self.auth.action("api/change_password", "POST", {}, body), { "updated": 1, "status": "success", "code": 200 }, ) body = {"password": "******", "new_email": "*****@*****.**"} self.assertEqual( self.auth.action("api/change_email", "POST", {}, body), { "updated": 1, "status": "success", "code": 200 }, ) body = {"first_name": "Max", "last_name": "Powers", "password": "******"} self.assertEqual( self.auth.action("api/profile", "POST", {}, body), { "errors": { "password": "******" }, "status": "error", "message": "validation errors", "code": 401, }, ) body = {"first_name": "Max", "last_name": "Powers"} self.assertEqual( self.auth.action("api/profile", "POST", {}, body), { "updated": 1, "status": "success", "code": 200 }, )
class TestAuth(unittest.TestCase): def setUp(self): os.environ["PY4WEB_APPS_FOLDER"] = "apps" _before_request() # mimic before_request bottle-hook self.db = DAL("sqlite:memory") self.session = Session(secret="a", expiration=10) self.session.initialize() self.auth = Auth(self.session, self.db, define_tables=True, password_complexity=None) self.auth.enable() self.auth.action = self.action request.app_name = "_scaffold" def tearDown(self): bottle.app.router.remove('/*') def action(self, name, method, query, data): request.environ['REQUEST_METHOD'] = method request.environ['ombott.request.query'] = query request.environ['ombott.request.json'] = data # we break a symmetry below. should fix in auth.py if name.startswith('api/'): return getattr(AuthAPI, name[4:])(self.auth) else: return getattr(self.auth.form_source, name)() def on_request(self, keep_session=False): storage = self.session._safe_local # mimic before_request bottle-hook _before_request() # mimic action.uses() self.session.initialize() self.auth.flash.on_request() self.auth.on_request() if keep_session: self.session._safe_local = storage def test_extra_fields(self): db = DAL("sqlite:memory") self.auth = Auth(self.session, db, define_tables=True, extra_fields=[Field('favorite_color')]) self.on_request() self.assertEqual(type(db.auth_user.favorite_color), Field) def test_register_invalid(self): self.on_request() body = {"email": "*****@*****.**"} self.assertEqual( self.auth.action("api/register", "POST", {}, body), { "id": None, "errors": { "username": "******", "password": "******", "first_name": "Enter a value", "last_name": "Enter a value", }, "status": "error", "message": "validation errors", "code": 401, }, ) def test_register(self): self.on_request() body = { "username": "******", "email": "*****@*****.**", "password": "******", "first_name": "Pinco", "last_name": "Pallino", } self.assertEqual( self.auth.action("api/register", "POST", {}, body), { "id": 1, "status": "success", "code": 200 }, ) user = self.db.auth_user[1] self.assertTrue(user.action_token.startswith("pending-registration")) self.assertEqual(self.auth.get_user(), {}) self.on_request() body = {"email": "*****@*****.**", "password": "******"} self.assertEqual( self.auth.action("api/login", "POST", {}, body), { "status": "error", "message": "Registration is pending", "code": 400 }, ) self.on_request() token = user.action_token[len("pending-registration") + 1:] try: self.auth.action("verify_email", "GET", {"token": token}, {}) assert False, "email not verified" except HTTP: pass user = self.db.auth_user[1] self.assertTrue(user.action_token is None) self.on_request() self.assertEqual( self.auth.action("api/login", "POST", {}, body), { "status": "error", "message": "Invalid Credentials", "code": 400 }, ) self.on_request() body = {"email": "*****@*****.**", "password": "******"} self.assertEqual( self.auth.action("api/login", "POST", {}, body), { "user": { "id": 1, "username": "******", "email": "*****@*****.**", "first_name": "Pinco", "last_name": "Pallino", }, "status": "success", "code": 200, }, ) self.on_request() body = { "email": "ppallino", # can login with both email and username "password": "******", } self.assertEqual( self.auth.action("api/login", "POST", {}, body), { "user": { "id": 1, "username": "******", "email": "*****@*****.**", "first_name": "Pinco", "last_name": "Pallino", }, "status": "success", "code": 200, }, ) self.on_request(keep_session=True) body = {"email": "*****@*****.**"} self.assertEqual( self.auth.action("api/request_reset_password", "POST", {}, body), { "status": "success", "code": 200 }, ) self.on_request(keep_session=True) body = {"token": "junk", "new_password": "******"} self.assertEqual( self.auth.action("api/reset_password", "POST", {}, body), { "status": "error", "message": "validation errors", "errors": { "token": "invalid token" }, "code": 401, }, ) self.on_request(keep_session=True) body = { "token": self.auth._link.split("?token=")[1], "new_password": "******", "new_password2": "987654321", } self.assertEqual( self.auth.action("api/reset_password", "POST", {}, body), { "status": "success", "code": 200 }, ) self.assertEqual( self.auth.get_user(), { "id": 1, "username": "******", "email": "*****@*****.**", "first_name": "Pinco", "last_name": "Pallino", }, ) self.on_request(keep_session=True) body = {} self.assertEqual( self.auth.action("api/change_password", "POST", {}, body), { 'errors': { 'old_password': '******' }, "status": "error", "message": "validation errors", "code": 401, }, ) self.on_request(keep_session=True) body = {"old_password": "******", "new_password": "******"} self.assertEqual( self.auth.action("api/change_password", "POST", {}, body), { "updated": 1, "status": "success", "code": 200 }, ) self.on_request(keep_session=True) body = {"password": "******", "new_email": "*****@*****.**"} self.assertEqual( self.auth.action("api/change_email", "POST", {}, body), { "updated": 1, "status": "success", "code": 200 }, ) self.on_request(keep_session=True) body = {"first_name": "Max", "last_name": "Powers", "password": "******"} self.assertEqual( self.auth.action("api/profile", "POST", {}, body), { "errors": { "password": "******" }, "status": "error", "message": "validation errors", "code": 401, }, ) self.on_request(keep_session=True) body = {"first_name": "Max", "last_name": "Powers"} self.assertEqual( self.auth.action("api/profile", "POST", {}, body), { "updated": 1, "status": "success", "code": 200 }, )
from py4web.utils.auth_plugins.ldap_plugin import LDAPPlugin auth.register_plugin(LDAPPlugin(**settings.LDAP_SETTINGS)) if settings.OAUTH2GOOGLE_CLIENT_ID: from py4web.utils.auth_plugins.oauth2google import OAuth2Google # TESTED auth.register_plugin( OAuth2Google( client_id=settings.OAUTH2GOOGLE_CLIENT_ID, client_secret=settings.OAUTH2GOOGLE_CLIENT_SECRET, callback_url="auth/plugin/oauth2google/callback", )) if settings.OAUTH2FACEBOOK_CLIENT_ID: from py4web.utils.auth_plugins.oauth2facebook import OAuth2Facebook # UNTESTED auth.register_plugin( OAuth2Facebook( client_id=settings.OAUTH2FACEBOOK_CLIENT_ID, client_secret=settings.OAUTH2FACEBOOK_CLIENT_SECRET, callback_url="auth/plugin/oauth2google/callback", )) # we enable auth, which requres sessions, T, db and we make T available to # the template, although we recommend client-side translations instead from py4web.utils.cors import CORS auth.enable(uses=(session, T, db, CORS()), env=dict(T=T)) unauthenticated = ActionFactory(db, session, T, auth) authenticated = ActionFactory(db, session, T, auth.user)