Coverage for webapp/authentication.py : 97%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import os
3from urllib.parse import urlparse
5from pymacaroons import Macaroon
6from webapp.api import sso
8LOGIN_URL = os.getenv("LOGIN_URL", "https://login.ubuntu.com")
10PERMISSIONS = [
11 "edit_account",
12 "package_access",
13 "package_manage",
14 "package_metrics",
15 "package_register",
16 "package_release",
17 "package_update",
18 "package_upload_request",
19 "store_admin",
20]
23def get_authorization_header(root, discharge):
24 """
25 Bind root and discharge macaroons and return the authorization header.
26 """
28 bound = Macaroon.deserialize(root).prepare_for_request(
29 Macaroon.deserialize(discharge)
30 )
32 return "macaroon root={}, discharge={}".format(root, bound.serialize())
35def get_publishergw_authorization_header(developer_token):
36 return {"Authorization ": f"Macaroon {developer_token}"}
39def is_authenticated(session):
40 """
41 Checks if the user is authenticated from the session
42 Returns True if the user is authenticated
43 """
44 return (
45 "publisher" in session
46 and "macaroon_discharge" in session
47 and "macaroon_root" in session
48 ) or ("publisher" in session and "macaroons" in session)
51def empty_session(session):
52 """
53 Empty the session, used to logout.
54 """
55 session.pop("macaroons", None)
56 session.pop("macaroon_root", None)
57 session.pop("macaroon_discharge", None)
58 session.pop("publisher", None)
59 session.pop("github_auth_secret", None)
62def get_caveat_id(root):
63 """
64 Returns the caveat_id generated by the SSO
65 """
66 location = urlparse(LOGIN_URL).hostname
67 (caveat,) = [
68 c
69 for c in Macaroon.deserialize(root).third_party_caveats()
70 if c.location == location
71 ]
73 return caveat.caveat_id
76def request_macaroon():
77 """
78 Request a macaroon from dashboard.
79 Returns the macaroon.
80 """
81 response = sso.post_macaroon({"permissions": PERMISSIONS})
83 return response["macaroon"]
86def get_refreshed_discharge(discharge):
87 """
88 Get a refresh macaroon if the macaroon is not valid anymore.
89 Returns the new discharge macaroon.
90 """
91 response = sso.get_refreshed_discharge({"discharge_macaroon": discharge})
93 return response["discharge_macaroon"]
96def is_macaroon_expired(headers):
97 """
98 Returns True if the macaroon needs to be refreshed from
99 the header response.
100 """
101 return headers.get("WWW-Authenticate") == ("Macaroon needs_refresh=1")