2
2
import argparse
3
3
import os
4
4
5
- from oauth2client import client , tools
6
- from oauth2client .file import Storage
5
+ from google .auth .transport .requests import Request # type: ignore[import-not-found]
6
+ from google .oauth2 .credentials import Credentials # type: ignore[import-not-found]
7
+ from google_auth_oauthlib .flow import InstalledAppFlow
8
+
9
+ parser = argparse .ArgumentParser (add_help = False )
10
+ parser .add_argument (
11
+ "--auth_host_name" , default = "localhost" , help = "Hostname when running a local web server."
12
+ )
13
+ parser .add_argument (
14
+ "--noauth_local_webserver" ,
15
+ action = "store_true" ,
16
+ default = False ,
17
+ help = "Do not run a local web server." ,
18
+ )
19
+ parser .add_argument (
20
+ "--auth_host_port" ,
21
+ default = [8080 , 8090 ],
22
+ type = int ,
23
+ nargs = "*" ,
24
+ help = "Port web server should listen on." ,
25
+ )
26
+ flags = parser .parse_args ()
7
27
8
- flags = argparse .ArgumentParser (parents = [tools .argparser ]).parse_args ()
9
28
10
29
# If modifying these scopes, delete your previously saved credentials
11
30
# at zulip/bots/gcal/
12
31
# NOTE: When adding more scopes, add them after the previous one in the same field, with a space
13
32
# seperating them.
14
- SCOPES = "https://www.googleapis.com/auth/calendar.readonly"
33
+ SCOPES = [ "https://www.googleapis.com/auth/calendar.readonly" ]
15
34
# This file contains the information that google uses to figure out which application is requesting
16
35
# this client's data.
17
36
CLIENT_SECRET_FILE = "client_secret.json" # noqa: S105
18
37
APPLICATION_NAME = "Zulip Calendar Bot"
19
38
HOME_DIR = os .path .expanduser ("~" )
20
39
21
40
22
- def get_credentials () -> client . Credentials :
41
+ def get_credentials () -> Credentials :
23
42
"""Gets valid user credentials from storage.
24
43
25
44
If nothing has been stored, or if the stored credentials are invalid,
@@ -28,19 +47,36 @@ def get_credentials() -> client.Credentials:
28
47
Returns:
29
48
Credentials, the obtained credential.
30
49
"""
31
-
50
+ credentials = None
32
51
credential_path = os .path .join (HOME_DIR , "google-credentials.json" )
33
-
34
- store = Storage (credential_path )
35
- credentials = store .get ()
36
- if not credentials or credentials .invalid :
37
- flow = client .flow_from_clientsecrets (os .path .join (HOME_DIR , CLIENT_SECRET_FILE ), SCOPES )
38
- flow .user_agent = APPLICATION_NAME
39
- # This attempts to open an authorization page in the default web browser, and asks the user
40
- # to grant the bot access to their data. If the user grants permission, the run_flow()
41
- # function returns new credentials.
42
- credentials = tools .run_flow (flow , store , flags )
52
+ if os .path .exists (credential_path ):
53
+ credentials = Credentials .from_authorized_user_file (credential_path , SCOPES )
54
+ if not credentials or not credentials .valid :
55
+ if credentials and credentials .expired and credentials .refresh_token :
56
+ credentials .refresh (Request ())
57
+ else :
58
+ flow = InstalledAppFlow .from_client_secrets_file (
59
+ os .path .join (HOME_DIR , CLIENT_SECRET_FILE ), SCOPES
60
+ )
61
+ if not flags .noauth_local_webserver :
62
+ credentials = flow .run_local_server (
63
+ host = flags .auth_host_name , port = flags .auth_host_port [0 ]
64
+ )
65
+ # This attempts to open an authorization page in the default web browser, and asks the user
66
+ # to grant the bot access to their data. If the user grants permission, the run_flow()
67
+ # function returns new credentials.
68
+ else :
69
+ auth_url , _ = flow .authorization_url (prompt = "consent" )
70
+ print (
71
+ "Proceed to the following link in your browser:" ,
72
+ auth_url ,
73
+ )
74
+ auth_code = input ("Enter the authorization code: " )
75
+ credentials = flow .fetch_token (code = auth_code )
76
+ with open (credential_path , "w" ) as token :
77
+ token .write (credentials .to_json ())
43
78
print ("Storing credentials to " + credential_path )
79
+ return credentials
44
80
45
81
46
82
get_credentials ()
0 commit comments