-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.py
156 lines (121 loc) · 4.25 KB
/
index.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/python3
import os
import requests
import json
from dotenv import load_dotenv
from flask import Flask, make_response, request, redirect, session
from urllib.parse import parse_qs, urlencode, urlparse
from urllib import parse
# get environment variables
load_dotenv()
# Fill these out with the values you got from Github
github_client_id = os.environ.get('GITHUB_CLIENT_ID')
github_client_secret = os.environ.get('GITHUB_CLIENT_SECRET')
# This is the URL we'll send the user to first to get their authorization
authorize_url = 'https://github.com/login/oauth/authorize'
# This is the endpoint our server will request an access token from
token_url = 'https://github.com/login/oauth/access_token'
# This is the Github base URL we can use to make authenticated API requests
api_url_base = 'https://api.github.com/'
# The URL for this script, used as the redirect URL
base_url = 'http://localhost:8000/callback'
# Start up the Flask app
# Use flask session so we have a place to store things between redirects
app = Flask(__name__)
app.secret_key = os.getenv('SECRET_KEY')
# Start the login process by sending the user
# to Github's authorization page
@app.route('/login', methods=['GET'])
def login():
session.pop('access_token', None)
# Generate a random hash and store in the session
session['state'] = os.urandom(16).hex()
params = {
'response_type': 'code',
'client_id': github_client_id,
'redirect_uri': base_url,
'scope': 'user public_repo',
'state': session['state']
}
# Redirect the user to GitHub's authorization page
res = make_response(redirect(f'{authorize_url}?{urlencode(params)}'))
return res
@app.route('/logout', methods=['GET'])
def logout():
session.pop('access_token', None)
return redirect('/')
# When Github redirects the user back here,
# there will be a "code" and "state" parameter in the query string
@app.route('/callback', methods=['GET'])
def callback():
parsed = urlparse(request.url)
code = parse_qs(parsed.query)['code'][0]
state = parse_qs(parsed.query)['state'][0]
if (not state) or (state != session['state']):
return redirect('/?error=invalid_state')
token = requests.post(
token_url,
data={
'grant_type': 'authorization_code',
'client_id': github_client_id,
'client_secret': github_client_secret,
'redirect_url': base_url,
'code': code
},
headers={
'Accept': 'application/vnd.github.v3+json, application/json',
'User-Agent': 'https://example-app.com/'
}
).json()
session['access_token'] = token['access_token']
return redirect('/callback')
@app.route('/repos', methods=['GET'])
def repos():
url = api_url_base + 'user/repos?' + urlencode({
'sort': 'created',
'direction': 'desc'
})
repos = requests.get(
url,
headers={
'Content-Type': 'application/json',
'Authorization': f"Bearer {session['access_token']}"
}
).json()
return_str = '<ul>'
for repo in repos:
return_str += '<li><a href="' + repo['html_url'] + '">' + repo['name'] + '</a></li>'
return_str += '</ul>'
return return_str
# If there is an access token in the session
# the user is already logged in
@app.route('/', methods=['GET'])
def index():
if 'access_token' in session:
return '''<h3>Logged In</h3>
<p><a href="/repos">View Repos</a></p>
<p><a href="/logout">Log Out</a></p>'''
else:
return '''<h3>Not logged in</h3>
<p><a href="/login">Log In</a></p>'''
# def api_request(url:str, body:dict, post:bool=False):
# headers = {
# 'Accept: application/vnd.github.v3+json, application/json',
# 'User-Agent: https://example-app.com/'
# }
# if 'access_token' in session:
# headers['Authorization'] = f"Bearer {session['access_token']}"
# if post:
# response = requests.post(
# url,
# data=json.dumps(body),
# headers=headers
# )
# else:
# response = requests.get(
# url,
# headers=headers
# )
# return response.json()
if __name__=="__main__":
app.run(debug=True, port='8000')