forked from duplicati/oauth-handler
-
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
Showing
14 changed files
with
1,228 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,27 @@ | ||
application: appspot-oauth-handler | ||
version: 1 | ||
runtime: python27 | ||
api_version: 1 | ||
threadsafe: no | ||
|
||
handlers: | ||
- url: /favicon\.ico | ||
static_files: favicon.ico | ||
upload: favicon\.ico | ||
|
||
- url: /cleanup | ||
script: main.app | ||
login: admin | ||
|
||
- url: .* | ||
script: main.app | ||
|
||
libraries: | ||
- name: webapp2 | ||
version: latest | ||
- name: jinja2 | ||
version: latest | ||
- name: django | ||
version: latest | ||
- name: pycrypto | ||
version: latest |
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,37 @@ | ||
# Copy this file to "config.py" and edit it | ||
|
||
#TESTING = False | ||
|
||
# Change this to the domain of the service | ||
#APP_DOMAIN='change-me-in-config-py.appspot.com' | ||
|
||
# Short name of the service | ||
#APP_NAME = 'CHANGE-ME-IN-CONFIG.PY' | ||
|
||
# Name to display on front page | ||
#SERVICE_DISPLAYNAME = APP_NAME + ' OAuth Handler' | ||
|
||
# Callback URI for OAuth | ||
#OAUTH_CALLBACK_URI = 'https://' + APP_DOMAIN + '/logged-in' | ||
|
||
# Conditional setup example: | ||
#if TESTING: | ||
# OAUTH_CALLBACK_URI = 'http://localhost:12080/logged-in' | ||
|
||
|
||
######## SECRETS AREA ########## | ||
|
||
# Windows Live Secrets | ||
# https://account.live.com/developers/applications/index | ||
#WL_CLIENT_ID='XXXXXXXXXXXXXXXXXXXX' | ||
#WL_CLIENT_SECRET='XXXXXXXXXXXXXXXXXXXX' | ||
|
||
# Google Secrets | ||
# https://console.developers.google.com | ||
#GD_CLIENT_ID='XXXXXXXXXXXXXXXXXXXX' | ||
#GD_CLIENT_SECRET='XXXXXXXXXXXXXXXXXXXX' | ||
|
||
# HubiC secrets | ||
# https://hubic.com/home/browser/apps/ | ||
#HC_CLIENT_ID='XXXXXXXXXXXXXXXXXXXX' | ||
#HC_CLIENT_SECRET='XXXXXXXXXXXXXXXXXXXX' |
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,4 @@ | ||
cron: | ||
- description: weekly cleanout | ||
url: /cleanup | ||
schedule: every monday 00:00 |
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,66 @@ | ||
from google.appengine.ext import db | ||
import datetime | ||
|
||
class AuthToken(db.Model): | ||
"""Representation of a stored authid""" | ||
user_id = db.StringProperty(required=True) | ||
blob = db.TextProperty(required=True) | ||
expires = db.DateTimeProperty(required=True) | ||
service = db.StringProperty(required=True) | ||
|
||
class FetchToken(db.Model): | ||
"""Representation of a stored fetch token""" | ||
authid = db.StringProperty(required=False) | ||
token = db.StringProperty(required=True) | ||
expires = db.DateTimeProperty(required=True) | ||
fetched = db.BooleanProperty(required=True) | ||
|
||
class StateToken(db.Model): | ||
"""Representation of a stored state token""" | ||
service = db.StringProperty(required=True) | ||
expires = db.DateTimeProperty(required=True) | ||
fetchtoken = db.StringProperty(required=False) | ||
|
||
|
||
@db.transactional(xg=True) | ||
def create_fetch_token(fetchtoken): | ||
# A fetch token stays active for 30 minutes | ||
if fetchtoken != None and fetchtoken != '': | ||
e = FetchToken.get_by_key_name(fetchtoken) | ||
if e == None: | ||
FetchToken(key_name=fetchtoken, token=fetchtoken, fetched=False, expires=datetime.datetime.utcnow() + datetime.timedelta(minutes=5)).put() | ||
|
||
@db.transactional(xg=True) | ||
def update_fetch_token(fetchtoken, authid): | ||
if fetchtoken != None and fetchtoken != '': | ||
e = FetchToken.get_by_key_name(fetchtoken) | ||
if e != None: | ||
e.expires = datetime.datetime.utcnow() + datetime.timedelta(seconds=30) | ||
e.authid = authid | ||
e.fetched = False | ||
e.put() | ||
|
||
@db.transactional | ||
def insert_new_authtoken(keyid, user_id, blob, expires, service): | ||
entry = AuthToken.get_by_key_name(keyid) | ||
if entry == None: | ||
|
||
entry = AuthToken(key_name=keyid, user_id=user_id, blob=blob, expires=expires, service=service) | ||
entry.put() | ||
|
||
return entry | ||
else: | ||
return None | ||
|
||
@db.transactional(xg=True) | ||
def insert_new_statetoken(token, service, fetchtoken): | ||
entry = StateToken.get_by_key_name(token) | ||
if entry == None: | ||
|
||
entry = StateToken(key_name=token, service=service, fetchtoken=fetchtoken, expires=datetime.datetime.utcnow() + datetime.timedelta(minutes=5)) | ||
entry.put() | ||
|
||
return entry | ||
else: | ||
return None | ||
|
Binary file not shown.
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,87 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<title>{{longappname}}</title> | ||
|
||
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> | ||
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css"> | ||
|
||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> | ||
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> | ||
|
||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> | ||
<!--[if lt IE 9]> | ||
<script src="//oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> | ||
<script src="//oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> | ||
<![endif]--> | ||
</head> | ||
<body> | ||
<script type="text/javascript"> | ||
$(document).ready(function() { | ||
|
||
var data = [ | ||
{% for item in providers %} | ||
{ | ||
'display': '{{item.display}}', | ||
'id': '{{item.id}}' | ||
}, | ||
{% endfor %} | ||
|
||
null /*dummy*/ | ||
]; | ||
|
||
for (var n in data) | ||
{ | ||
if (n == null || data[n] == null) | ||
continue; | ||
|
||
var d = data[n]; | ||
if (d.id == '{{redir}}') { | ||
window.location.href = $('#start-btn-' + d.id).attr('href'); | ||
$('#normal-login').hide(); | ||
$('#fast-login').show(); | ||
$('#fast-login-text').text('Redirecting to ' + d.display + ' for login ...'); | ||
} | ||
} | ||
|
||
}); | ||
</script> | ||
|
||
<div class="well well-lg"> | ||
<div class="jumbotron"> | ||
<h1>{{longappname}}</h1> | ||
<div id="normal-login"> | ||
|
||
{% if providers.length != 1 %} | ||
<p>This service is intended for {{appname}} users that want to use one of the following OAuth enabled providers:</p> | ||
<p> | ||
{% for item in providers %} | ||
<a href="{{item.servicelink}}" target="_blank">{{item.display}}</a> | ||
{% endfor %} | ||
</p> | ||
<p> Click the button for the provider you wish to log in with:</p> | ||
{% endif %} | ||
|
||
<p> | ||
{% for item in providers %} | ||
<a id="start-btn-{{item.id}}" class="btn btn-primary btn-lg" role="button" href="{{item.authlink}}">{{item.display}} login</a> | ||
{% endfor %} | ||
</p> | ||
|
||
|
||
{% for item in providers %} | ||
{{item.notes|safe}} | ||
{% endfor %} | ||
|
||
<p style="font-size: small"><a href="/revoke">Click here if you need to revoke a previously established authid</a></p> | ||
</div> | ||
<div id="fast-login" style="display: none"> | ||
<p id="fast-login-text"></p> | ||
</div> | ||
</div> | ||
</div> | ||
</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,11 @@ | ||
indexes: | ||
|
||
# AUTOGENERATED | ||
|
||
# This index.yaml is automatically updated whenever the dev_appserver | ||
# detects that a new type of query is run. If you want to manage the | ||
# index.yaml file manually, remove the above marker line (the line | ||
# saying "# AUTOGENERATED"). If you want to manage some indexes | ||
# manually, move them above the marker line. The index.yaml file is | ||
# automatically uploaded to the admin console when you next deploy | ||
# your application using appcfg.py. |
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,69 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<title>{{longappname}}</title> | ||
|
||
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> | ||
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css"> | ||
|
||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> | ||
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> | ||
|
||
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> | ||
<!--[if lt IE 9]> | ||
<script src="//oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> | ||
<script src="//oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> | ||
<![endif]--> | ||
</head> | ||
<body> | ||
<script type="text/javascript"> | ||
$(document).ready(function() { | ||
var showDeauth = '{{deauthlink}}'; | ||
if (showDeauth == 'true') | ||
$('#deauth-gdrive').show(); | ||
|
||
var countDown = 30; | ||
var v = $('#auth-token').text(); | ||
|
||
if (v == null || v == '') | ||
return; | ||
|
||
var recheck = function() { | ||
countDown--; | ||
if (countDown > 0) { | ||
$.ajax({ | ||
url: '/token-state', | ||
dataType: 'json', | ||
data: {'token': v} | ||
}) | ||
.done(function(data) { | ||
if (data.success) { | ||
$('#auto-id').show(); | ||
} else { | ||
setTimeout(recheck, 1000); | ||
} | ||
}) | ||
.fail(function() { | ||
setTimeout(recheck, 1000); | ||
}); | ||
} | ||
}; | ||
|
||
setTimeout(recheck, 3000); | ||
}); | ||
</script> | ||
|
||
<div class="jumbotron"> | ||
<h1>{{appname}} for {{service}}</h1> | ||
<p>Use these credentials for {{appname}}:</p> | ||
|
||
<p><pre id="user-id">{{authid}}</pre></p> | ||
<p id="auto-id" style="display: none">The AuthID has been fetched, you can close this window now.</p> | ||
<p id="auth-token" style="display: none">{{fetchtoken}}</p> | ||
<p id="deauth-gdrive" style="display: none">Visit your <a href="https://security.google.com/settings/security/permissions">App Permissions</a> page to de-authorize {{appname}}</p> | ||
</div> | ||
</body> | ||
</html> |
Oops, something went wrong.