routes.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. from flask import request, jsonify, url_for, redirect, current_app
  2. from flask_login import login_user, logout_user, login_required, current_user
  3. from app import db, oauth
  4. from app.models import User
  5. from . import auth
  6. @auth.route('/register', methods=['POST'])
  7. def register():
  8. data = request.get_json()
  9. if User.query.filter_by(email=data['email']).first():
  10. return jsonify({'error': 'Email already registered'}), 400
  11. if User.query.filter_by(username=data['username']).first():
  12. return jsonify({'error': 'Username already taken'}), 400
  13. if len(data.get('password', '')) < 9:
  14. return jsonify({'error': 'Password must be at least 9 characters long'}), 400
  15. user = User(username=data['username'], email=data['email'])
  16. user.set_password(data['password'])
  17. db.session.add(user)
  18. db.session.commit()
  19. return jsonify({'message': 'User registered successfully'}), 201
  20. @auth.route('/login', methods=['POST'])
  21. def login():
  22. data = request.get_json()
  23. user = User.query.filter_by(email=data['email']).first()
  24. if user is None or not user.check_password(data['password']):
  25. return jsonify({'error': 'Invalid email or password'}), 401
  26. login_user(user)
  27. return jsonify({'message': 'Logged in successfully', 'user': {'username': user.username, 'email': user.email, 'is_admin': user.is_admin}})
  28. @auth.route('/logout', methods=['POST'])
  29. @login_required
  30. def logout():
  31. logout_user()
  32. return jsonify({'message': 'Logged out successfully'})
  33. @auth.route('/me', methods=['GET'])
  34. @login_required
  35. def get_current_user():
  36. return jsonify({
  37. 'id': current_user.id,
  38. 'username': current_user.username,
  39. 'email': current_user.email,
  40. 'is_admin': current_user.is_admin,
  41. 'profile_pic_url': current_user.profile_pic_url,
  42. 'is_probation': current_user.is_probation
  43. })
  44. # Google OAuth
  45. @auth.route('/google')
  46. def google_login():
  47. google = oauth.register(
  48. name='google',
  49. client_id=current_app.config.get('GOOGLE_CLIENT_ID'),
  50. client_secret=current_app.config.get('GOOGLE_CLIENT_SECRET'),
  51. access_token_url='https://accounts.google.com/o/oauth2/token',
  52. access_token_params=None,
  53. authorize_url='https://accounts.google.com/o/oauth2/auth',
  54. authorize_params=None,
  55. api_base_url='https://www.googleapis.com/oauth2/v1/',
  56. client_kwargs={'scope': 'openid email profile'},
  57. )
  58. redirect_uri = url_for('auth.google_authorize', _external=True)
  59. return google.authorize_redirect(redirect_uri)
  60. @auth.route('/google/authorize')
  61. def google_authorize():
  62. google = oauth.create_client('google')
  63. token = google.authorize_access_token()
  64. resp = google.get('userinfo')
  65. user_info = resp.json()
  66. user = User.query.filter_by(email=user_info['email']).first()
  67. if not user:
  68. # Create new user
  69. # Note: Username might need to be handled if it conflicts or just use email prefix
  70. base_username = user_info['email'].split('@')[0]
  71. username = base_username
  72. counter = 1
  73. while User.query.filter_by(username=username).first():
  74. username = f"{base_username}{counter}"
  75. counter += 1
  76. user = User(
  77. email=user_info['email'],
  78. username=username,
  79. google_id=user_info['id'],
  80. profile_pic_url=user_info.get('picture')
  81. )
  82. db.session.add(user)
  83. db.session.commit()
  84. login_user(user)
  85. # Redirect to frontend
  86. return redirect('http://localhost:3000/') # Should be configurable