def test_authenticate_invalid_user(self): def error(*args): raise ValueError("Invalid Signature") self.replacer.replace("nexus.token_utils.validate_token", error) client = Client(self.config) self.assertFalse(client.authenticate_user("this is a bad token"))
def test_authenticate_valid_user(self): username = "******" def auth(*args, **kwargs): return username self.replacer.replace("nexus.token_utils.validate_token", auth) client = Client(self.config) self.assertEqual(username, client.authenticate_user("this is a good token"))
def test_get_access_token(self): from nexus.token_utils import DictObj expected_expiry = datetime.datetime.utcnow() + datetime.timedelta(minutes=5) expected_expiry = time.mktime(expected_expiry.timetuple()) result = {"access_token": 1234567, "refresh_token": 7654321, "expires_in": 5 * 60} def dummy_get_access_token(client_id, client_secret, auth_code, auth_uri): self.assertEqual("my token", auth_code) self.assertEqual(self.config["api_key"], client_id) self.assertEqual(self.config["api_secret"], client_secret) return DictObj(result) self.replacer.replace("nexus.client.token_utils.request_access_token", dummy_get_access_token) client = Client(self.config) access_token, refresh_token, expiry = client.get_access_token_from_code("my token") self.assertEqual(1234567, access_token) self.assertEqual(7654321, refresh_token) self.assertEqual(expected_expiry, expiry)
def test_full_authenticate_user(self): import rsa pubkey, privkey = rsa.newkeys(512) def get_cert(*args, **kwargs): return namedtuple("Request", ["content"])(json.dumps({"pubkey": pubkey.save_pkcs1()})) self.replacer.replace("requests.get", get_cert) token = "un=test|SigningSubject=https://graph.api.globusonline.org/goauth/keys/test1|expiry={0}" expires = datetime.datetime.utcnow() + datetime.timedelta(minutes=5) token = token.format(time.mktime(expires.timetuple())) sig = rsa.sign(token, privkey, "SHA-1") hex_sig = binascii.hexlify(sig) token = "{0}|sig={1}".format(token, hex_sig) client = Client(self.config) self.assertTrue(client.authenticate_user(token)) sig = sig + "f" hex_sig = binascii.hexlify(sig) token = "{0}|sig={1}".format(token, hex_sig) self.assertFalse(client.authenticate_user(token))
import os.path from getpass import getpass from nexus import Client # First instantiate a client object either with a dictionary or with a yaml file pwd = os.path.dirname(__file__) client = Client(config_file=os.path.join(pwd, 'sample.yml')) # Generate a url for the end user to use to authorize this client/authenticate. url = client.generate_request_url() print "Please authenticate using the following url" print url token = raw_input("Please copy the resulting code here: ") # At this point the end user needs to authenticate with the supplied url. The # easiest way to do this is: curl -k --user test:test1 "<supplied_url>". The # result will contain the token in the "code" field. Paste that here. # Validate the token: user = client.authenticate_user(token) if user is not None: print "Yup, you are {0}".format(user) else: print "That is not a valid authorization code" #Get an access key for yourself using rsa: print client.request_client_credential(user, lambda: getpass("Private Key Password")) print "Get a request token using rsa authentication" print client.rsa_get_request_token(user, lambda: getpass("Private Key Password"))
def test_generate_request_url(self): client = Client(self.config) expected = "https://graph.api.globusonline.org/goauth/authorize?response_type=code&client_id=I+am+not+a+key" self.assertEqual(expected, client.generate_request_url())
class OAuth2Middleware(AuthenticationMiddleware): """ Two Legged OAuth authenticator. This Authentication method checks for a provided HTTP_AUTHORIZATION and looks up to see if this is a valid OAuth Consumer """ # Authentication server # Create a Python Globus client client = Client( config_file=os.path.join(os.path.dirname(__file__), 'nexus/nexus.yml')) try: authsvc = "https://%s/" % client.config['server'] except: authsvc = 'https://nexus.api.globusonline.org/' # Set the salt used for computing a session hash from the signature hash salt = "(African || European)?" def __init__(self, realm='API'): self.realm = realm self.user = None self.http = httplib2.Http(disable_ssl_certificate_validation=True) # The shortcut option will bypass token validation if we already have a django session self.shortcut = False def process_request(self, request): """ Verify 2-legged oauth request. Parameters accepted as values in "Authorization" header, or as a GET request or in a POST body. """ # AuthenticationMiddleware is required so that request.user exists. if not hasattr(request, 'user'): raise ImproperlyConfigured( "The Django remote user auth middleware requires the" " authentication middleware to be installed. Edit your" " MIDDLEWARE_CLASSES setting to insert" " 'django.contrib.auth.middleware.AuthenticationMiddleware'" " before the RemoteUserMiddleware class.") try: if 'HTTP_AUTHORIZATION' in request.META: auth_header = request.META.get('HTTP_AUTHORIZATION') else: logging.debug("No authorization header found.") return None # Extract the token based on whether it is an OAuth or Bearer # token if auth_header[:6] == 'OAuth ': token = auth_header[6:] elif auth_header[:7] == 'Bearer ': token = auth_header[7:] else: logging.info( "Authorization header did not contain OAuth or Bearer type token" ) return None # Push the token into the META for future reference request.META['KBASEtoken'] = token if (request.user.is_authenticated() and self.shortcut): return user_id = OAuth2Middleware.client.authenticate_user(token) if not user_id: logging.error("Authentication token failed validation") return None else: logging.info("Validated as user " + user_id) token_map = {} for entry in token.split('|'): key, value = entry.split('=') token_map[key] = value profile = self.get_profile(token) if (profile == None): logging.error( "Token validated, but could not retrieve user profile") return None # For now, compute a sessionid based on hashing the # the signature with the salt request.META['KBASEsessid'] = hashlib.sha256( token_map['sig'] + OAuth2Middleware.salt).hexdigest() # Add in some useful details that came in from the token validation request.META['KBASEprofile'] = profile # See if the username is already associated with any currently logged # in user, if so just pass over the rest # Raises exception if it doesn't pass user = authenticate(remote_user=profile['username']) if user: request.user = user # For now, compute a sessionid based on hashing the # the signature with the salt request.META['KBASEsessid'] = hashlib.sha256( token_map['sig'] + OAuth2Middleware.salt).hexdigest() print pformat(request.META['KBASEsessid']) # Add in some useful details that came in from the token validation request.META['KBASEprofile'] = profile login(request, user) else: logging.error( "Failed to return user from call to authenticate() with username " + profile['username']) except KeyError, e: logging.exception("KeyError in TwoLeggedOAuthMiddleware: %s" % e) request.user = AnonymousUser() except Exception, e: logging.exception("Error in TwoLeggedOAuthMiddleware: %s" % e)