def delete(): if request.method == 'POST': dos = arrow.get(g.user.created).humanize() calendars = len([c for c in Calendar.query(ancestor=g.user.key)]) todos = len([e for e in Event.query(ancestor=g.user.key)]) subject = '%s %s closed their account' % (g.user.first_name, g.user.last_name) body = ''' %s (joined %s, made %d todos and had %d calendars) %s ''' % (g.user.email, dos, todos, calendars, request.form.get('feedback')) mail.send_mail(sender=EMAILS['alerts'], to=EMAILS['support'], subject=subject, body=body) calendars = Calendar.get_all(g.user.key) for calendar in calendars: for event in Event.get_all(calendar.key): event.key.delete() calendar.key.delete() User.unindex(g.user.key.urlsafe()) g.user.key.delete() session.pop('user', None) return redirect('/index.html') return render_template('delete.html')
def login(provider): if request.method == 'POST': session.permanent = 'remember' in request.form session.modified = True response = make_response() result = AUTHOMATIC.login(WerkzeugAdapter(request, response), provider) if result: if result.user: result.user.update() credentials = result.user.credentials.serialize() user = User.create_or_update(provider, result.user.id, result.user.email, result.user.first_name, result.user.last_name, credentials) session['user'] = user.key.urlsafe() # If they are on the freemium list hook them up. if (not user.is_premium) and (Freemium.get_by_email( result.user.email) is not None): user.is_premium = True user.put() flash( 'You\'ve been upgraded to a free premium account for one year!' ) return redirect('/todos') return render_template('login.html', result=result) return response
def current_user(request): """获取当前登录用户 Args: request: 请求对象 Returns: 如果已登录,返回当前登录用户对象,否则返回 None """ # 从 Cookie 中获取 session_id cookies = request.cookies logger(f'cookies: {cookies}') session_id = cookies.get('session_id') # 查找 Session 并验证其是否过期 session = Session.get(session_id) if not session: return None if session.is_expired(): session.delete() return None # 查找当前登录用户 user = User.get(session.user_id) if not user: return None return user
def login(provider): if request.method == 'POST': session.permanent = 'remember' in request.form session.modified = True response = make_response() result = AUTHOMATIC.login(WerkzeugAdapter(request, response), provider) if result: if result.user: result.user.update() credentials = result.user.credentials.serialize() user = User.create_or_update(provider, result.user.id, result.user.email, result.user.first_name, result.user.last_name, credentials) session['user'] = user.key.urlsafe() # If they are on the freemium list hook them up. if (not user.is_premium) and (Freemium.get_by_email(result.user.email) is not None): user.is_premium = True user.put() flash('You\'ve been upgraded to a free premium account for one year!') return redirect('/todos') return render_template('login.html', result=result) return response
def test_user(): """测试 User 模型类""" username = uuid.uuid4().hex raw_password = '******' password = User.generate_password(raw_password) u = User(username=username, password=password) u.save() us = User.all(sort=True) find_user = User.find_by(username=username, ensure_one=True) u.delete() assert u.username == username assert u.password == password assert u.validate_password(raw_password, u.password) is True assert u.id in [u.id for u in us] assert u.id == find_user.id
def restrict_to_admin_users(): g.user = None if 'user' in session: g.user = User.get_by_id(session['user']) if not g.user or not g.user.is_admin: session.pop('user', None) abort(403)
def manage_user(user_id): user = User.get_by_id(user_id) if user is None: User.unindex(user_id) flash('User deleted their account; cleaned up search index') return redirect('/admin/user/search') if request.method == 'POST': operation = request.form.get('operation') if operation == 'goodbye': app_user.send_goodbye(user) elif operation == 'sync': sync_time = datetime.utcnow() sync_utc = pytz.utc.localize(sync_time) client = make_client(user) sync_user(sync_time, user, client, debug=True) flash('Synced user') elif operation == 'upgrade': user.is_premium = True user.put() elif operation == 'downgrade': user.is_premium = False user.put() else: flash('Unknown operation') calendars = 0 todos = 0 completed = 0 for calendar in Calendar.get_all(user.key): calendars += 1 for event in Event.get_all(calendar.key): todos += 1 if event.done: completed += 1 extra = { 'calendars': calendars, 'todos': todos, 'completed': completed, 'created': arrow.get(user.created).humanize(), 'updated': arrow.get(user.updated).humanize(), } return render_template('admin-user-manage.html', manage_user=user, extra=extra)
def test_login(): """测试登录""" # 测试 GET 请求 request_message = 'GET /login HTTP/1.1\r\nHost: 127.0.0.1:8000\r\n\r\n' request = Request(request_message) route, method = routes.get(request.path) r = route(request) assert 'Login' in r # 测试 POST 请求 username = uuid.uuid4().hex raw_password = '******' password = User.generate_password(raw_password) u = User(username=username, password=password) u.save() request_message = f'POST /login HTTP/1.1\r\nHost: 127.0.0.1:8000\r\n\r\n' \ f'username={username}&password={raw_password}' request = Request(request_message) route, method = routes.get(request.path) r = route(request) u.delete() s = Session.get(r.cookies.get('session_id')) s.delete() assert b'302 FOUND' in bytes(r) assert b'/index' in bytes(r) assert b'session_id' in bytes(r) r = route(request) assert r.decode('utf-8') == '用户名或密码不正确'
def test_delete(): """测试删除 todo""" username = uuid.uuid4().hex raw_password = '******' password = User.generate_password(raw_password) u = User(username=username, password=password) u.save() s = Session(user_id=u.id, expire_in='2099-12-31 00:00:00') s.save() content = uuid.uuid4().hex t = Todo(user_id=u.id, content=content) t.save() request_message = f'POST /delete HTTP/1.1\r\nHost: 127.0.0.1:8000\r\n' \ f'Cookie: session_id={s.id}\r\n\r\nid={t.id}' request = Request(request_message) route, method = routes.get(request.path) r = route(request) t = Todo.find_by(user_id=u.id, content=content, ensure_one=True) u.delete() s.delete() assert b'302 FOUND' in bytes(r) assert b'/index' in bytes(r) assert t is None r = route(request) assert b'302 FOUND' in bytes(r) assert b'/login' in bytes(r)
def login(request): """登录 Args: request: 请求对象 Returns: GET 请求: 返回登录页面 POST 请求: 登录成功将重定向到首页 登录失败返回失败原因提示短语 """ # 如果用户已经登录,直接重定向到首页 if current_user(request): return redirect('/index') if request.method == 'POST': message = '用户名或密码不正确'.encode('utf-8') # 获取表单中的用户名和密码 form = request.form logger(f'form: {form}') username = form.get('username') raw_password = form.get('password') # 验证用户名和密码是否正确 if not username or not raw_password: return message user = User.find_by(username=username, ensure_one=True) if not user: return message password = user.password if not User.validate_password(raw_password, password): return message # 创建 Session 并将 session_id 写入 Cookie 实现登录 session = Session(user_id=user.id) session.save() cookies = { 'session_id': session.id, } return redirect('/index', cookies=cookies) return render_template('auth/login.html')
def restrict_to_signed_in_users(): g.user = None if 'user' in session: g.user = User.get_by_id(session['user']) if not g.user: session.pop('user', None) return redirect('/') g.client = make_client(g.user)
def force_job(): task_url = '/api/v1/queues/sync/user' for key in User.get_all_keys(): params = { 'user_id': key.urlsafe(), 'force': 1, } taskqueue.add(url=task_url, params=params) return make_response()
def register(request): """注册 Args: request: 请求对象 Returns: GET 请求: 返回注册页面 POST 请求: 注册成功将重定向到登录页 注册失败返回失败原因提示短语 """ if request.method == 'POST': # 获取表单中的用户名和密码 form = request.form logger(f'form: {form}') username = form.get('username') raw_password = form.get('password') # 验证用户名和密码是否合法 if not username or not raw_password: return '无效的用户名或密码'.encode('utf-8') user = User.find_by(username=username, ensure_one=True) if user: return '用户名已存在'.encode('utf-8') # 对密码进行散列计算,创建并保存用户信息 password = User.generate_password(raw_password) user = User(username=username, password=password) user.save() # 注册成功后重定向到登录页面 return redirect('/login') return render_template('auth/register.html')
def test_register(): """测试注册""" # 测试 GET 请求 request_message = 'GET /register HTTP/1.1\r\nHost: 127.0.0.1:8000\r\n\r\n' request = Request(request_message) route, method = routes.get(request.path) r = route(request) assert 'Register' in r # 测试 POST 请求 username = uuid.uuid4().hex raw_password = '******' password = User.generate_password(raw_password) request_message = f'POST /register HTTP/1.1\r\nHost: 127.0.0.1:8000\r\n\r\n' \ f'username={username}&password={password}' request = Request(request_message) route, method = routes.get(request.path) r = route(request) u = User.find_by(username=username, ensure_one=True) u.delete() assert b'302 FOUND' in bytes(r) assert b'/login' in bytes(r)
def rollup_users(): rollup = defaultdict(lambda: defaultdict(int)) for user in User.get_all(): (year, week, day) = user.created.isocalendar() rollup[year][week] += 1 def gen(): for year in sorted(rollup): for week in sorted(rollup[year]): yield (year, week) cum = 0 for year, week in gen(): cum += rollup[year][week] Stat.create_or_update('user-count', year, week, cum)
def sync_job(): sync_time = datetime.utcnow() sync_utc = pytz.utc.localize(sync_time) user = User.get_by_id(request.form['user_id']) if 'force' in request.form: client = make_client(user) sync_user(sync_time, user, client) else: for db_calendar in Calendar.get_all(user.key): local_tz = safe_timezone(db_calendar.time_zone) sync_local = local_tz.normalize(sync_utc) if sync_local.hour == 0: client = make_client(user) sync_user(sync_time, user, client) break return make_response()
def search_user(): query = request.args.get('q', '') results = User.search(query) simplified = list() for result in results: entry = {'link': '/admin/user/manage/%s' % result.doc_id} for field in result.fields: if field.name == 'created': entry[field.name] = arrow.get(field.value).humanize() else: entry[field.name] = field.value simplified.append(entry) extra = { 'total': results.number_found, 'shown': len(results.results), } return render_template('admin-user-search.html', results=simplified, extra=extra)
def search_user(): query = request.args.get('q', '') results = User.search(query) simplified = list() for result in results: entry = { 'link': '/admin/user/manage/%s' % result.doc_id } for field in result.fields: if field.name == 'created': entry[field.name] = arrow.get(field.value).humanize() else: entry[field.name] = field.value simplified.append(entry) extra = { 'total': results.number_found, 'shown': len(results.results), } return render_template('admin-user-search.html', results=simplified, extra=extra)
def test_todo(): """测试 Todo 模型类""" username = uuid.uuid4().hex raw_password = '******' password = User.generate_password(raw_password) u = User(username=username, password=password) u.save() content = uuid.uuid4().hex t = Todo(user_id=u.id, content=content) t.save() ts = Todo.all() find_todo = Todo.get(t.id) u.delete() t.delete() assert t.user_id == u.id assert t.content == content assert t.id in [t.id for t in ts] assert t.id == find_todo.id
def test_session(): """测试 Session 模型类""" username = uuid.uuid4().hex raw_password = '******' password = User.generate_password(raw_password) u = User(username=username, password=password) u.save() expire_in = '2099-12-31 00:00:00' s = Session(user_id=u.id, expire_in=expire_in) s.save() ss = Session.all() find_sessions = Session.find_by(user_id=u.id, expire_in=expire_in) u.delete() s.delete() assert s.user_id == u.id assert s.expire_in == expire_in assert s.id in [s.id for s in ss] assert s.id == find_sessions[0].id assert len(find_sessions) == 1
def test_index(): """测试首页""" username = uuid.uuid4().hex raw_password = '******' password = User.generate_password(raw_password) u = User(username=username, password=password) u.save() s = Session(user_id=u.id, expire_in='2099-12-31 00:00:00') s.save() request_message = f'GET / HTTP/1.1\r\nHost: 127.0.0.1:8000\r\n' \ f'Cookie: session_id={s.id}\r\n\r\n' request = Request(request_message) route, method = routes.get(request.path) r = route(request) u.delete() s.delete() assert b'Todo List' in bytes(r, encoding='utf-8') assert b'/new' in bytes(r, encoding='utf-8') r = route(request) assert b'302 FOUND' in bytes(r) assert b'/login' in bytes(r)