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 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 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 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 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)