def delete(request): """Handles the "/users/{uid}/delete" URL, providing the form and backend functionality for deleting a :class:`~wte.models.User`. Also deletes all the data that is linked to that :class:`~wte.models.User`. """ dbsession = DBSession() user = dbsession.query(User).filter( User.id == request.matchdict['uid']).first() if user: if user.allow('delete', request.current_user): if request.method == 'POST': try: CSRFSchema().to_python(request.params, State(request=request)) with transaction.manager: dbsession.delete(user) request.session.flash('The account has been deleted', queue='info') if request.current_user.has_permission('admin.users.view'): raise HTTPSeeOther(request.route_url('users')) else: raise HTTPSeeOther(request.route_url('root')) except Invalid as e: return { 'errors': e.error_dict, 'user': user, 'crumbs': create_user_crumbs( request, [{ 'title': user.display_name, 'url': request.route_url('user.view', uid=user.id) }, { 'title': 'Delete', 'url': request.route_url('user.delete', uid=user.id) }]) } return { 'user': user, 'crumbs': create_user_crumbs( request, [{ 'title': user.display_name, 'url': request.route_url('user.view', uid=user.id) }, { 'title': 'Delete', 'url': request.route_url('user.delete', uid=user.id) }]) } else: unauthorised_redirect(request) else: raise HTTPNotFound()
def action(request): """Handles the ``/users/action`` URL, applying the given action to the list of selected users. Requires that the current :class:`~wte.models.User` has the "admin.users.view" :class:`~wte.models.Permission`. """ dbsession = DBSession() try: query_params = [] for param in ['q', 'status', 'start']: if param in request.params and request.params[param]: query_params.append((param, request.params[param])) params = ActionSchema().to_python(request.params, State(request=request)) if params['action'] != 'delete' or params['confirm']: with transaction.manager: for user in dbsession.query(User).filter( User.id.in_(params['user_id'])): if params['action'] == 'validate': if user.status == 'unconfirmed' and user.allow( 'edit', request.current_user): user.status = 'active' elif params['action'] == 'delete': if user.allow('delete', request.current_user): dbsession.delete(user) elif params['action'] == 'password': if user.status == 'active' and user.allow( 'edit', request.current_user): token = TimeToken( user.id, 'reset_password', datetime.now() + timedelta(seconds=1200)) dbsession.add(token) dbsession.flush() if 'user.password_reset' in active_callbacks: active_callbacks['user.password_reset']( request, user, token) raise HTTPSeeOther(request.route_url('users', _query=query_params)) else: return { 'params': params, 'users': dbsession.query(User).filter(User.id.in_(params['user_id'])), 'query_params': query_params, 'crumbs': create_user_crumbs(request, [{ 'title': 'Confirm', 'url': request.current_route_url() }]) } except Invalid as e: print(e) request.session.flash( 'Please select the action you wish to apply and the users to apply it to', queue='error') raise HTTPSeeOther(request.route_url('users', _query=query_params))
def delete_part_task(request): """Handles the ``parts/{pid}/timed-tasks/{tid}/delete`` URL, providing the UI and backend for deleting an existing :class:`~wte.models.TimedTask` that belongs to a :class:`~wte.models.Part`. Requires that the user has "edit" rights on the :class:`~wte.models.Part`. """ dbsession = DBSession() part = dbsession.query(Part).filter( Part.id == request.matchdict['pid']).first() task = dbsession.query(TimedTask).filter( TimedTask.id == request.matchdict['tid']).first() if part and task: if part.allow('edit', request.current_user): crumbs = create_part_crumbs( request, part, [{ 'title': 'Timed Actions', 'url': request.route_url('part.timed_task', pid=part.id) }, { 'title': 'Delete', 'url': request.current_route_url }]) if request.method == 'POST': try: CSRFSchema().to_python(request.params, State(request=request)) dbsession = DBSession() with transaction.manager: dbsession.delete(task) dbsession.add(part) raise HTTPSeeOther( request.route_url('part.timed_task', pid=part.id)) except formencode.Invalid as e: return { 'errors': e.error_dict, 'part': part, 'task': task, 'crumbs': crumbs, 'include_footer': True, 'help': ['user', 'teacher', 'timed_actions.html'] } return { 'part': part, 'task': task, 'crumbs': crumbs, 'include_footer': True, 'help': ['user', 'teacher', 'timed_actions.html'] } else: unauthorised_redirect(request) else: raise HTTPNotFound()
def delete(request): dbsession = DBSession() experiment = dbsession.query(Experiment).filter(Experiment.id == request.matchdict['eid']).first() page = dbsession.query(Page).filter(and_(Page.id == request.matchdict['pid'], Page.experiment_id == request.matchdict['eid'])).first() if experiment and page: if request.method == 'POST': try: DeleteSchema().to_python(request.params, State(request=request, dbsession=dbsession)) with transaction.manager: dbsession.add(experiment) dbsession.add(page) if experiment.start == page: experiment.start = None dbsession.delete(page) dbsession.add(experiment) raise HTTPFound(request.route_url('experiment.page', eid=experiment.id)) except formencode.Invalid as e: return {'experiment': experiment, 'page': page, 'crumbs': [{'title': 'Experiments', 'url': request.route_url('dashboard')}, {'title': experiment.title, 'url': request.route_url('experiment.view', eid=experiment.id)}, {'title': 'Pages', 'url': request.route_url('experiment.page', eid=experiment.id)}, {'title': '%s (%s)' % (page.title, page.name) if page.title else 'No title (%s)' % page.name, 'url': request.route_url('experiment.page.edit', eid=experiment.id, pid=page.id)}, {'title': 'Delete', 'url': request.route_url('experiment.page.delete', eid=experiment.id, pid=page.id)}], 'values': request.params, 'errors': e.error_dict} return {'experiment': experiment, 'page': page, 'crumbs': [{'title': 'Experiments', 'url': request.route_url('dashboard')}, {'title': experiment.title, 'url': request.route_url('experiment.view', eid=experiment.id)}, {'title': 'Pages', 'url': request.route_url('experiment.page', eid=experiment.id)}, {'title': '%s (%s)' % (page.title, page.name) if page.title else 'No title (%s)' % page.name, 'url': request.route_url('experiment.page.edit', eid=experiment.id, pid=page.id)}, {'title': 'Delete', 'url': request.route_url('experiment.page.delete', eid=experiment.id, pid=page.id)}]} else: raise HTTPNotFound()
def delete(request): """Handles the ``/parts/{pid}/assets/{aid}/delete`` URL, providing the UI and backend for deleting :class:`~wte.models.Asset`. Requires that the user has "edit" rights on the current :class:`~wte.models.Part`. """ dbsession = DBSession() part = dbsession.query(Part).filter( Part.id == request.matchdict['pid']).first() asset = dbsession.query(Asset).join(Part.all_assets).\ filter(and_(Asset.id == request.matchdict['aid'], Part.id == request.matchdict['pid'])).first() if part and asset: if part.allow('edit', request.current_user): crumbs = create_part_crumbs(request, part, { 'title': 'Delete Asset', 'url': request.current_route_url() }) if request.method == 'POST': try: CSRFSchema().to_python(request.params, State(request=request)) dbsession = DBSession() with transaction.manager: dbsession.add(asset) asset.parts = [] dbsession.delete(asset) dbsession.add(part) raise HTTPSeeOther( request.route_url('part.view', pid=part.id)) except formencode.Invalid as e: return { 'errors': e.error_dict, 'part': part, 'asset': asset, 'crumbs': crumbs, 'help': ['user', 'teacher', 'asset', 'delete.html'] } return { 'part': part, 'asset': asset, 'crumbs': crumbs, 'help': ['user', 'teacher', 'asset', 'delete.html'] } else: unauthorised_redirect(request) else: raise HTTPNotFound()
def data_item_delete(request): dbsession = DBSession() experiment = dbsession.query(Experiment).filter( Experiment.id == request.matchdict['eid']).first() data_set = dbsession.query(DataSet).filter( and_(DataSet.id == request.matchdict['did'], DataSet.experiment_id == request.matchdict['eid'], DataSet.type == 'dataset')).first() data_item = dbsession.query(DataItem).filter( and_(DataItem.id == request.matchdict['diid'], DataItem.dataset_id == request.matchdict['did'])).first() if experiment and data_set and data_item: with transaction.manager: dbsession.delete(data_item) dbsession.add(experiment) dbsession.add(data_set) raise HTTPFound( request.route_url('experiment.data.view', eid=experiment.id, did=data_set.id)) else: raise HTTPNotFound()
def delete_transition(request): dbsession = DBSession() experiment = dbsession.query(Experiment).filter(Experiment.id == request.matchdict['eid']).first() if experiment: page = dbsession.query(Page).filter(and_(Page.id == request.matchdict['pid'], Page.experiment == experiment)).first() else: page = None if page: transition = dbsession.query(Transition).filter(and_(Transition.id == request.matchdict['tid'], Transition.source == page)).first() else: transition = None if experiment and page and transition: try: with transaction.manager: dbsession.delete(transition) dbsession.add(experiment) dbsession.add(page) raise HTTPFound(request.route_url('experiment.page.transition', eid=experiment.id, pid=page.id)) except formencode.Invalid: raise HTTPFound(request.route_url('experiment.page.transition', eid=experiment.id, pid=page.id)) else: raise HTTPNotFound()
def data_delete(request): mode = 'latinsquare' if 'latinsquare' in request.matched_route.name else 'dataset' dbsession = DBSession() experiment = dbsession.query(Experiment).filter( Experiment.id == request.matchdict['eid']).first() data_set = dbsession.query(DataSet).filter( and_(DataSet.id == request.matchdict['did'], DataSet.experiment_id == request.matchdict['eid'], DataSet.type == mode)).first() if experiment and data_set: try: CSRFSchema().to_python(request.params, State(request=request)) with transaction.manager: dbsession.delete(data_set) dbsession.add(experiment) raise HTTPFound( request.route_url('experiment.%s' % mode, eid=experiment.id)) except formencode.Invalid: raise HTTPFound( request.route_url('experiment.%s.view' % mode, eid=experiment.id, did=data_set.id)) else: raise HTTPNotFound()
def reset_password(request): """Handles the "user.forgotten_password" URL, showing the form where the user can provide their e-mail address. If token is valid, calls the "user.password_reset_complete" callback with the current request and the :class:`~pywebtools.pyramid.auth.models.User`. Uses either the ``return_to`` parameter in the request to redirect on success or the "user.login" redirection route, with parameter replacement "{uid}" will be replaced with the logged in user's identifier. If overriding the URL, the URL must only have a ``{token}`` parameter. """ dbsession = DBSession() token = dbsession.query(TimeToken).filter( and_(TimeToken.action == 'reset_password', TimeToken.token == request.matchdict['token'], TimeToken.timeout >= datetime.now())).first() if token: if request.method == 'POST': try: params = ResetPasswordSchema().to_python( request.params, State(request=request)) user = token.user with transaction.manager: dbsession.add(user) user.new_password(params['password']) user.login_limit = 0 dbsession.delete(token) dbsession.add(user) request.current_user = user request.current_user.logged_in = True request.session['uid'] = user.id request.session.new_csrf_token() if 'user.password_reset_complete' in active_callbacks: active_callbacks['user.password_reset_complete'](request, user) redirect(request, 'user.reset_password', uid=request.current_user.id) except Invalid as e: return { 'errors': e.error_dict, 'values': request.params, 'allow_reset': True, 'crumbs': [{ 'title': 'Login', 'url': request.route_url('user.login') }, { 'title': 'Reset Password', 'url': request.route_url('user.reset_password', token=request.matchdict['token']), 'current': True }] } else: return { 'allow_reset': True, 'crumbs': [{ 'title': 'Login', 'url': request.route_url('user.login') }, { 'title': 'Reset Password', 'url': request.route_url('user.reset_password', token=request.matchdict['token']), 'current': True }] } else: return { 'allow_reset': False, 'crumbs': [{ 'title': 'Login', 'url': request.route_url('user.login') }, { 'title': 'Reset Password', 'url': request.route_url('user.reset_password', token=request.matchdict['token']), 'current': True }] }
def confirm(request): """Handles the "users.confirm" URL, validating that the user with the ``{token}`` has access to the e-mail address they provided. On a successful confirmation, calls the "user.validated" callback with three parameters: the current request object, the new :class:`~pywebtools.pyramid.auth.models.User`, and the validation :class:`~pywebtools.pyramid.auth.models.TimeToken`. If overriding the URL, the URL must only have a ``{token}`` parameter. """ dbsession = DBSession() token = dbsession.query(TimeToken).filter( and_(TimeToken.action == 'validate_account', TimeToken.token == request.matchdict['token'], TimeToken.timeout >= datetime.now())).first() if token: user = token.user with transaction.manager: dbsession.delete(token) dbsession.add(user) user.status = 'active' token = TimeToken(user.id, 'reset_password', datetime.now() + timedelta(seconds=1200)) dbsession.add(token) dbsession.add(user) dbsession.add(token) if 'user.validated' in active_callbacks: active_callbacks['user.validated'](request, user, token) return { 'status': 'success', 'crumbs': [{ 'title': 'Login', 'url': request.route_url('user.login') }, { 'title': 'Register', 'url': request.route_url('user.register') }, { 'title': 'Confirmation', 'url': request.route_url('user.confirm', token=request.matchdict['token']) }] } else: return { 'status': 'fail', 'crumbs': [{ 'title': 'Login', 'url': request.route_url('user.login') }, { 'title': 'Register', 'url': request.route_url('user.register') }, { 'title': 'Confirmation', 'url': request.route_url('user.confirm', token=request.matchdict['token']) }] }
def status(request): dbsession = DBSession() experiment = dbsession.query(Experiment).filter( Experiment.id == request.matchdict['eid']).first() if experiment: if request.method == 'POST': try: params = StatusSchema().to_python(request.params, State(request=request)) with transaction.manager: dbsession.add(experiment) if experiment.status == 'develop' and params[ 'status'] == 'live': for participant in dbsession.query(Participant).\ filter(Participant.experiment_id == experiment.id): dbsession.delete(participant) experiment.status = params['status'] dbsession.add(experiment) if experiment.status == 'completed': raise HTTPFound( request.route_url('experiment.results', eid=experiment.id)) else: raise HTTPFound( request.route_url('experiment.view', eid=experiment.id)) except formencode.Invalid as e: return { 'experiment': experiment, 'crumbs': [{ 'title': 'Experiments', 'url': request.route_url('dashboard') }, { 'title': experiment.title, 'url': request.route_url('experiment.view', eid=experiment.id) }, { 'title': 'Status', 'url': request.route_url('experiment.status', eid=experiment.id) }], 'errors': e.error_dict, 'values': request.params } return { 'experiment': experiment, 'crumbs': [{ 'title': 'Experiments', 'url': request.route_url('dashboard') }, { 'title': experiment.title, 'url': request.route_url('experiment.view', eid=experiment.id) }, { 'title': 'Status', 'url': request.route_url('experiment.status', eid=experiment.id) }] } else: raise HTTPNotFound()
def actions_delete(request): dbsession = DBSession() experiment = dbsession.query(Experiment).filter( Experiment.id == request.matchdict['eid']).first() if experiment: if request.method == 'POST': try: DeleteSchema().to_python(request.params, State(request=request)) with transaction.manager: dbsession.delete(experiment) raise HTTPFound(request.route_url('dashboard')) except formencode.Invalid as e: return { 'experiment': experiment, 'crumbs': [{ 'title': 'Experiments', 'url': request.route_url('dashboard') }, { 'title': experiment.title, 'url': request.route_url('experiment.view', eid=experiment.id) }, { 'title': 'Actions', 'url': request.route_url('experiment.actions', eid=experiment.id) }, { 'title': 'Delete', 'url': request.route_url('experiment.actions.delete', eid=experiment.id) }], 'errors': e.error_dict, 'values': request.params } return { 'experiment': experiment, 'crumbs': [{ 'title': 'Experiments', 'url': request.route_url('dashboard') }, { 'title': experiment.title, 'url': request.route_url('experiment.view', eid=experiment.id) }, { 'title': 'Actions', 'url': request.route_url('experiment.actions', eid=experiment.id) }, { 'title': 'Delete', 'url': request.route_url('experiment.actions.delete', eid=experiment.id) }] } else: raise HTTPNotFound()
def update(request): """Handles the ``parts/{pid}/users`` URL, applying the changes select when the user views :func:`~wte.views.user_role.action`. Requires that the user has "users" rights on the :class:`~wte.models.Part`. """ dbsession = DBSession() dbsession.add(request.current_user) part = dbsession.query(Part).filter(Part.id == request.matchdict['pid']).first() if part: if part.allow('users', request.current_user): query_params = [] for param in ['q', 'role', 'start']: if param in request.params and request.params[param]: query_params.append((param, request.params[param])) try: crumbs = create_part_crumbs(request, part, [{'title': 'Users', 'url': request.route_url('part.users', pid=part.id)}, {'title': 'Update', 'url': request.current_route_url()}]) users = [] params = {} params = ActionSchema().to_python(request.params, State(request=request)) users = dbsession.query(UserPartRole).filter(UserPartRole.id.in_(params['role_id'])).all() if params['action'] == 'change_role': params = ChangeRoleSchema().to_python(request.params, State(request=request)) with transaction.manager: for role in users: dbsession.add(role) role.role = params['role'] raise HTTPSeeOther(request.route_url('part.users', pid=request.matchdict['pid'], _query=query_params)) elif params['action'] == 'remove': schema = CSRFSchema() schema.allow_extra_fields = True schema.to_python(request.params, State(request=request)) with transaction.manager: dbsession.add(part) parts = get_all_parts(part) for role in users: dbsession.add(role) for child_part in parts: progress = dbsession.query(UserPartProgress).\ filter(and_(UserPartProgress.part_id == child_part.id, UserPartProgress.user_id == role.user.id)).first() if progress: dbsession.delete(progress) dbsession.delete(role) raise HTTPSeeOther(request.route_url('part.users', pid=request.matchdict['pid'], _query=query_params)) elif params['action'] == 'block': schema = CSRFSchema() schema.allow_extra_fields = True schema.to_python(request.params, State(request=request)) with transaction.manager: for role in users: dbsession.add(role) role.role = 'block' raise HTTPSeeOther(request.route_url('part.users', pid=request.matchdict['pid'], _query=query_params)) except formencode.api.Invalid as e: return {'errors': e.error_dict, 'values': request.params, 'part': part, 'params': params, 'query_params': query_params, 'users': users, 'crumbs': crumbs, 'help': ['user', 'teacher', 'module', 'users.html']} return {'part': part, 'params': params, 'query_params': query_params, 'users': users, 'crumbs': crumbs, 'help': ['user', 'teacher', 'module', 'users.html']} else: unauthorised_redirect(request) else: raise HTTPNotFound()