def test_ligo_update_or_create(self): payload = { 'givenName': "buffy", 'sn': "summers", 'mail': '*****@*****.**' } self.assertFalse(GWCloudUser.does_user_exist("buffy123")) buffy = GWCloudUser.ligo_update_or_create("buffy123", payload) self.assertEqual(buffy.first_name, payload['givenName']) self.assertEqual(buffy.last_name, payload['sn']) self.assertEqual(buffy.email, payload['mail']) payload['sn'] = "married" payload['mail'] = '*****@*****.**' GWCloudUser.ligo_update_or_create("buffy123", payload) buffy.refresh_from_db() self.assertEqual(buffy.first_name, payload['givenName']) self.assertEqual(buffy.last_name, payload['sn']) self.assertEqual(buffy.email, payload['mail'])
def setUpTestData(cls): payload = { 'givenName': "buffy", 'sn': "summers", 'mail': '*****@*****.**' } cls.buffy = GWCloudUser.ligo_update_or_create("buffy", payload) cls.bill = GWCloudUser.objects.create(username="******", first_name="billy", last_name="nye", email="*****@*****.**") cls.sally = GWCloudUser.objects.create(username="******", first_name="sally", last_name="gold", email="*****@*****.**") cls.mike = GWCloudUser.objects.create(username="******", first_name="Mike", last_name="Pats", email="*****@*****.**")
def ligo_auth(request): # 'cn': 'Lewis Lakerink' # 'displayName': 'Lewis Lakerink' # 'eduPersonPrincipalName': '*****@*****.**' # 'employeeNumber': '5429' # 'givenName': 'Lewis' # 'mail': '*****@*****.**' # 'sn': 'Lakerink' # 'uid': 'lewis.lakerink' # Check if 'special' was passed through to the view - this is currently used by the ozstar accounts portal to verify # that a user is a valid ligo user if 'special' in request.GET: # The 'special' get parameter is a JWT encoded token containing a callback url and a payload payload = jwt.decode(request.GET['special'], settings.ACCOUNTS_PORTAL_LIGO_AUTH_SECRET_KEY, algorithms='HS256') # Generate the response token to send back to the accounts portal response_token = jwt.encode( { "verified": True, "project_join_request_id": payload['project_join_request_id'] }, settings.ACCOUNTS_PORTAL_LIGO_AUTH_SECRET_KEY, algorithm='HS256') # Return a response that will redirect to the callback url with the verification token return HttpResponse(f""" <!DOCTYPE html> <script> window.location = "{payload['callback_url']}{response_token.decode()}"; </script> """) else: # This will generate a unique hash that is 128 characters long (Django has 160 limit on username field) username_hash = sha3_512( (request.META['uid'] + settings.SECRET_KEY).encode()).hexdigest() # Get and update the user user = GWCloudUser.ligo_update_or_create(username_hash, request.META) # Authorize the user and get the token details token = get_token(user) refresh_token = refresh_token_lazy(user) # Get the next url next_url = request.GET.get('next', '/') response_token = jwt.encode( { "token": token, "refresh_token": str(refresh_token), "next_url": next_url }, settings.SECRET_KEY, algorithm='HS256') # Now we need to determine if the login was for gwlab, gwcloud or gwlandscape and correctly redirect to # the relevant domain # todo: Perhaps this can be improved domain_param = request.GET.get('domain', 'gwcloud') if domain_param == 'gwlab': domain = "https://gwlab.org.au" elif domain_param == 'gwcloud': domain = "https://gwcloud.org.au" elif domain_param == 'gwlandscape': domain = "https://gwlandscape.org.au" # Since the ligo authentication works only under gw-cloud.org, we need to redirect to the # calling domain with the provided token. Each of gwcloud/gwlab.org.au exposes an /auth/ # url which can handle the ligo_continue. # To make this work as expected, we append the ligo_continue url to the domain and redirect # there with the generated token. This allows the token to be correctly set in local storage # for the relevant calling application return HttpResponseRedirect( parse.urljoin( domain, reverse('ligo_continue', args=[response_token.decode()])))