Skip to content

Commit c5c1bcc

Browse files
committedJul 17, 2015
Merge pull request jupyter#6 from Xarthisius/bbteams
Authenticate Bitbucket's users basing on team membership
2 parents 145e96b + ead94ef commit c5c1bcc

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed
 

‎oauthenticator.py

+37-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from jupyterhub.auth import Authenticator, LocalAuthenticator
2020
from jupyterhub.utils import url_path_join
2121

22-
from traitlets import Unicode
22+
from traitlets import Unicode, Set
2323

2424

2525
class GitHubMixin(OAuth2Mixin):
@@ -158,6 +158,10 @@ class BitbucketOAuthenticator(Authenticator):
158158
config=True)
159159
client_secret = Unicode(os.environ.get('BITBUCKET_CLIENT_SECRET', ''),
160160
config=True)
161+
team_whitelist = Set(
162+
config=True,
163+
help="Automatically whitelist members of selected teams",
164+
)
161165

162166
def login_url(self, base_url):
163167
return url_path_join(base_url, 'oauth_login')
@@ -216,9 +220,39 @@ def authenticate(self, handler):
216220
resp_json = json.loads(resp.body.decode('utf8', 'replace'))
217221

218222
username = resp_json["username"]
219-
if self.whitelist and username not in self.whitelist:
223+
whitelisted = yield self.check_whitelist(username, headers)
224+
if not whitelisted:
220225
username = None
221-
raise gen.Return(username)
226+
return username
227+
228+
def check_whitelist(self, username, headers):
229+
if self.team_whitelist:
230+
return self._check_group_whitelist(username, headers)
231+
else:
232+
return self._check_user_whitelist(username)
233+
234+
@gen.coroutine
235+
def _check_user_whitelist(self, user):
236+
return (not self.whitelist) or (user in self.whitelist)
237+
238+
@gen.coroutine
239+
def _check_group_whitelist(self, username, headers):
240+
http_client = AsyncHTTPClient()
241+
242+
# We verify the team membership by calling teams endpoint.
243+
# Re-use the headers, change the request.
244+
next_page = url_concat("https://api.bitbucket.org/2.0/teams",
245+
{'role': 'member'})
246+
user_teams = set()
247+
while next_page:
248+
req = HTTPRequest(next_page, method="GET", headers=headers)
249+
resp = yield http_client.fetch(req)
250+
resp_json = json.loads(resp.body.decode('utf8', 'replace'))
251+
next_page = resp_json.get('next', None)
252+
253+
user_teams |= \
254+
set([entry["username"] for entry in resp_json["values"]])
255+
return len(self.team_whitelist & user_teams) > 0
222256

223257

224258
class LocalGitHubOAuthenticator(LocalAuthenticator, GitHubOAuthenticator):

0 commit comments

Comments
 (0)
Please sign in to comment.