Add Google SSO
This pull request adds Google SSO support. There are two main changes: 1. Add the Google auth view resource 2. Make passwords optional when creating a new user. This allows an admin to create a user without a password so that they can only login via Google.
This commit is contained in:
parent
70c92fea15
commit
350d013043
|
@ -230,5 +230,46 @@ class Ping(Resource):
|
||||||
return dict(token=create_token(user))
|
return dict(token=create_token(user))
|
||||||
|
|
||||||
|
|
||||||
|
class Google(Resource):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.reqparse = reqparse.RequestParser()
|
||||||
|
super(Google, self).__init__()
|
||||||
|
|
||||||
|
def post(self):
|
||||||
|
access_token_url = 'https://accounts.google.com/o/oauth2/token'
|
||||||
|
people_api_url = 'https://www.googleapis.com/plus/v1/people/me/openIdConnect'
|
||||||
|
|
||||||
|
self.reqparse.add_argument('clientId', type=str, required=True, location='json')
|
||||||
|
self.reqparse.add_argument('redirectUri', type=str, required=True, location='json')
|
||||||
|
self.reqparse.add_argument('code', type=str, required=True, location='json')
|
||||||
|
|
||||||
|
args = self.reqparse.parse_args()
|
||||||
|
|
||||||
|
# Step 1. Exchange authorization code for access token
|
||||||
|
payload = {
|
||||||
|
'client_id': args['clientId'],
|
||||||
|
'grant_type': 'authorization_code',
|
||||||
|
'redirect_uri': args['redirectUri'],
|
||||||
|
'code': args['code'],
|
||||||
|
'client_secret': current_app.config.get('GOOGLE_SECRET')
|
||||||
|
}
|
||||||
|
|
||||||
|
r = requests.post(access_token_url, data=payload)
|
||||||
|
token = r.json()
|
||||||
|
|
||||||
|
# Step 2. Retrieve information about the current user
|
||||||
|
headers = {'Authorization': 'Bearer {0}'.format(token['access_token'])}
|
||||||
|
|
||||||
|
r = requests.get(people_api_url, headers=headers)
|
||||||
|
profile = r.json()
|
||||||
|
|
||||||
|
user = user_service.get_by_email(profile['email'])
|
||||||
|
|
||||||
|
if user:
|
||||||
|
return dict(token=create_token(user))
|
||||||
|
|
||||||
|
|
||||||
api.add_resource(Login, '/auth/login', endpoint='login')
|
api.add_resource(Login, '/auth/login', endpoint='login')
|
||||||
api.add_resource(Ping, '/auth/ping', endpoint='ping')
|
api.add_resource(Ping, '/auth/ping', endpoint='ping')
|
||||||
|
api.add_resource(Google, '/auth/google', endpoint='google')
|
||||||
|
|
|
@ -30,8 +30,7 @@
|
||||||
Password
|
Password
|
||||||
</label>
|
</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<input type="password" name="password" ng-model="user.password" placeholder="hunter2" class="form-control" required/>
|
<input type="password" name="password" ng-model="user.password" placeholder="hunter2" class="form-control" />
|
||||||
<p ng-show="createForm.password.$invalid && !createForm.password.$pristine" class="help-block">You must enter an password</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -52,7 +52,10 @@ class User(db.Model):
|
||||||
:param password:
|
:param password:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
return bcrypt.check_password_hash(self.password, password)
|
if self.password:
|
||||||
|
return bcrypt.check_password_hash(self.password, password)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
def hash_password(self):
|
def hash_password(self):
|
||||||
"""
|
"""
|
||||||
|
@ -60,8 +63,11 @@ class User(db.Model):
|
||||||
|
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
self.password = bcrypt.generate_password_hash(self.password)
|
if self.password:
|
||||||
return self.password
|
self.password = bcrypt.generate_password_hash(self.password)
|
||||||
|
return self.password
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_admin(self):
|
def is_admin(self):
|
||||||
|
|
|
@ -157,7 +157,7 @@ class UsersList(AuthenticatedResource):
|
||||||
"""
|
"""
|
||||||
self.reqparse.add_argument('username', type=str, location='json', required=True)
|
self.reqparse.add_argument('username', type=str, location='json', required=True)
|
||||||
self.reqparse.add_argument('email', type=str, location='json', required=True)
|
self.reqparse.add_argument('email', type=str, location='json', required=True)
|
||||||
self.reqparse.add_argument('password', type=str, location='json', required=True)
|
self.reqparse.add_argument('password', type=str, location='json', default=None)
|
||||||
self.reqparse.add_argument('active', type=bool, default=True, location='json')
|
self.reqparse.add_argument('active', type=bool, default=True, location='json')
|
||||||
self.reqparse.add_argument('roles', type=roles, default=[], location='json')
|
self.reqparse.add_argument('roles', type=roles, default=[], location='json')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue