def test_oauth_crypto(self):

        phrase = 'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE'

        token = {
            'access_token':
            'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE',
            'expires_in': oauth2_settings.ACCESS_TOKEN_EXPIRE_SECONDS,
            'token_type': 'Password',
            'refresh_token': 'abc',
            'scope': 'read write'
        }

        data = encrypt_access_token(token)

        if not data:
            self.fail()

        result = decrypt_access_token(data)

        if not result:
            self.fail()

        if phrase != result['access_token']:
            self.fail('Decrypted value does not match phrase.')
Example #2
0
def sdLogin(request, *args, **kwargs):

    # TODO: Support the "next" parameter in the template javascript redirect code.

    # This POST method is called by javascript and expects some JSON in return.
    # The goal here is to authenticate the user with oauth and then encrypt the
    # oauth information.  The encrypted information will be stored in a browser cookie,
    # to be later decrypted in the middleware level to set the "Authorization" header.
    if request.method == 'POST':

        if 'username' not in request.POST or 'password' not in request.POST:
            raise ValueError

        # Manually do django authentication.
        username = request.POST['username']
        password = request.POST['password']

        user = authenticate(username=username, password=password)

        if user is not None and user.is_active:

            # Log our user in to django
            login(request, user)

            # Create and encrypt the access token based on this user
            enc = encrypt_access_token(create_access_token(user, user.profile.oauth_scope))

            # Setup login redirect
            if 'next' in request.GET:
                redirect = request.GET['next']
            else:
                redirect = settings.LOGIN_REDIRECT_URL

            # Format our response
            response = JsonResponse(
                dict([('status', 'OK'), ('next', redirect)])
            )

            # Set the encrypted token in the response.
            response.set_cookie('token', enc.decode('UTF-8'))
            response.set_cookie('fade-page-in', 1)

        else:
            # Send our error message
            response = JsonResponse(
                dict([('status', 'ERROR')])
            )

        return response

    else:

        form = accounts.forms.SDAuthenticationForm()
        context = {
            'form': form,
            'next': request.GET['next'] if 'next' in request.GET else None,
        }

    return render(request, 'accounts/login.html', context)
Example #3
0
    def test_token_encryption(self):
        """ Test the encryption and decryption of the access token """
        enc_token = encrypt_access_token(self.token)

        self.assertTrue(enc_token)

        token = decrypt_access_token(enc_token)
        self.assertTrue(is_access_token_valid(token))
        self.assertTrue(token)
Example #4
0
    def test_token_encryption(self):
        """ Test the encryption and decryption of the access token """
        enc_token = encrypt_access_token(self.token)

        self.assertTrue(enc_token)

        token = decrypt_access_token(enc_token)
        self.assertTrue(is_access_token_valid(token))
        self.assertTrue(token)
Example #5
0
    def process_request(self, request):

        # Check to see if this is the login/logout page, if so just return.
        if '/accounts/login/' in request.path or '/accounts/logout/' in request.path:
            return

        # TODO: Only do oauth token stuff when the url is an API url
        if 'token' in request.COOKIES:

            # Get the encrypted access token data, fix any equal sign encoding.
            enc = request.COOKIES['token'].replace('%3D', '=').encode('UTF-8')

            # Decrypt the access token data
            token = decrypt_access_token(enc)

            # Check for a valid oauth token.
            if token is not None and 'access_token' in token:

                # Check to see if access token is not valid.
                if not is_access_token_valid(token):

                    # TODO: Figure out when we should *not* just refresh the token.
                    # Try to refresh the token.
                    token = refresh_access_token(token)

                    # If we have a good refreshed token, update the cookies.
                    if 'access_token' in token:

                        # Encrypt the new token
                        enc = encrypt_access_token(token)

                        # Set the token into the request object
                        cookies = request.COOKIES.copy()
                        cookies['token'] = enc.decode('UTF-8')
                        cookies['token-update'] = "1"

                        request.COOKIES = cookies.copy()

                    else:
                        # Refresh token failed
                        return HttpResponseRedirect('/accounts/logout/')

                # Create the Authorization header with the access token.
                request.META['Authorization'] = 'bearer {0}'.format(token['access_token'])

        else:
            pass
Example #6
0
    def test_api_node_post(self):
        """
        The url '/api/nodes' requires the oauth2 encrypted token when creating a record.
        If the 'token' cookie is not set, then the node API requires the HTTP_NODE header value
        set to access and update records.
        """

        # Encrypt the token and store it in the client cookies.
        self.client.cookies['token'] = encrypt_access_token(self.token).decode('UTF-8')

        # Set node header value and see if we can retrieve the node record.
        response = self.client.get('/api/nodes/1/', HTTP_NODE=self.machine_id)
        self.assertEquals(response.status_code, 200)

        # Check for any unmatched fields.  If there are, then check client models or node models
        # for field updates.
        data = response.json()

        # Update Node record
        data['dist_version'] = u'camelot'
        response = self.client.post('/api/nodes/', data=data)

        self.assertEquals(response.status_code, 200)
        self.assertEquals(response.json()['dist_version'], 'camelot')

        # Remove token cookie so we can test node authentication
        self.client.cookies.pop('token', None)

        # Test accessing the node record with no authentication set. We should get access denied.
        response = self.client.get('/api/nodes/')
        self.assertEquals(response.status_code, 403)

        # Set node header value and see if we can retrieve the node record.
        response = self.client.get('/api/nodes/1/', HTTP_NODE=self.machine_id)
        self.assertEquals(response.status_code, 200)

        # Check for any unmatched fields.  If there are, then check client models or node models
        # for field updates.
        unmatched = set(response.json()) ^ set(data)
        self.assertTrue(len(unmatched) == 0)
Example #7
0
    def test_oauth_crypto(self):

        phrase = 'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE'

        token = {
            'access_token': 'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE',
            'expires_in': oauth2_settings.ACCESS_TOKEN_EXPIRE_SECONDS,
            'token_type': 'Password',
            'refresh_token': 'abc',
            'scope': 'read write'
        }

        data = encrypt_access_token(token)

        if not data:
            self.fail()

        result = decrypt_access_token(data)

        if not result:
            self.fail()

        if phrase != result['access_token']:
            self.fail('Decrypted value does not match phrase.')
Example #8
0
def login_view(request, *args, **kwargs):

    # TODO: Support the "next" parameter in the template javascript redirect code.

    # This POST method is called by javascript and expects some JSON in return.
    # The goal here is to authenticate the user with oauth and then encrypt the
    # oauth information.  The encrypted information will be stored in a browser cookie,
    # to be later decrypted in the middleware level to set the "Authorization" header.
    if request.method == 'POST':

        if 'username' not in request.POST or 'password' not in request.POST:
            raise ValueError

        # Manually do django authentication.
        username = request.POST['username']
        password = request.POST['password']

        user = authenticate(request=request,
                            username=username,
                            password=password)

        if user is not None and user.is_active:

            # Log our user in to django
            login(request, user)

            # Create and encrypt the access token based on this user
            enc = encrypt_access_token(
                create_access_token(user, user.profile.oauth_scope))

            # Setup login redirect
            if 'next' in request.GET:
                redirect = request.GET['next']
            else:
                redirect = settings.LOGIN_REDIRECT_URL

            # Format our response
            response = JsonResponse(
                dict([('status', 'OK'), ('next', redirect)]))

            # TODO: find out why this delays forever when celery service is not running
            # user_security_event.delay(username, 'login')

            # Set the encrypted token in the response.
            response.set_cookie('token', enc.decode('UTF-8'))
            response.set_cookie('fade-page-in', 1)

        else:
            # Send our error message
            response = JsonResponse(dict([('status', 'ERROR')]))
            # user_security_event.delay(username, 'login', success=False)

        return response

    else:

        form = forms.LoginForm()
        context = {
            'form': form,
            'next': request.GET['next'] if 'next' in request.GET else None,
        }

    return render(request, 'accounts/login.html', context)