Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kenkendk committed Jul 9, 2015
1 parent 8e9d58e commit 891d357
Show file tree
Hide file tree
Showing 14 changed files with 1,228 additions and 0 deletions.
27 changes: 27 additions & 0 deletions app.yaml
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
37 changes: 37 additions & 0 deletions config-template.py
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'
4 changes: 4 additions & 0 deletions cron.yaml
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
66 changes: 66 additions & 0 deletions dbmodel.py
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 added favicon.ico
Binary file not shown.
87 changes: 87 additions & 0 deletions index.html
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>
11 changes: 11 additions & 0 deletions index.yaml
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.
69 changes: 69 additions & 0 deletions logged-in.html
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>
Loading

0 comments on commit 891d357

Please sign in to comment.