Skip to content

Commit

Permalink
Auth working; Fixes #1 for now
Browse files Browse the repository at this point in the history
  • Loading branch information
GladeDiviney committed Mar 28, 2016
1 parent 73f8d57 commit 6026178
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 34 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,22 @@ Combines data from ZenHub.io and GitHub to make some interesting charts.

1. Create a new application in Google App Engine
2. Copy the application ID into `.gaeid`
3. Create a `config.yaml` as below.
3. From the root folder run `dev/update`

### `config.yaml`

```
# Github application credentials
github:
id: <FROM GITHUB>
secret: <FROM GITHUB>
# URL of the appspot host
host: <YOUR APP NAME>.appspot.com
# An app-specific secret session key
webapp2_extras.sessions:
secret_key: <SOME LONG RANDOM THING>
```

17 changes: 7 additions & 10 deletions github.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import webapp2
import sys
import urllib, urlparse
from urllib2 import Request, urlopen, URLError, HTTPError
import webapp2, sys, urllib, urlparse, random
import base64, json, logging, datetime, time
from urllib2 import Request, urlopen, HTTPError
from google.appengine.ext import deferred
from google.appengine.ext import vendor
vendor.add('lib') # uritemplate is vendored
import uritemplate
import random
from model import Issue, Repo
from config import config
import zenhub

githubUrl = 'https://api.github.com'

Expand Down Expand Up @@ -92,13 +89,13 @@ def syncIssues(self, repoKey):
issue = Issue(repo = repo.key, number = number)
issue.github = self.issue(repo, number, issue.github)
issue.githubUpdate = updateTime
issue.zenhubUpdate = None # github update means zenhub update
issue.zenhubUpdate = None # mark for Zenhub update
logging.info("Upserting issue %s" % issue.number)
issue.upsert()

# After a github sync, start a zenhub sync
zenhub.syncIssues(repo.key)

#TODO: Go get zenhub updates (separately so it can be metered safely)?
#getZenhubIssues(repo.key, keysToRefresh)

def newIssueNumbers(self, repo, until):
"""Return issues that changed after issueTime, along with most recent update time"""
numbers = set()
Expand Down
4 changes: 2 additions & 2 deletions html/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
{% if user %}
<p>Welcome {{ user.name }} (<a href="/logout">Logout</a>)</p>
{% else %}
<form method="get">
<div>Github Personal Access Token: <input type="text" name="paToken" placeholder="github token"></div>
<form action="/login" method="get">
<!--<div>Github Personal Access Token: <input type="text" name="paToken" placeholder="github token"></div>-->
<div><input type="submit" value="Login"></div>
</form>
{% endif %}
Expand Down
63 changes: 41 additions & 22 deletions zenchart.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/python
import os
import os, random
import webapp2, jinja2, logging
import urllib, cgi, json
import urllib, cgi, json, urllib2, urlparse
from google.appengine.ext import ndb
from google.appengine.api import taskqueue
import github
Expand Down Expand Up @@ -53,7 +53,9 @@ def session(self):

class MainPage(BaseHandler):
def get(self):
user = self.user()
user = None
if 'user' in self.session:
user = self.session['user']

# List repositories that we know about
if user:
Expand All @@ -79,9 +81,9 @@ def post(self):
repo.name = self.request.get('repo')
repo.auth = Auth(zenhubToken = self.request.get('zenhubToken'))
repo.data = Github(user).repo(repo.name)
logging.info("Adding repo %s" % repo)
repo.put()
logging.info("Putting repo %s" % repo)
# TODO: defer get all issues for this repo
deferred.defer(github.syncIssues, user, repo.key)
self.redirect(repo.url())

class RepoPage(BaseHandler):
Expand All @@ -92,10 +94,6 @@ def get(self, id):
logging.info("Deferring github repo issue sync")
deferred.defer(github.syncIssues, user, repo.key)
self.redirect(repo.url())
elif self.request.get('z'):
logging.info("Deferring zenhub repo issue sync")
deferred.defer(zenhub.syncIssues, repo.key)
self.redirect(repo.url())
elif self.request.get('f'):
deferred.defer(github.getAllIssues, user, repo.key)
self.redirect(repo.url())
Expand Down Expand Up @@ -134,8 +132,6 @@ def post(self):
repo.name = name
repo.auth = Auth()
repo.auth.zenhubToken = self.request.get('zenhubToken')
repo.auth.githubToken = self.request.get('githubToken')
repo.auth.githubUser = self.request.get('githubUser')
repo.put()
deferred.defer(github.getAllIssues, repo)
self.redirect(repo.url())
Expand Down Expand Up @@ -174,10 +170,20 @@ def post(self, id):
class LoginPage(BaseHandler):
def get(self):
self.session['return'] = self.request.get('r')
# TODO: If user is missing we should allow redirection back to the current route
url = github.authUrl(self.session)
logging.info('Redirecting to %s to get user info' % url)
self.redirect(url)

if self.request.get('paToken'):
user = session.user()
self.redirect('/')
else:
# Github login
state = '%030x' % random.randrange(16**30)
url = 'https://github.com/login/oauth/authorize?%s' % urllib.urlencode({
'client_id': config['github']['id'],
'scope': 'repo',
'state': state})
self.session['state'] = state
logging.info('Redirecting to %s to get user info' % url)
self.redirect(url)

class LogoutPage(BaseHandler):
def get(self):
Expand All @@ -186,16 +192,29 @@ def get(self):

class GithubAuthPage(BaseHandler):
def get(self):
# TODO: Verify the 'state'
code = self.request.GET['code']
state = self.request.GET['state']
github.getAccessToken(self.session, code, state)
if 'return' in self.session:
returnTo = self.session['return']
del session['return']
if state != self.session['state']:
self.response.set_status(403)
else:
returnTo = '/'
self.redirect(returnTo)
request = urllib2.Request('https://github.com/login/oauth/access_token', urllib.urlencode({
'client_id': config['github']['id'],
'client_secret': config['github']['secret'],
'code': code
}))
data = urlparse.parse_qs(urllib2.urlopen(request).read())
logging.info('result is %s' % data)
aToken = data['access_token'][0]
user = Github({'aToken': aToken}).user()
user['aToken'] = aToken
self.session['user'] = user
if 'return' in self.session and self.session['return']:
returnTo = self.session['return']
logging.info("Login complete for user %s, returning to %s" % (json.dumps(user), returnTo))
del self.session['return']
else:
returnTo = '/'
self.redirect(returnTo)

app = webapp2.WSGIApplication([
('/', MainPage),
Expand Down
2 changes: 2 additions & 0 deletions zenhub.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from urllib2 import Request, urlopen, HTTPError
import json, datetime, logging
from google.appengine.ext import deferred
from model import Repo

zenhubUrl = 'https://api.zenhub.io/p1'

Expand Down

0 comments on commit 6026178

Please sign in to comment.