Coverage for webapp/login/oauth_views.py: 42%

31 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-28 22:05 +0000

1import os 

2 

3import flask 

4from webapp.decorators import login_required 

5from webapp.api.requests import Session 

6from urllib.parse import urlencode 

7from werkzeug.exceptions import BadRequest 

8 

9 

10oauth = flask.Blueprint( 

11 "oauth", __name__, template_folder="/templates", static_folder="/static" 

12) 

13 

14 

15@oauth.route("/github/auth", methods=["GET"]) 

16@login_required 

17def github_auth(): 

18 """ 

19 Redirect to authorize our Github application and request 

20 access to the user's data. 

21 """ 

22 redirect_path = flask.request.args.get("back") 

23 

24 if redirect_path and redirect_path.startswith("/"): 

25 flask.session["github_auth_redirect"] = redirect_path 

26 

27 params = { 

28 "client_id": os.getenv("GITHUB_CLIENT_ID"), 

29 "scope": "admin:repo_hook read:org", 

30 "state": flask.session["csrf_token"], 

31 } 

32 

33 return flask.redirect( 

34 f"https://github.com/login/oauth/authorize?{urlencode(params)}" 

35 ) 

36 

37 

38@oauth.route("/github/auth/verify", methods=["GET"]) 

39@login_required 

40def github_login_verify(): 

41 """ 

42 Handles response after the redirect to Github. This response determines 

43 if the user has allowed this application access. If we were then we send 

44 a POST request for the access_key used to authenticate requests to Github. 

45 """ 

46 url_to_redirect = flask.session.pop( 

47 "github_auth_redirect", flask.url_for("snapcraft.homepage") 

48 ) 

49 

50 state = flask.request.args.get("state") 

51 

52 # Avoid CSRF attacks 

53 if state != flask.session["csrf_token"]: 

54 flask.flash("Invalid request", "negative") 

55 return flask.redirect(url_to_redirect) 

56 

57 data = { 

58 "code": flask.request.args.get("code"), 

59 "client_id": os.getenv("GITHUB_CLIENT_ID"), 

60 "client_secret": os.getenv("GITHUB_CLIENT_SECRET"), 

61 } 

62 

63 session = Session() 

64 response = session.request( 

65 method="POST", 

66 url="https://github.com/login/oauth/access_token", 

67 json=data, 

68 headers={"Accept": "application/json"}, 

69 ) 

70 

71 data = response.json() 

72 

73 if "error" in data: 

74 raise BadRequest(data["error_description"], response=response) 

75 

76 flask.session["github_auth_secret"] = data["access_token"] 

77 

78 return flask.redirect(url_to_redirect)