def get(self, request, username): """ Create a new token in the database on behalf of 'username' Returns success 201 Created - Body is JSON and contains """ user = request.user if not username: return Response("Username was not provided", status=status.HTTP_400_BAD_REQUEST) if user.username is not 'admin' and not user.is_superuser: logger.error("URGENT! User: %s is attempting to emulate a user!" % user.username) return Response("Only admin and superusers can emulate accounts. " "This offense has been reported", status=status.HTTP_401_UNAUTHORIZED) if not AtmosphereUser.objects.filter(username=username): return Response("Username %s does not exist as an AtmosphereUser" % username, status=status.HTTP_404_NOT_FOUND) # User is authenticated, username exists. Make a token for them. user_to_emulate = AtmosphereUser.objects.get_by_natural_key(username) token = get_or_create_token(user_to_emulate, issuer="DRF-EmulatedUser") expireTime = token.issuedTime + secrets.TOKEN_EXPIRY_TIME auth_json = { # Extra data passed only on emulation.. "emulator": request.user.username, # Normal token data.. "token": token.key, "username": token.user.username, "expires": expireTime.strftime("%b %d, %Y %H:%M:%S") } return Response(auth_json, status=status.HTTP_201_CREATED)
def get(self, request, username): """ Create a new token in the database on behalf of 'username' Returns success 201 Created - Body is JSON and contains """ user = request.user if not username: return Response("Username was not provided", status=status.HTTP_400_BAD_REQUEST) if user.username is not 'admin' and not user.is_superuser: logger.error("URGENT! User: %s is attempting to emulate a user!" % user.username) return Response( "Only admin and superusers can emulate accounts. " "This offense has been reported", status=status.HTTP_401_UNAUTHORIZED) if not AtmosphereUser.objects.filter(username=username): return Response("Username %s does not exist as an AtmosphereUser" % username, status=status.HTTP_404_NOT_FOUND) # User is authenticated, username exists. Make a token for them. user_to_emulate = AtmosphereUser.objects.get_by_natural_key(username) token = get_or_create_token(user_to_emulate, issuer="DRF-EmulatedUser") expireTime = token.issuedTime + secrets.TOKEN_EXPIRY_TIME auth_json = { # Extra data passed only on emulation.. "emulator": request.user.username, # Normal token data.. "token": token.key, "username": token.user.username, "expires": expireTime.strftime("%b %d, %Y %H:%M:%S") } return Response(auth_json, status=status.HTTP_201_CREATED)
def create_user_token_from_globus_profile(profile, access_token): """ Use this method on your Resource Provider (Like Atmosphere) to exchange a profile (that was retrieved via a tokeninfo endpoint) for a UserToken that can then be internally validated in an 'authorize' authBackend step.. """ logger.info(profile) expiry = profile['exp'] # This is an 'epoch-int' expiry = _extract_expiry_date(expiry) issuer = profile['iss'] issued_at = profile['iat'] raw_username = profile['username'] # username@login_auth.com raw_name = profile['name'] email = profile['email'] username = _extract_user_from_email(raw_username) first_name, last_name = _extract_first_last_name(raw_name) profile_dict = { 'username': username, 'firstName': first_name, 'lastName': last_name, 'email': email, } user = get_or_create_user(profile_dict['username'], profile_dict) auth_token = get_or_create_token(user, access_token, token_expire=expiry, issuer=issuer) return auth_token
def create_token_from_jwt(self, jwt_assertion): """ This method point represents the 'entry point' """ decoded_assertion = self.decode_assertion(jwt_assertion) user, expiration = self.validate_assertion(decoded_assertion) auth_token = get_or_create_token(user.username, expiration) return auth_token
def _create_token(self, request, user, token_key, issuer="DRF"): token = get_or_create_token(user, token_key, issuer=issuer) expireTime = token.issuedTime + secrets.TOKEN_EXPIRY_TIME auth_json = { 'token': token.key, 'username': token.user.username, 'expires': expireTime.strftime("%b %d, %Y %H:%M:%S") } request.session['token'] = token.key return Response(auth_json, status=status.HTTP_201_CREATED)
def _create_token(self, request, user, token_key, issuer="DRF"): token = get_or_create_token(user, token_key, issuer=issuer) expireTime = token.issuedTime + secrets.TOKEN_EXPIRY_TIME auth_json = { 'token': token.key, 'username': token.user.username, 'expires': expireTime.strftime("%b %d, %Y %H:%M:%S") } request.session['token'] = token.key return Response(auth_json, status=status.HTTP_201_CREATED)
def get(self, request): user = request.user if not user.is_authenticated(): return Response("Logged-in User or POST required " "to retrieve AuthToken", status=status.HTTP_403_FORBIDDEN) token = lookupSessionToken(request) if not token: token_key = request.session.pop('token_key',None) token = get_or_create_token(user, token_key, issuer="DRF") serialized_data = TokenSerializer(token).data return Response(serialized_data, status=status.HTTP_200_OK)
def emulate_session(request, username=None): try: logger.info( "Emulate attempt: %s wants to be %s" % (request.user, username) ) logger.info(request.session.__dict__) if not username and 'emulator' in request.session: logger.info("Clearing emulation attributes from user") request.session['username'] = request.session['emulator'] del request.session['emulator'] # Allow user to fall through on line below try: user = AtmosphereUser.objects.get(username=username) except AtmosphereUser.DoesNotExist: logger.info( "Emulate attempt failed. User <%s> does not exist" % username ) return HttpResponseRedirect(settings.REDIRECT_URL + "/api/v2") logger.info("Emulate success, creating tokens for %s" % username) expireDate = timezone.now() + secrets.TOKEN_EXPIRY_TIME token = get_or_create_token( user, token_key='EMULATED-' + str(uuid4()), token_expire=expireDate, remote_ip=request.META['REMOTE_ADDR'], issuer="DRF-EmulatedSession-%s" % user.username ) token.save() # Keep original emulator if it exists, or use the last known username original_emulator = request.session.get( 'emulator', request.session['username'] ) request.session['emulator'] = original_emulator # Set the username to the user to be emulated # to whom the token also belongs request.session['username'] = username request.session['token'] = token.key logger.info("Returning emulated user - %s - to api root " % username) logger.info(request.session.__dict__) logger.info(request.user) serialized_data = TokenSerializer( token, context={ 'request': request } ).data return Response(serialized_data, status=status.HTTP_201_CREATED) except Exception as e: logger.warn("Emulate request failed") logger.exception(e) return HttpResponseRedirect(settings.REDIRECT_URL + "/api/v2")
def retrieve(self, *args, **kwargs): user = self.request.user # data = self.request.data username = kwargs.get('username') expireDate = timezone.now() + secrets.TOKEN_EXPIRY_TIME new_token = get_or_create_token( user, token_key='EMULATED-' + str(uuid4()), remote_ip=self.request.META['REMOTE_ADDR'], token_expire=expireDate, issuer="DRF-EmulatedToken-%s" % user.username) serialized_data = TokenSerializer(new_token, context={'request':self.request}).data return Response(serialized_data, status=status.HTTP_201_CREATED)
def get(self, request): user = request.user if not user.is_authenticated(): return Response( "Logged-in User or POST required " "to retrieve AuthToken", status=status.HTTP_403_FORBIDDEN) token = lookupSessionToken(request) if not token: token_key = request.session.pop('token_key', None) token = get_or_create_token(user, token_key, issuer="DRF") serialized_data = TokenSerializer(token).data return Response(serialized_data, status=status.HTTP_200_OK)
def retrieve(self, *args, **kwargs): user = self.request.user expireDate = timezone.now() + secrets.TOKEN_EXPIRY_TIME new_token = get_or_create_token( user, token_key='EMULATED-' + str(uuid4()), remote_ip=self.request.META['REMOTE_ADDR'], token_expire=expireDate, issuer="DRF-EmulatedToken-%s" % user.username ) serialized_data = TokenSerializer( new_token, context={ 'request': self.request } ).data return Response(serialized_data, status=status.HTTP_201_CREATED)
def globus_validate_code(request): """ This flow is used to create a new Token on behalf of a Service Client (Like Troposphere) Validates 'code' returned from the IdP If valid: Return new AuthToken to be passed to the Resource Provider. else: Return None """ code = request.GET.get('code', '') error = request.GET.get('error', '') error_description = request.GET.get('error_description', '') if error: error_msg = "%s: %s" % ( error, error_description) if error_description else error raise Unauthorized(error_msg) if not code: logger.warn( "User returned from Login prompt but there was NO `code` to validate!" ) return None if type(code) == list: code = code[0] flow = globus_initFlow() try: credentials = flow.step2_exchange(code) logger.info(credentials.__dict__) except OAuthError as err: logger.exception("Error exchanging code w/ globus") return None except Exception as err: logger.exception( "Unknown Error occurred while exchanging code w/ globus") return None # Parsing try: user_access_token = parse_atmosphere_token(credentials.token_response) token_profile = credentials.id_token expiry_date = credentials.token_expiry except Exception as err: logger.exception( "Parse of the credentials response failed. Ask a developer for help!" ) return None raw_username = token_profile['preferred_username'] email = token_profile['email'] username = _extract_user_from_email(raw_username) if not username: logger.info("No user provided in token_profile: Check output %s" % token_profile) return None full_name = token_profile['name'] issuer = token_profile['iss'] # Creation first_name, last_name = _extract_first_last_name(full_name) username = username.lower() user_profile = { 'username': username, 'firstName': first_name, 'lastName': last_name, 'email': email, } user = get_or_create_user(user_profile['username'], user_profile) auth_token = get_or_create_token(user, user_access_token, token_expire=expiry_date, issuer="OpenstackLoginBackend") return auth_token