def user_resetpass(): form = ResetPwdForm(request.form) if request.method == 'POST' and form.validate(): email = form.email.data if not email: raise ResponseError(400, 'Email required', 'Please provide the email address you use to log in.') try: user = ApdUser.get(ApdUser.email == email) except ApdUser.DoesNotExist: user = None if user: token = user.create_reset_token( app.config['SECRET'], app.config['RESET_TIMEOUT'], which='password' ) if not token: raise ResponseError() # email user return template('email_sent.html') return template('reset_password.html', dict(form=form))
def user_chemail(): form = ChangeEmailForm(request.form) if request.method == 'POST' and form.validate(): old = form.old_email.data new = form.new_email.data pwd = form.password.data if None in [old,new] or old == new: raise ResponseError() if old != g.user.email or not g.user.verify_pass(pwd): raise ResponseError(403, 'Wrong email or password', 'Please provide your original email and current password.') token = g.user.create_reset_token( app.config['SECRET'], app.config['RESET_TIMEOUT'], which='email', extra={'new_email':new} ) if not token: raise ResponseError() # email user g.user.inactivate() delattr(g, 'user') resp = template('email_sent.html') resp = set_auth_cookie(resp, 'null', current_date()) return resp return template('change_email.html', dict(form=form))
def admin_sessions(a=''): '''(ADMIN) List user sessions.''' session_rows = Session.select().join(ApdUser)\ .order_by(Session.start_time.desc())\ .limit(100) if a == 'active': session_rows = session_rows.where(Session.active == True) user = request.args.get('user') if user: session_rows = session_rows.where(Session.user == user) sessions = [] for s in session_rows: sessions.append(dict( user = s.user.get_key(), email = s.user.email, start_time = str(s.start_time), end_time = str(s.end_time), active = s.active, location = s.location )) return template('admin_sessions.html', dict(sessions=sessions))
def admin_single_user(user_id): try: user = ApdUser.get(ApdUser.keyfield() == user_id) except ApdUser.NotFound: raise ResponseError(404, 'No such user') if request.method == 'GET': # Get user info sub_res = {} for r in sub_resources: model = resources[r] rows = model\ .select(model.keyfield(), model.orderfield())\ .order_by(model.orderfield()) sub_res[r] = [] for row in rows: sub_res[r].append({ 'id' : row.get_id(), 'name' : row.get_name(), }) d = dict(user=user, sub=sub_res, sub_keys=sub_resources) return template('admin_single_user.html', d) elif request.method == 'PUT': # Update user dat = request.get_json(silent=True) if dat: action = dat['action'] if action == 'activate': user.activate() elif action == 'inactivate': user.inactivate() elif action == 'ban': user.ban() elif action == 'unban': user.unban() status = { 'active':user.active, 'banned':user.banned, 'banned_date':user.banned_date if user.banned_date else 'None' } return jsonify(success=True, status=status) else: raise ResponseError() elif request.method == 'DELETE': # Remove user pass
def apd_search(qq=None): query = qq or request.args.get('q') d = {} if query: qs = [s.lower() for s in query.strip().split()] results = {} for resource, model in resources.items(): if not hasattr(model, '_searchable'): continue idx = Subscription.available_items(g.user, resource) items = model.select() for fname in model._searchable: field = model._meta.fields[fname] for s in qs: items = items.orwhere(field.contains(s)) if items.count() == 0: continue results[resource] = [] for item in items: key = item.get_key() subbed = g.user.is_admin or \ Subscription.can_access(g.user, resource, idx) results[resource].append({ 'id': key, 'rel': resource + '/' + str(key), 'name': item.get_name(), 'href': url_for('apd_view', resource=resource, rid=key), 'subscribed': subbed }) d['query'] = query d['results'] = results return template('search.html', d)
def admin_users(): '''(ADMIN) List all users.''' create_form = CreateUserForm(request.form) # List users user_rows = ApdUser.select().order_by( ApdUser.admin.desc(), ApdUser.orderfield() ) users = [] for u in user_rows: users.append(dict( id = u.get_key(), email = u.email, active = u.active, banned = u.banned, admin = u.admin, wrong_logins = u.wrong_logins )) new_user = None if request.method == 'POST': # Create new user if create_form.validate(): email = create_form.new_email.data password = create_form.new_password.data new_user, created = ApdUser.get_or_create(email=email) if created and password: new_user.set_pass(password) if not created: create_form.new_email.errors.append('User already exists.') new_user = None return template( 'admin_users.html', dict(users=users, create_form=create_form, new_user=new_user) )
def user_chpass(): form = ChangePwdForm(request.form) if request.method == 'POST' and form.validate(): old = form.old_password.data new = form.new_password.data if None in [old,new] or old == new: raise ResponseError() if not g.user.verify_pass(old): raise ResponseError(403, 'Wrong password', 'Please provide your original password.') g.user.set_pass(new) g.user.expire_sessions() delattr(g, 'user') resp = redirect(url_for('user_login')) resp = set_auth_cookie(resp, 'null', current_date()) return resp return template('change_password.html', dict(form=form))
def user_login(): user = g.get('user', None) if user: if user.is_authenticated: return redirect(url_for('index')) form = LoginForm(request.form) if request.method == 'POST': if form.validate(): email = form.email.data password = form.password.data next = check_url(form.next.data) or url_for('index') user = ApdUser.verify_user(email, password, attempts=app.config['AUTH_ATTEMPTS']) if user: token, expires = user.create_session( app.config['SECRET'], app.config['AUTH_TIMEOUT'], location=request.remote_addr ) if token: resp = redirect(next) resp = set_auth_cookie(resp, token, expires) return resp else: form.email.errors.append('Could not log in.') else: form.email.errors.append('Could not log in.') else: form.email.errors.append('Missing information.') form.next.data = next_url() return template('login.html', dict(form=form))
def user_logout(): user = g.get('user', None) if request.method == 'GET': if user: if not user.is_authenticated: raise redirect(url_for('index')) else: return redirect(url_for('index')) return template('logout.html') elif request.method == 'POST': value = request.form.get('confirm') next = request.form.get('next') next = check_url(next) or url_for('index') if value == 'accept': g.user.expire_sessions() delattr(g, 'user') resp = redirect(url_for('index')) resp = set_auth_cookie(resp, 'null', current_date()) return resp else: return redirect(next)
def apd_list(resource, page=1): if resource not in resources: raise ResponseError(404, 'Unknown resource', 'Resource not found.') # Get the model that was requested model = resources[resource] items = model.select() # If user isn't admin, and the resource is subscribable, only get items that # user is subscribed to if g.user.is_admin == False and resource in sub_resources: if Subscription.can_access(g.user, resource, -1) == False: idx = Subscription.available_items(g.user, resource) if idx.count() == 0: raise ResponseError( 403, 'Not Subscribed: ' + plural_filter(resource).title(), 'You are not subscribed to any ' + plural_filter(resource) + '.') items = model.select().join( Subscription, on=(Subscription.resource_id == model.keyfield() )).where(model.keyfield() << idx) # Do initial character filtering startsw = request.args.get('sw') if startsw: if startsw.isalpha(): startsw = startsw[0] swu = startsw.upper() swl = startsw.lower() items = items.where(model.orderfield().regexp('^[{}{}]'.format( swu, swl))) elif startsw == '0': items = items.where(model.orderfield().regexp('^[0-9]')) # Further filtering based on query string and_filters = request.args.getlist('flt') + request.args.getlist('and_flt') or_filters = request.args.getlist('or_flt') items = select_filter(items, and_filters, or_filters) # Filtering inputs if hasattr(model, '_filter'): ff = filter_form(model, as_json=True) else: ff = None # Pagination try: per = int(request.args.get('per')) except (ValueError, TypeError) as e: per = app.config['PER_PAGE'] count = items.count() items = items.order_by(model.orderfield()).paginate(page, per) total_pages = int(ceil(count / per)) if page > 1 and page > total_pages: raise ResponseError(404, 'Page not found', 'No such page.') if items: all_args = {} for k, v in request.args.items(): if k not in ['resource', 'page']: all_args[k] = v next_page = url_for('apd_list', resource=resource, page=page + 1, **all_args) prev_page = url_for('apd_list', resource=resource, page=max(1, page - 1), **all_args) itemlist = [] for item in items: key = item.get_key() name = item.get_name() href = url_for('apd_view', resource=resource, rid=key) if 'page' in request.args: href = url_for('apd_view', resource=resource, rid=key, page=page) if 'per' in request.args: href = url_for('apd_view', resource=resource, rid=key, page=page, per=per) itemlist.append({ 'id': key, 'rel': resource + '/' + str(key), 'name': name, 'href': href }) return template( 'base_list.html', dict(items=itemlist, count=count, resource=resource, href=url_for('apd_list', resource=resource, page=page, **all_args), page=page, prev=prev_page, next=next_page, total_pages=total_pages, per=per, start=(page - 1) * per + 1, end=min(count, page * per), filter_form=ff)) else: raise ResponseError()
def apd_view(resource, rid): if resource not in resources: raise ResponseError(404, 'Unknown resource', 'Resource not found.') if g.user.is_admin == False and resource in sub_resources: if Subscription.can_access(g.user, resource, rid) == False: raise ResponseError(403, 'Not Subscribed', 'You cannot access this ' + resource + '.') model = resources[resource] try: item = model.get(model.keyfield() == rid) except model.DoesNotExist: raise ResponseError(403, 'Unknown resource', 'Resource not found.') obj = {} links = {} for prop, field in model._meta.fields.items(): if isinstance(field, ForeignKeyField): rel_resource = field.rel_model.modelname() rel_item = getattr(item, prop) if rel_item is None: continue text = rel_item.get_name() key = rel_item.get_key() links[prop] = url_for('apd_view', resource=rel_resource, rid=key) obj[prop] = text else: obj[prop] = getattr(item, prop) backrefs = {} for relname, fk in model._meta.reverse_rel.items(): if g.get('fmt_json'): flt_d = dict(field=fk.name, sep=app.config['FLT_SEP'], id=item.id) flt = '{field}{sep}eq{sep}{id}'.format(**flt_d) backrefs[relname] = url_for('apd_list', resource=fk.model_class.modelname(), flt=flt) else: br = getattr(item, relname) backrefs[relname] = br.order_by(br.model_class.orderfield()) obj['key'] = item.get_key() obj['href'] = url_for('apd_view', resource=resource, rid=rid) obj['_links'] = links obj['_backrefs'] = backrefs if 'name' not in obj: obj['name'] = item.get_name() resource_href = request.referrer # For JSON and template d = dict(resource=model.modeltitle(), resource_href=resource_href, item=obj) # For use in templates g.item = item return template(resource + '.html', d)
def admin(): return template('admin.html')
def index(): return template('index.html')
def handle_response_error(error): return template('error.html', {'error':error.to_dict()}, code=error.code)