def login_view(request): """ Render the login form. Display an empty login form or check the submited credentials with the ones from the database. Add a success flash message, an userid in the cookies and redirect to the home page if the credentials are goods. Add an error flash message and display again the login form if the credentials are wrong. :param request: a ``pyramid.request`` object """ _ = request.translate form = Form(request, schema=LoginForm) if 'form_submitted' in request.params and form.validate(): username = request.params['username'] password = request.params['password'] if AuthUser.check_password(username, password): auth_user = AuthUser.get_by_username(username) headers = remember(request, auth_user.user_id) request.session.flash(_(u"Successful login."), 'success') return HTTPFound(location=request.route_path('home'), headers=headers) else: request.session.flash(_(u"Check your login credentials!"), 'error') return dict(renderer=FormRenderer(form))
def login_view(request): """ Render the login form. Display an empty login form or check the submited credentials with the ones from the database. Add a success flash message, an userid in the cookies and redirect to the home page if the credentials are goods. Add an error flash message and display again the login form if the credentials are wrong. :param request: a ``pyramid.request`` object """ _ = request.translate form = Form(request, schema=LoginForm) if 'form_submitted' in request.params and form.validate(): username = request.params['username'] password = request.params['password'] if AuthUser.check_password(username, password): auth_user = AuthUser.get_by_username(username) headers = remember(request, auth_user.user_id) request.session.flash(_(u"Successful login."), 'success') return HTTPFound(location=request.route_path('home'), headers=headers) else: request.session.flash(_(u"Check your login credentials!"), 'error') return dict(renderer=FormRenderer(form))
def test_AuthUser_get_by_username(self): """ Test the `get_by_username` method of the ``AuthUser`` model class. """ user = self.dummy_user_fixture() from anuket.models.auth import AuthUser self.assertTrue(AuthUser.get_by_username(u'username')) self.assertEqual(user, AuthUser.get_by_username(u'username'))
def test_AuthUser_get_by_username(self): """ Test the `get_by_username` method of the ``AuthUser`` model class. """ user = self.dummy_user_fixture() from anuket.models.auth import AuthUser self.assertTrue(AuthUser.get_by_username(u'username')) self.assertEqual(user, AuthUser.get_by_username(u'username'))
def test_AuthUser_check_password(self): """ Test the `check_password` method of the ``AuthUser`` model class. """ self.dummy_user_fixture() from anuket.models.auth import AuthUser self.assertTrue(AuthUser.check_password(u'username', u'password')) self.assertFalse(AuthUser.check_password(u'username', u'wrongpass')) self.assertFalse(AuthUser.check_password(u'nobody', u'password'))
def test_AuthUser_check_password(self): """ Test the `check_password` method of the ``AuthUser`` model class. """ self.dummy_user_fixture() from anuket.models.auth import AuthUser self.assertTrue(AuthUser.check_password(u'username', u'password')) self.assertFalse(AuthUser.check_password(u'username', u'wrongpass')) self.assertFalse(AuthUser.check_password(u'nobody', u'password'))
def initialize_db(self): """ Initialize the database schema and insert default values. :return: 0 (OK) or 1 (abnormal termination error) """ config_uri = self.args.config_uri settings = get_appsettings(config_uri) engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) # check if there is already a versioned database revision = get_alembic_revision(config_uri) if revision: print("This database is versioned. " "Use the upgrade script instead!") return 1 # create the tables (except alembic_version) Base.metadata.create_all(engine) # add default user & group values with transaction.manager: admins_group = AuthGroup() admins_group.groupname = u'admins' admin_user = AuthUser() admin_user.username = u'admin' admin_user.password = u'admin' admin_user.group = admins_group try: DBSession.add(admins_group) DBSession.add(admin_user) DBSession.flush() except IntegrityError: DBSession.rollback() print("There is already a database. " "Use the upgrade script instead!") return 1 # stamp the database with the most recent revision # (and create alembic_version table) try: alembic_cfg = get_alembic_settings(config_uri) stamp(alembic_cfg, 'head') except (AttributeError, ImportError): # pragma: no cover # alembic is missing or not configured pass print("Database initialization done.") return 0
def initialize_db(self): """ Initialize the database schema and insert default values. :return: 0 (OK) or 1 (abnormal termination error) """ config_uri = self.args.config_uri settings = get_appsettings(config_uri) engine = engine_from_config(settings, 'sqlalchemy.') DBSession.configure(bind=engine) # check if there is already a versioned database revision = get_alembic_revision(config_uri) if revision: print("This database is versioned. " "Use the upgrade script instead!") return 1 # create the tables (except alembic_version) Base.metadata.create_all(engine) # add default user & group values with transaction.manager: admins_group = AuthGroup() admins_group.groupname = u'admins' admin_user = AuthUser() admin_user.username = u'admin' admin_user.password = u'admin' admin_user.group = admins_group try: DBSession.add(admins_group) DBSession.add(admin_user) DBSession.flush() except IntegrityError: DBSession.rollback() print("There is already a database. " "Use the upgrade script instead!") return 1 # stamp the database with the most recent revision # (and create alembic_version table) try: alembic_cfg = get_alembic_settings(config_uri) stamp(alembic_cfg, 'head') except (AttributeError, ImportError): # pragma: no cover # alembic is missing or not configured pass print("Database initialization done.") return 0
def admin_user_fixture(self): """ Create an admin auth user test fixture in the database.""" try: from anuket.models.auth import AuthUser group = self.admin_group_fixture() user = AuthUser() user.username = u'admin' user.password = u'admin' user.group = group self.DBSession.add(user) self.DBSession.flush() return user except: # pragma: no cover self.DBSession.rollback() raise AssertionError
def admin_user_fixture(self): """ Create an admin auth user test fixture in the database.""" try: from anuket.models.auth import AuthUser group = self.admin_group_fixture() user = AuthUser() user.username = u'admin' user.password = u'admin' user.group = group self.DBSession.add(user) self.DBSession.flush() return user except: # pragma: no cover self.DBSession.rollback() raise AssertionError
def password_edit_view(request): """ Render the change password form page. Seek the database for the user datas based on user_id used in the route. If the user did not exist then add an error flash message and redirect to the user list. If the user exist then render an empty password form. If the form is validated then change the user password in the database and add success flash message. If the form is not valid, then display again the form with validation errors. :param request: a ``pyramid.request`` object """ _ = request.translate user_id = request.matchdict['user_id'] user = AuthUser.get_by_id(user_id) if not user: request.session.flash(_(u"This user did not exist!"), 'error') return HTTPFound(location=request.route_path('tools.user_list')) form = Form(request, schema=UserPasswordForm, obj=user) if 'form_submitted' in request.params and form.validate(): form.bind(user) DBSession.add(user) request.session.flash(_(u"Password updated."), 'success') return HTTPFound(location=request.route_path('tools.user_list')) return dict(renderer=FormRenderer(form))
def password_edit_view(request): """ Render the change password form page. Seek the database for the user datas based on user_id used in the route. If the user did not exist then add an error flash message and redirect to the user list. If the user exist then render an empty password form. If the form is validated then change the user password in the database and add success flash message. If the form is not valid, then display again the form with validation errors. :param request: a ``pyramid.request`` object """ _ = request.translate user_id = request.matchdict['user_id'] user = AuthUser.get_by_id(user_id) if not user: request.session.flash(_(u"This user did not exist!"), 'error') return HTTPFound(location=request.route_path('tools.user_list')) form = Form(request, schema=UserPasswordForm, obj=user) if 'form_submitted' in request.params and form.validate(): form.bind(user) DBSession.add(user) request.session.flash(_(u"Password updated."), 'success') return HTTPFound(location=request.route_path('tools.user_list')) return dict(renderer=FormRenderer(form))
def test_AuthUser_username_unique_constraint(self): """ Test `username` uniqueness in the ``AuthUser`` model class.""" self.dummy_user_fixture() from anuket.models.auth import AuthUser from sqlalchemy.exc import IntegrityError duplicate = AuthUser(username=u'username') self.DBSession.add(duplicate) self.assertRaises(IntegrityError, self.DBSession.flush)
def get_auth_user(request): """ Get the authenticated user id from the request and return an `AuthUser` object. :param request: a ``pyramid.request`` object """ user_id = unauthenticated_userid(request) if user_id: return AuthUser.get_by_id(user_id)
def test_user_show_view(self): """ Test the response of the `user_show` view.""" self.dummy_user_fixture() from anuket.views.user import user_show_view request = AnuketDummyRequest() request.matchdict = {'user_id': 1} response = user_show_view(request) from anuket.models.auth import AuthUser user = AuthUser.get_by_id(1) self.assertIsInstance(response['user'], AuthUser) self.assertEqual(response['user'], user)
def test_user_show_view(self): """ Test the response of the `user_show` view.""" self.dummy_user_fixture() from anuket.views.user import user_show_view request = AnuketDummyRequest() request.matchdict = {'user_id': 1} response = user_show_view(request) from anuket.models.auth import AuthUser user = AuthUser.get_by_id(1) self.assertIsInstance(response['user'], AuthUser) self.assertEqual(response['user'], user)
def test_initialize_db_default_values(self): """ Test than the `initialize_db` method add the default values to the initialized database. """ command = self._makeOne() command.args.config_uri = self.config_uri command.initialize_db() from anuket.models.auth import AuthUser user = self.DBSession.query(AuthUser).filter_by().first() self.assertEqual(user.username, u'admin') self.assertTrue(AuthUser.check_password(u'admin', u'admin')) self.assertEqual(user.group.groupname, u'admins')
def test_initialize_db_default_values(self): """ Test than the `initialize_db` method add the default values to the initialized database. """ command = self._makeOne() command.args.config_uri = self.config_uri command.initialize_db() from anuket.models.auth import AuthUser user = self.DBSession.query(AuthUser).filter_by().first() self.assertEqual(user.username, u'admin') self.assertTrue(AuthUser.check_password(u'admin', u'admin')) self.assertEqual(user.group.groupname, u'admins')
def test_direct_user_delete_is_forbiden_for_anonymous(self): """ Test than direct delete is forbiden for non logged users.""" user = self.dummy_user_fixture() response = self.testapp.get('/tools/user/1/delete', status=302) redirect = response.follow() self.assertEqual(redirect.status, '200 OK') self.assertEqual(redirect.request.path, '/login') self.assertTrue('You are not connected.' in redirect.body) # check than the user is effectively still in the database from anuket.models.auth import AuthUser usercheck = AuthUser.get_by_id(1) self.assertTrue(usercheck, user)
def test_direct_user_delete_is_forbiden_for_anonymous(self): """ Test than direct delete is forbiden for non logged users.""" user = self.dummy_user_fixture() response = self.testapp.get('/tools/user/1/delete', status=302) redirect = response.follow() self.assertEqual(redirect.status, '200 OK') self.assertEqual(redirect.request.path, '/login') self.assertTrue('You are not connected.' in redirect.body) # check than the user is effectively still in the database from anuket.models.auth import AuthUser usercheck = AuthUser.get_by_id(1) self.assertTrue(usercheck, user)
def root_view(request): """ Render the root pages. Render the home page, the login page and 404 not found page. :param request: a ``pyramid.request`` object """ _ = request.translate #check the default admin password if any admin is connected from pyramid.security import has_permission if has_permission('admin', request.context, request): if AuthUser.check_password(username=u'admin', password=u'admin'): request.session.flash(_("Change the default password!"), 'error') return dict()
def groupfinder(user_id, request): """ Groupfinder callback for authentification policy. Return the groupname (principal) of an authenticated user form the database. Return None if the user do not exist. :param user_id: the id of the authenticated user :type user_id: integer :param request: a ``pyramid.request`` object :return: the user groupname or None """ auth_user = AuthUser.get_by_id(user_id) if auth_user: auth_group = auth_user.group.groupname return [('group:%s' % auth_group)]
def root_view(request): """ Render the root pages. Render the home page, the login page and 404 not found page. :param request: a ``pyramid.request`` object """ _ = request.translate #check the default admin password if any admin is connected from pyramid.security import has_permission if has_permission('admin', request.context, request): if AuthUser.check_password(username=u'admin', password=u'admin'): request.session.flash(_("Change the default password!"), 'error') return dict()
def user_show_view(request): """ Render the show user datas page. Seek the database for the user datas based on user_id used in the route. If the user did not exist then add an error flash message and redirect to the user list. If the user exist then return his datas. :param request: a ``pyramid.request`` object """ _ = request.translate user_id = request.matchdict['user_id'] user = AuthUser.get_by_id(user_id) if not user: request.session.flash(_(u"This user did not exist!"), 'error') return HTTPFound(location=request.route_path('tools.user_list')) return dict(user=user)
def user_show_view(request): """ Render the show user datas page. Seek the database for the user datas based on user_id used in the route. If the user did not exist then add an error flash message and redirect to the user list. If the user exist then return his datas. :param request: a ``pyramid.request`` object """ _ = request.translate user_id = request.matchdict['user_id'] user = AuthUser.get_by_id(user_id) if not user: request.session.flash(_(u"This user did not exist!"), 'error') return HTTPFound(location=request.route_path('tools.user_list')) return dict(user=user)
def dummy_user_fixture(self): """ Create a dummy auth user test fixture in the database.""" try: from anuket.models.auth import AuthUser group = self.dummy_group_fixture() user = AuthUser() user.username = u'username' user.first_name = u'firstname' user.last_name = u'lastname' user.email = u'*****@*****.**' user.password = u'password' user.group = group self.DBSession.add(user) self.DBSession.flush() return user except: # pragma: no cover self.DBSession.rollback() raise AssertionError
def validate_python(self, values, state): """ Check for the uniqueness of `email`.""" if 'email' in values: email = values['email'] user = AuthUser.get_by_email(email) else: user = None # no check for None emails or empty value # user_id is used to not raise an error when editing the user # the user_id must be available as hidden field in the edit form if 'user_id' in values: user_id = values['user_id'] else: user_id = None if user and (user.user_id != user_id): errors = {'email': self.message('not_unique_email', state)} raise Invalid(self.message('not_unique_email', state), values, state, error_dict=errors)
def dummy_user_fixture(self): """ Create a dummy auth user test fixture in the database.""" try: from anuket.models.auth import AuthUser group = self.dummy_group_fixture() user = AuthUser() user.username = u'username' user.first_name = u'firstname' user.last_name = u'lastname' user.email = u'*****@*****.**' user.password = u'password' user.group = group self.DBSession.add(user) self.DBSession.flush() return user except: # pragma: no cover self.DBSession.rollback() raise AssertionError
def user_add_view(request): """ Render the add user form page. Display an empty user form or validate the user submited form. If the form is validated then add the user datas to the database and a success flash message. If the form is not valid, then display again the form with validation errors. Return also a list of groups to use in the group select form. :param request: a ``pyramid.request`` object """ _ = request.translate grouplist = get_grouplist() form = Form(request, schema=UserForm) if 'form_submitted' in request.params and form.validate(): user = form.bind(AuthUser()) DBSession.add(user) request.session.flash(_(u"User added."), 'success') return HTTPFound(location=request.route_path('tools.user_list')) return dict(renderer=FormRenderer(form), grouplist=grouplist)
def user_delete_view(request): """ Delete an user. Seek the database for the user datas based on user_id used in the route. If the user did not exist then add an error flash message and redirect to the user list. If the user exist then delete the user in the database, add a warning flash message and then redirect to the user list. :param request: a ``pyramid.request`` object """ # The confirm delete must be managed by modal messages in the templates, # and we forbid direct deletion from the address bar (no referer) _ = request.translate if not request.referer: request.session.flash(_(u"Insufficient permissions!"), 'error') return HTTPFound(location=request.route_path('home')) user_id = request.matchdict['user_id'] user = AuthUser.get_by_id(user_id) if not user: request.session.flash(_(u"This user did not exist!"), 'error') return HTTPFound(location=request.route_path('tools.user_list')) #forbid the deletion if it's the only admin user if user.group.groupname == u'admins': adminscount = DBSession.query(AuthUser.user_id).join(AuthGroup).\ filter(AuthGroup.groupname == u'admins').\ count() if adminscount == 1: request.session.flash(_(u"Deletion of the only admin forbidden!"), 'error') return HTTPFound(location=request.route_path('tools.user_list')) DBSession.delete(user) request.session.flash(_(u"User deleted."), 'warn') return HTTPFound(location=request.route_path('tools.user_list'))
def user_delete_view(request): """ Delete an user. Seek the database for the user datas based on user_id used in the route. If the user did not exist then add an error flash message and redirect to the user list. If the user exist then delete the user in the database, add a warning flash message and then redirect to the user list. :param request: a ``pyramid.request`` object """ # The confirm delete must be managed by modal messages in the templates, # and we forbid direct deletion from the address bar (no referer) _ = request.translate if not request.referer: request.session.flash(_(u"Insufficient permissions!"), 'error') return HTTPFound(location=request.route_path('home')) user_id = request.matchdict['user_id'] user = AuthUser.get_by_id(user_id) if not user: request.session.flash(_(u"This user did not exist!"), 'error') return HTTPFound(location=request.route_path('tools.user_list')) #forbid the deletion if it's the only admin user if user.group.groupname == u'admins': adminscount = DBSession.query(AuthUser.user_id).join(AuthGroup).\ filter(AuthGroup.groupname == u'admins').\ count() if adminscount == 1: request.session.flash(_(u"Deletion of the only admin forbidden!"), 'error') return HTTPFound(location=request.route_path('tools.user_list')) DBSession.delete(user) request.session.flash(_(u"User deleted."), 'warn') return HTTPFound(location=request.route_path('tools.user_list'))