You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by jo...@apache.org on 2013/11/15 16:43:05 UTC
[40/50] git commit: [#6656] ticket:437 GitHub OAuth flow
[#6656] ticket:437 GitHub OAuth flow
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/d1f23ad8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/d1f23ad8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/d1f23ad8
Branch: refs/heads/cj/6777
Commit: d1f23ad8cb3605cba94e59ad5ca6bf74d7b2fa04
Parents: 3c07c83
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Oct 25 17:24:37 2013 +0300
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Wed Nov 13 20:43:46 2013 +0000
----------------------------------------------------------------------
Allura/development.ini | 4 ++
.../forgeimporters/github/__init__.py | 41 ++++++++++++++++++++
ForgeImporters/forgeimporters/github/project.py | 5 ++-
requirements-common.txt | 1 +
4 files changed, 50 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d1f23ad8/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 2c701cb..848955a 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -157,6 +157,10 @@ bulk_export_download_instructions = Sample instructions for {project}
importer_upload_path = /tmp/importer_upload/{nbhd}/{project}
+# GitHub importer keys
+# github_importer.client_id =
+# github_importer.client_secret =
+
# space-separated list of tool names that are valid options
# for project admins to set for their 'support_page' field
# this field is not used by default in Allura, so this option
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d1f23ad8/ForgeImporters/forgeimporters/github/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/github/__init__.py b/ForgeImporters/forgeimporters/github/__init__.py
index 951d670..a92f4a1 100644
--- a/ForgeImporters/forgeimporters/github/__init__.py
+++ b/ForgeImporters/forgeimporters/github/__init__.py
@@ -22,6 +22,11 @@ import time
import urllib2
from datetime import datetime
+from tg import config, session, redirect, request, expose
+from tg.decorators import without_trailing_slash
+from pylons import tmpl_context as c
+from requests_oauthlib import OAuth2Session
+
from forgeimporters import base
log = logging.getLogger(__name__)
@@ -136,3 +141,39 @@ class GitHubProjectExtractor(base.ProjectExtractor):
def has_wiki(self):
return self.get_page('project_info').get('has_wiki')
+
+
+class GitHubOAuthMixin(object):
+ '''Support for github oauth web application flow.'''
+
+ def oauth_begin(self, controller_url):
+ '''controller_url is absolute url, refers the controller you mixed this class in'''
+ client_id = config.get('github_importer.client_id')
+ secret = config.get('github_importer.client_secret')
+ if not client_id or not secret:
+ return # GitHub app is not configured
+ if c.user.get_tool_data('GitHubProjectImport', 'token'):
+ return # token already exists, nothing to do
+ redirect_uri = controller_url.rstrip('/') + '/oauth_callback'
+ oauth = OAuth2Session(client_id, redirect_uri=redirect_uri)
+ auth_url, state = oauth.authorization_url('https://github.com/login/oauth/authorize')
+ session['github.oauth.state'] = state # Used in callback to prevent CSRF
+ session['github.oauth.redirect'] = controller_url
+ session.save()
+ redirect(auth_url)
+
+ @without_trailing_slash
+ @expose()
+ def oauth_callback(self, **kw):
+ client_id = config.get('github_importer.client_id')
+ secret = config.get('github_importer.client_secret')
+ if not client_id or not secret:
+ return # GitHub app is not configured
+ oauth = OAuth2Session(client_id, state=session.get('github.oauth.state'))
+ token = oauth.fetch_token(
+ 'https://github.com/login/oauth/access_token',
+ client_secret=secret,
+ authorization_response=request.url
+ )
+ c.user.set_tool_data('GitHubProjectImport', token=token['access_token'])
+ redirect(session.get('github.oauth.redirect', '/'))
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d1f23ad8/ForgeImporters/forgeimporters/github/project.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/github/project.py b/ForgeImporters/forgeimporters/github/project.py
index e04590a..29df780 100644
--- a/ForgeImporters/forgeimporters/github/project.py
+++ b/ForgeImporters/forgeimporters/github/project.py
@@ -23,9 +23,11 @@ from tg import expose, validate
from tg.decorators import with_trailing_slash
from allura.lib.decorators import require_post
+from allura.lib import helpers as h
from .. import base
from . import tasks
+from . import GitHubOAuthMixin
log = logging.getLogger(__name__)
@@ -37,7 +39,7 @@ class GitHubProjectForm(base.ProjectImportForm):
'invalid': 'Valid symbols are: letters, numbers, dashes, underscores and periods',
})
-class GitHubProjectImporter(base.ProjectImporter):
+class GitHubProjectImporter(base.ProjectImporter, GitHubOAuthMixin):
source = 'GitHub'
index_template = 'jinja:forgeimporters.github:templates/project.html'
@@ -51,6 +53,7 @@ class GitHubProjectImporter(base.ProjectImporter):
@with_trailing_slash
@expose(index_template)
def index(self, **kw):
+ self.oauth_begin(h.absurl('/p/import_project/github/'))
return super(self.__class__, self).index(**kw)
@require_post()
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d1f23ad8/requirements-common.txt
----------------------------------------------------------------------
diff --git a/requirements-common.txt b/requirements-common.txt
index 1b1d2f6..685f437 100644
--- a/requirements-common.txt
+++ b/requirements-common.txt
@@ -39,6 +39,7 @@ python-openid==2.2.5
python-oembed==0.2.1
pytidylib==0.2.1
requests==1.2.3
+requests-oauthlib==0.4.0
# for taskd proc name switching
setproctitle==1.1.7
# dep of pypeline