Exemplo n.º 1
0
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()
Exemplo n.º 2
0
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()
Exemplo n.º 4
0
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()
Exemplo n.º 5
0
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()
Exemplo n.º 6
0
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()
Exemplo n.º 7
0
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()
Exemplo n.º 8
0
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()
Exemplo n.º 9
0
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
            }]
        }
Exemplo n.º 10
0
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'])
            }]
        }
Exemplo n.º 11
0
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()
Exemplo n.º 12
0
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()
Exemplo n.º 13
0
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()