This repository has been archived by the owner on Oct 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 26022c9
Showing
15 changed files
with
284 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
**/__pycache__ | ||
**/env_ccauth |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
__pycache__/ | ||
instance/secret.json | ||
env_* | ||
*.pyc | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
FROM python:alpine3.7 | ||
|
||
COPY . /app | ||
WORKDIR /app | ||
|
||
RUN apk add make | ||
|
||
RUN pip install -r requirements.txt | ||
|
||
EXPOSE 5000 | ||
CMD make prod |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# compsoc committee sso | ||
|
||
## what? | ||
|
||
This is a tool to allow compsoc committee members to sign into internal applications, using our existing google admin platform. | ||
|
||
## why? | ||
|
||
This lets us greatly reduce the overhead of launching new applications, as we can shift account management up to the long-suffering administrator. | ||
|
||
## how? | ||
|
||
This is just a demo application, intended as a starting off point for creating new applications. You'll need to create a project on (ideally CompSoc's) [GCP](https://console.cloud.google.com/), issue a client ID and secret for a web oauth application, and properly configure the callback urls. | ||
|
||
More verbosely: | ||
|
||
1) Log into [GCP](https://console.cloud.google.com), and create a new project by clicking th project header on the title bar and clicking "New Project." Ideally this should be created under the "comp-soc.com" domain. | ||
|
||
2) Once you've created the project, go to the sidebar > APIs & Services > Credentials. You'll need to add routes like so: | ||
|
||
 | ||
 | ||
|
||
3) You'll also need to enable access to the People API, which is used to retrieve a profile photo and other information. This can be done through the sidebar > APIs & Services > Library portal. | ||
|
||
Once you've done that, you'll need to create your json configuration file in `instance/secret.json`: | ||
|
||
```json | ||
{ | ||
"client_id": "YOUR_GOOGLE_CLIENT_ID", | ||
"client_secret": "YOUR_GOOGLE_CLIENT_SECRET", | ||
"app_secret_key": "SOME_RANDOM_STRING" | ||
} | ||
``` | ||
|
||
Then you should be good to go! Start the server with: | ||
|
||
``` | ||
$ make run | ||
``` | ||
|
||
# who? | ||
|
||
This was written in a fit of procrastination by [@pkage](//kage.dev). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
from flask import Flask, redirect, url_for, render_template | ||
from flask_dance.contrib.google import make_google_blueprint, google | ||
from oauthlib.oauth2.rfc6749.errors import TokenExpiredError | ||
import requests | ||
import json | ||
|
||
secrets = json.load(open('instance/secret.json', 'r')) | ||
|
||
app = Flask(__name__) | ||
app.secret_key = secrets['app_secret_key'] | ||
blueprint = make_google_blueprint( | ||
client_id=secrets['client_id'], | ||
client_secret=secrets['client_secret'], | ||
scope=['profile', 'email'] | ||
) | ||
app.register_blueprint(blueprint, url_prefix='/login') | ||
|
||
# magic happens here | ||
def email_valid(email): | ||
if email.endswith('@comp-soc.com') or email.endswith('@hacktheburgh.com') or email.endswith('@sigint.mx'): | ||
return True | ||
return False | ||
|
||
@app.route('/') | ||
def index(): | ||
if google.authorized: | ||
return redirect(url_for('profile')) | ||
return render_template('login.html') | ||
|
||
@app.route('/logout') | ||
def logout(): | ||
# retrieve token | ||
token = blueprint.token["access_token"] | ||
|
||
try: | ||
# revoke permission from Google's API | ||
resp = google.post( | ||
"https://accounts.google.com/o/oauth2/revoke", | ||
params={"token": token}, | ||
headers={"Content-Type": "application/x-www-form-urlencoded"} | ||
) | ||
assert resp.ok, resp.text | ||
except TokenExpiredError as e: | ||
print('token expired, ignoring') | ||
del blueprint.token # Delete OAuth token from storage | ||
return redirect(url_for('index')) | ||
|
||
@app.route('/profile') | ||
def profile(): | ||
if not google.authorized: | ||
return redirect(url_for('google.login')) | ||
# print(dir(google.get)) | ||
# print('google token: {}'.format(google.token[u'access_token'])) | ||
resp = requests.get( | ||
'https://people.googleapis.com/v1/people/me', | ||
params={ | ||
'personFields': 'names,emailAddresses,photos' | ||
}, | ||
headers={ | ||
'Authorization': 'Bearer {}'.format(google.token[u'access_token']) | ||
}) | ||
|
||
person_info = resp.json() | ||
|
||
profile = { | ||
'email': person_info[u'emailAddresses'][0][u'value'], | ||
'name': person_info[u'names'][0][u'displayName'], | ||
'image': person_info[u'photos'][0][u'url'].split('=')[0] # remove the 100px limit (ends with =s100) | ||
} | ||
|
||
return render_template('profile.html', | ||
profile=profile, | ||
valid=email_valid(profile['email']) | ||
) | ||
|
||
if __name__ == '__main__': | ||
app.run() |
Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
all: run | ||
|
||
|
||
run: | ||
OAUTHLIB_INSECURE_TRANSPORT=1 OAUTHLIB_RELAX_TOKEN_SCOPE=1 FLASK_DEBUG=1 flask run | ||
|
||
prod: | ||
FLASK_DEBUG=0 flask run |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
flask | ||
Flask-Dance | ||
requests |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
@import url('https://fonts.googleapis.com/css?family=Merriweather&display=swap'); | ||
|
||
body { | ||
margin: 0; | ||
background-color: #725752; | ||
|
||
font-family: 'Merriweather', serif; | ||
} | ||
|
||
main { | ||
min-height: 100vh; | ||
|
||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
} | ||
|
||
.row { | ||
display: flex; | ||
flex-direction: row; | ||
align-items: center; | ||
justify-content: center; | ||
} | ||
|
||
/* -- LOGIN PAGE -- */ | ||
|
||
.login__bg { | ||
} | ||
.login { | ||
color: white; | ||
opacity: 0.7; | ||
|
||
transition: opacity 0.25s cubic-bezier(0,0,0.3,1); | ||
text-decoration: none; | ||
} | ||
.login > span { | ||
margin-right: 0.5em; | ||
} | ||
.login:hover { | ||
opacity: 1; | ||
} | ||
|
||
/* -- PROFILE -- */ | ||
|
||
.profile__bg { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
|
||
|
||
color: white; | ||
min-height: 100vh; | ||
} | ||
|
||
.profile__block { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
} | ||
|
||
.profile__img { | ||
width: 300px; | ||
height: 300px; | ||
margin-bottom: 1em; | ||
} | ||
|
||
.profile__status { | ||
margin: 1em 0 1em 0; | ||
} | ||
|
||
.profile__status--invalid { | ||
color: #ee6c4d; | ||
} | ||
|
||
.profile__status--valid { | ||
color: #98af57; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<!DOCTYPE html> | ||
|
||
<html> | ||
<head> | ||
<title>compsoc sso demo</title> | ||
<link href="{{ url_for('static', filename='index.css') }}" rel="stylesheet" type="text/css"> | ||
<link href="{{ url_for('static', filename='compsoc-icon.png') }}" type="image/png" rel="icon"> | ||
|
||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous"> | ||
</head> | ||
<body> | ||
{% block content %}{% endblock %} | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block content %} | ||
|
||
<main class="login__bg"> | ||
<a href="{{ url_for('profile') }}" class="login row"> | ||
<span>login </span> | ||
<i class="fas fa-arrow-right"></i> | ||
</a> | ||
</main> | ||
|
||
{% endblock %} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{% extends "base.html" %} | ||
|
||
{% block content %} | ||
|
||
<div class="profile__bg {{ 'profile__bg--valid' if valid else ''}}"> | ||
<div class="profile__block"> | ||
<img src="{{ profile.image }}" alt="{{ profile.name }}" class="profile__img"> | ||
<div class="profile__name">{{ profile.name }}</div> | ||
<div class="profile__status {{ 'profile__status--valid' if valid else 'profile__status--invalid' }}"> | ||
{% if valid %} | ||
<i class="fas fa-check"></i> | ||
<span> verified compsoc committee member!</span> | ||
{% else %} | ||
<i class="fas fa-times"></i> | ||
<span> not a compsoc committee member.</span> | ||
{% endif %} | ||
</div> | ||
|
||
<a href="{{ url_for('logout') }}" class="login row"> | ||
<span>logout </span> | ||
<i class="fas fa-arrow-right"></i> | ||
</a> | ||
</div> | ||
</div> | ||
|
||
{% endblock %} |