Skip to content
Snippets Groups Projects
Commit fa1f3b94 authored by Kevin S. Hahn's avatar Kevin S. Hahn Committed by Gunnar Schaefer
Browse files

integrate oauth2

parent 53d9d061
No related branches found
No related tags found
No related merge requests found
...@@ -44,10 +44,10 @@ def update(db, api_uri, site_id, privkey, internims_url): ...@@ -44,10 +44,10 @@ def update(db, api_uri, site_id, privkey, internims_url):
new_remotes = response['users'] new_remotes = response['users']
log.debug('users w/ remotes: ' + str(new_remotes)) log.debug('users w/ remotes: ' + str(new_remotes))
for user in response['users']: for user in response['users']:
db.users.update({'oa2_id': user}, {'$set': {'remotes': new_remotes.get(user, [])}}) db.users.update({'user_id': user}, {'$set': {'remotes': new_remotes.get(user, [])}})
# cannot use new_remotes.viewkeys(). leads to 'bson.errors.InvalidDocument: Cannot encode object: dict_keys([])' # cannot use new_remotes.viewkeys(). leads to 'bson.errors.InvalidDocument: Cannot encode object: dict_keys([])'
db.users.update({'remotes': {'$exists':True}, 'oa2_id': {'$nin': new_remotes.keys()}}, {'$unset': {'remotes': ''}}, multi=True) db.users.update({'remotes': {'$exists':True}, 'user_id': {'$nin': new_remotes.keys()}}, {'$unset': {'remotes': ''}}, multi=True)
else: else:
log.warning((r.status_code, r.reason)) log.warning((r.status_code, r.reason))
......
...@@ -43,7 +43,7 @@ class NIMSAPI(nimsapiutil.NIMSRequestHandler): ...@@ -43,7 +43,7 @@ class NIMSAPI(nimsapiutil.NIMSRequestHandler):
nimsapi/remotes | list of remote instances nimsapi/remotes | list of remote instances
[(nimsapi/log)] | list of uwsgi log messages [(nimsapi/log)] | list of uwsgi log messages
[(nimsapi/users)] | list of users [(nimsapi/users)] | list of users
(nimsapi/users/current) | details for currently logged in user nimsapi/users/current | details for currently logged in user
[(nimsapi/users/count)] | count of users [(nimsapi/users/count)] | count of users
[(nimsapi/users/listschema)] | schema for user list [(nimsapi/users/listschema)] | schema for user list
[(nimsapi/users/schema)] | schema for single user [(nimsapi/users/schema)] | schema for single user
...@@ -132,7 +132,7 @@ class NIMSAPI(nimsapiutil.NIMSRequestHandler): ...@@ -132,7 +132,7 @@ class NIMSAPI(nimsapiutil.NIMSRequestHandler):
def remotes(self): def remotes(self):
"""Return the list of remotes where user has membership""" """Return the list of remotes where user has membership"""
remotes = [remote['_id'] for remote in list(self.app.db.remotes.find({}, []))] remotes = [remote['_id'] for remote in list(self.app.db.remotes.find({}, []))]
self.response.write(json.dumps(remotes)) self.response.write(json.dumps(remotes, default=bson.json_util.default))
def log(self): def log(self):
"""Return logs""" """Return logs"""
...@@ -212,7 +212,8 @@ class Users(nimsapiutil.NIMSRequestHandler): ...@@ -212,7 +212,8 @@ class Users(nimsapiutil.NIMSRequestHandler):
def current(self): def current(self):
"""Return the current User.""" """Return the current User."""
self.response.write(json.dumps(self.user)) # FIXME: trim this down to not use the self.user object, and only send relevant info
self.response.write(json.dumps(self.user, default=bson.json_util.default))
def post(self): def post(self):
"""Create a new User""" """Create a new User"""
...@@ -272,12 +273,12 @@ class User(nimsapiutil.NIMSRequestHandler): ...@@ -272,12 +273,12 @@ class User(nimsapiutil.NIMSRequestHandler):
def get(self, uid): def get(self, uid):
"""Return User details.""" """Return User details."""
user = self.app.db.users.find_one({'oa2_id': uid}) user = self.app.db.users.find_one({'user_info': uid})
self.response.write(json.dumps(user, default=bson.json_util.default)) self.response.write(json.dumps(user, default=bson.json_util.default))
def put(self, uid): def put(self, uid):
"""Update an existing User.""" """Update an existing User."""
user = self.app.db.users.find_one({'oa2_id': uid}) user = self.app.db.users.find_one({'user_info': uid})
if not user: if not user:
self.abort(404) self.abort(404)
if uid == self.userid or self.user_is_superuser: # users can only update their own info if uid == self.userid or self.user_is_superuser: # users can only update their own info
...@@ -292,7 +293,7 @@ class User(nimsapiutil.NIMSRequestHandler): ...@@ -292,7 +293,7 @@ class User(nimsapiutil.NIMSRequestHandler):
updates['$set'][k] = False # superuser is tri-state: False indicates granted, but disabled, superuser privileges updates['$set'][k] = False # superuser is tri-state: False indicates granted, but disabled, superuser privileges
elif v.lower() not in ('1', 'true'): elif v.lower() not in ('1', 'true'):
updates['$unset'][k] = '' updates['$unset'][k] = ''
self.app.db.users.update({'oa2_id': uid}, updates) self.app.db.users.update({'user_info': uid}, updates)
else: else:
self.abort(403) self.abort(403)
...@@ -463,6 +464,7 @@ if __name__ == '__main__': ...@@ -463,6 +464,7 @@ if __name__ == '__main__':
arg_parser.add_argument('--stage_path', help='path to staging area') arg_parser.add_argument('--stage_path', help='path to staging area')
arg_parser.add_argument('--ssl_key', help='path to private SSL key file') arg_parser.add_argument('--ssl_key', help='path to private SSL key file')
arg_parser.add_argument('--site_id', help='InterNIMS site ID') arg_parser.add_argument('--site_id', help='InterNIMS site ID')
arg_parser.add_argument('--oauth2_id_endpoint', help='OAuth2 provider ID endpoint')
args = arg_parser.parse_args() args = arg_parser.parse_args()
config = ConfigParser.ConfigParser({'here': os.path.dirname(os.path.abspath(args.config_file))}) config = ConfigParser.ConfigParser({'here': os.path.dirname(os.path.abspath(args.config_file))})
...@@ -483,7 +485,8 @@ if __name__ == '__main__': ...@@ -483,7 +485,8 @@ if __name__ == '__main__':
app.config['site_id'] = args.site_id or 'local' app.config['site_id'] = args.site_id or 'local'
app.config['stage_path'] = args.stage_path or config.get('nims', 'stage_path') app.config['stage_path'] = args.stage_path or config.get('nims', 'stage_path')
app.config['oauth2_id_endpoint'] = args.oauth2_id_endpoint or config.get('oauth2', 'id_endpoint')
log.debug(app.config['oauth2_id_endpoint'])
db_uri = args.db_uri or config.get('nims', 'db_uri') db_uri = args.db_uri or config.get('nims', 'db_uri')
app.db = (pymongo.MongoReplicaSetClient(db_uri) if 'replicaSet' in db_uri else pymongo.MongoClient(db_uri)).get_default_database() app.db = (pymongo.MongoReplicaSetClient(db_uri) if 'replicaSet' in db_uri else pymongo.MongoClient(db_uri)).get_default_database()
......
...@@ -50,6 +50,7 @@ application = nimsapi.app ...@@ -50,6 +50,7 @@ application = nimsapi.app
application.config['stage_path'] = config.get('nims', 'stage_path') application.config['stage_path'] = config.get('nims', 'stage_path')
application.config['site_id'] = site_id application.config['site_id'] = site_id
application.config['ssl_key'] = privkey application.config['ssl_key'] = privkey
application.config['oauth2_id_endpoint'] = config.get('oauth2', 'id_endpoint')
# connect to db # connect to db
db_uri = config.get('nims', 'db_uri') db_uri = config.get('nims', 'db_uri')
......
...@@ -55,27 +55,29 @@ class NIMSRequestHandler(webapp2.RequestHandler): ...@@ -55,27 +55,29 @@ class NIMSRequestHandler(webapp2.RequestHandler):
log.debug('accesstoken: ' + str(self.access_token)) log.debug('accesstoken: ' + str(self.access_token))
self.userid = '@public' # @public is default user self.userid = '@public' # @public is default user
# self.user_is_superuser = None
# check for user as url encoded param # check for user as url encoded param
if self.request.remote_user: if self.request.remote_user:
self.userid = self.request.remote_user self.userid = self.request.remote_user
# handle access token # handle access token
if self.access_token: if self.access_token and self.app.config['oauth2_id_endpoint']:
r = requests.request(method='GET', r = requests.request(method='GET',
url='https://www.googleapis.com/plus/v1/people/me/openIdConnect', url = self.app.config['oauth2_id_endpoint'],
params={'access_token': self.access_token}) headers={'Authorization': 'Bearer ' + self.access_token})
if r.status_code == 200: if r.status_code == 200:
# TODO: reduce to minimum needed to match # TODO: reduce to minimum needed to match
user_profile = json.loads(r.content) user_profile = json.loads(r.content)
# FIXME: lookup should be on oauth_id # FIXME: lookup should be on user_id
self.user = self.app.db.users.find_one({'firstname': user_profile['given_name'], 'lastname': user_profile['family_name']}) self.user = self.app.db.users.find_one({'user_id': user_profile['email']})
self.userid = self.user['_id'] # self.user_is_superuser = self.user.get('superuser', None)
self.userid = self.user['user_id']
log.debug('oauth user: ' + user_profile['email']) log.debug('oauth user: ' + user_profile['email'])
else: else:
#TODO: add handlers for bad tokens. #TODO: add handlers for bad tokens.
log.debug('ERR: ' + str(r.status_code) + ' bad token') log.debug('ERR: ' + str(r.status_code) + ' bad token')
self.user = self.app.db.users.find_one({'oa2_id': self.userid}) # self.user = self.app.db.users.find_one({'user_info': self.user_info})
self.user_is_superuser = self.user.get('superuser', None) self.user = self.app.db.users.find_one({'user_id': self.userid})
log.debug(self.user) self.user_is_superuser = self.user.get('superuser', None) if self.user else False
# p2p request # p2p request
self.target_id = self.request.get('iid', None) self.target_id = self.request.get('iid', None)
...@@ -143,6 +145,10 @@ class NIMSRequestHandler(webapp2.RequestHandler): ...@@ -143,6 +145,10 @@ class NIMSRequestHandler(webapp2.RequestHandler):
except KeyError as e: except KeyError as e:
pass # not all requests will have access_token pass # not all requests will have access_token
# build up a description of request to sign
# msg = self.request.method + self.request.path + str(self.request.params) + str(self.request.headers) + self.request.body
# log.debug(msg)
# create a signature of the incoming request payload # create a signature of the incoming request payload
h = Crypto.Hash.SHA.new(reqpayload) h = Crypto.Hash.SHA.new(reqpayload)
signature = Crypto.Signature.PKCS1_v1_5.new(self.ssl_key).sign(h) signature = Crypto.Signature.PKCS1_v1_5.new(self.ssl_key).sign(h)
...@@ -153,7 +159,7 @@ class NIMSRequestHandler(webapp2.RequestHandler): ...@@ -153,7 +159,7 @@ class NIMSRequestHandler(webapp2.RequestHandler):
r = requests.request(method=self.request.method, data=reqpayload, url=target_api, params=reqparams, headers=reqheaders, verify=False) r = requests.request(method=self.request.method, data=reqpayload, url=target_api, params=reqparams, headers=reqheaders, verify=False)
# return response content # return response content
# TODO: headers # TODO: think about: are the headers even useful?
self.response.write(r.content) self.response.write(r.content)
elif self.ssl_key is None or self.site_id is None: elif self.ssl_key is None or self.site_id is None:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment