Exemplo n.º 1
0
    def create(cls, host, data, access_token, headers=None):
        """
        Create an API resource with POST.
        """

        resource_url = build_url(host, [cls.resource_fragment])
        params = {'access_token': access_token}

        if headers:
            headers['Content-Type'] = 'application/json'
            headers['Host'] = host
        else:
            headers = {'Content-Type': 'application/json', 'Host': host}

        response = requests.post(resource_url,
                                 data=json.dumps(data, cls=DateTimeEncoder),
                                 headers=headers,
                                 params=params)

        try:
            resource = response.json()
        except ValueError:
            raise APIException(
                'The API has returned invalid json: %s' % response.content,
                500)

        if resource['error']:
            raise APIException(resource['error'], response.status_code)

        if not resource['data']:
            raise APIException('No data returned at: %s' % resource_url)

        return resource['data']
Exemplo n.º 2
0
 def retrieve(cls, host, q, access_token):
     """
     Forward a geocode request (q) to the API.
     """
     params = {'q': q}
     headers = {'Authorization': 'Bearer %s' % access_token}
     response = requests.get(build_url(host, ['geocode']), params=params, headers=headers)
     return response.content
Exemplo n.º 3
0
    def rsvp(cls, host, event_id, profile_id, attendance_data, access_token):
        """
        Create or update attendance to an event.
        TODO: This is obviously pretty nasty but it'll be changed soon.
        """

        collection_url = build_url(
            host, [cls.resource_fragment, event_id, 'attendees'])
        item_url = collection_url + '/' + str(profile_id)

        # See if there is an attendance entry for this profile
        try:
            response = requests.get(item_url,
                                    params={'access_token': access_token})
        except RequestException:
            raise

        # If it is not found, POST an attendance
        if response.status_code == 404:
            try:
                print 'Not found, posting to ' + collection_url
                post_response = requests.post(
                    collection_url,
                    attendance_data,
                    params={'access_token': access_token})
            except RequestException:
                raise

            try:
                post_response.json()
            except ValueError:
                raise APIException('Invalid JSON returned')

            return

        # Attendance record exists, so update it with PUT
        elif response.status_code >= 200 and response.status_code < 400:

            try:
                print 'Found, putting to ' + item_url
                put_response = requests.post(item_url,
                                             data=attendance_data,
                                             params={
                                                 'method': 'PUT',
                                                 'access_token': access_token
                                             })
            except RequestException:
                raise

            try:
                put_response.json()
            except ValueError:
                raise APIException('Invalid JSON returned')

            return

        else:
            raise APIException(response.content)
Exemplo n.º 4
0
    def process_response(self, request, response):
        """Deletes the user's access token cookie if it has previously
        been marked as invalid (by process_request)
        """

        if hasattr(request, 'delete_token') and request.delete_token:
            response.delete_cookie('access_token')
            requests.delete(build_url(request.META['HTTP_HOST'], ['auth', request.COOKIES['access_token']]))
        return response
Exemplo n.º 5
0
    def retrieve_attendees(cls, host, id, access_token=None):
        """
        Retrieve a list of attendees for an event.
        TODO: pagination support
        """

        resource_url = build_url(host, [cls.resource_fragment, id, 'attendees'])
        resource = APIResource.retrieve(host, id=id, access_token=access_token, url_override=resource_url)
        resource = cls.create_linkmap(resource)
        return APIResource.process_timestamp(resource)
Exemplo n.º 6
0
 def retrieve(cls, host, q, access_token):
     """
     Forward a geocode request (q) to the API.
     """
     params = {'q': q}
     headers = {'Authorization': 'Bearer %s' % access_token}
     response = requests.get(build_url(host, ['geocode']),
                             params=params,
                             headers=headers)
     return response.content
Exemplo n.º 7
0
    def process_response(self, request, response):
        """Deletes the user's access token cookie if it has previously
        been marked as invalid (by process_request)
        """

        if hasattr(request, 'delete_token') and request.delete_token:
            response.delete_cookie('access_token')
            requests.delete(
                build_url(request.META['HTTP_HOST'],
                          ['auth', request.COOKIES['access_token']]))
        return response
Exemplo n.º 8
0
    def rsvp(cls, host, event_id, profile_id, attendance_data, access_token):
        """
        Create or update attendance to an event.
        TODO: This is obviously pretty nasty but it'll be changed soon.
        """

        collection_url = build_url(host, [cls.resource_fragment, event_id, 'attendees'])
        item_url = collection_url + '/' + str(profile_id)

        # See if there is an attendance entry for this profile
        try:
            response = requests.get(item_url, params={'access_token': access_token})
        except RequestException:
            raise

        # If it is not found, POST an attendance
        if response.status_code == 404:
            try:
                print 'Not found, posting to ' + collection_url
                post_response = requests.post(collection_url, attendance_data, params={'access_token': access_token})
            except RequestException:
                raise

            try:
                post_response.json()
            except ValueError:
                raise APIException('Invalid JSON returned')

            return

        # Attendance record exists, so update it with PUT
        elif response.status_code >= 200 and response.status_code < 400:

            try:
                print 'Found, putting to ' + item_url
                put_response = requests.post(
                    item_url,
                    data=attendance_data,
                    params={'method': 'PUT', 'access_token': access_token}
                )
            except RequestException:
                raise

            try:
                put_response.json()
            except ValueError:
                raise APIException('Invalid JSON returned')

            return

        else:
            raise APIException(response.content)
Exemplo n.º 9
0
    def retrieve_attendees(cls, host, id, access_token=None):
        """
        Retrieve a list of attendees for an event.
        TODO: pagination support
        """

        resource_url = build_url(host,
                                 [cls.resource_fragment, id, 'attendees'])
        resource = APIResource.retrieve(host,
                                        id=id,
                                        access_token=access_token,
                                        url_override=resource_url)
        resource = cls.create_linkmap(resource)
        return APIResource.process_timestamp(resource)
Exemplo n.º 10
0
    def retrieve(cls,
                 host,
                 id=None,
                 offset=None,
                 access_token=None,
                 url_override=None):
        """
        GET an API resource. If resource ID is omitted, returns a list. Appends access_token
        and offset (for paging) if provided.
        """

        headers = {'Host': host}

        if url_override:
            resource_url = url_override
        else:
            path_fragments = [cls.resource_fragment]
            if id:
                id = int(id)
                assert id > 0, 'Resource ID must be greater than zero'
                path_fragments.append(id)
            resource_url = build_url(host, path_fragments)

        params = {}
        if access_token:
            params['access_token'] = access_token
        if offset:
            offset = int(offset)
            assert offset % 25 == 0, 'Offset must be a multiple of 25'
            params['offset'] = offset

        response = requests.get(resource_url, params=params, headers=headers)

        try:
            resource = response.json()
        except ValueError:
            raise APIException(
                'The API has returned invalid json: %s' % response.content,
                500)

        if resource['error']:
            raise APIException(resource['error'], response.status_code)

        if not resource['data']:
            raise APIException('No data returned at: %s' % resource_url)

        return resource['data']
Exemplo n.º 11
0
    def logout(request):
        """
        Log a user out. Issues a DELETE request to the backend for the
        user's access_token, and issues a delete cookie header in response to
        clear the user's access_token cookie.
        """

        view_data = {
            'site': request.site,
        }

        response = render(request, 'logout.html', view_data)

        if request.COOKIES.has_key('access_token'):
            response.delete_cookie('access_token')
            url = build_url(request.META['HTTP_HOST'], ['auth',request.access_token])
            requests.post(url, params={'method': 'DELETE', 'access_token': request.access_token})

        return response
Exemplo n.º 12
0
    def testMicrocosmsView(self):

        # Construct a random subdomain string
        subdomain = ''
        for x in xrange(10):
            subdomain += random.choice(string.lowercase)
        host = '%s.microco.sm' % subdomain

        # Create a request for a list of microcosms
        request = self.factory.get('/microcosms', HTTP_HOST=host)
        request.access_token = None
        request.whoami = None
        request.site = None

        # Patch requests.get and check the call args
        with patch('requests.get') as mock:
            mock.return_value.json.return_value = {'error': None, 'data': {'hi': 5}}
            MicrocosmView.list(request)
            path = build_url(host, ['microcosms'])
            mock.assert_called_once_with(path, headers={'Host': host}, params={})
Exemplo n.º 13
0
    def retrieve(cls, host, id=None, offset=None, access_token=None, url_override=None):
        """
        GET an API resource. If resource ID is omitted, returns a list. Appends access_token
        and offset (for paging) if provided.
        """

        headers = {'Host': host}

        if url_override:
            resource_url = url_override
        else:
            path_fragments = [cls.resource_fragment]
            if id:
                id = int(id)
                assert id > 0, 'Resource ID must be greater than zero'
                path_fragments.append(id)
            resource_url = build_url(host, path_fragments)

        params = {}
        if access_token:
            params['access_token'] = access_token
        if offset:
            offset = int(offset)
            assert offset % 25 == 0, 'Offset must be a multiple of 25'
            params['offset'] = offset

        response = requests.get(resource_url, params=params, headers=headers)

        try:
            resource = response.json()
        except ValueError:
            raise APIException('The API has returned invalid json: %s' % response.content, 500)

        if resource['error']:
            raise APIException(resource['error'], response.status_code)

        if not resource['data']:
            raise APIException('No data returned at: %s' % resource_url)

        return resource['data']
Exemplo n.º 14
0
    def delete(cls, host, id, access_token):
        """
        DELETE an API resource. ID must be supplied.

        A 'data' object is never returned by a DELETE, so this
        method will raise an exception on failure. In normal
        operation the method simply returns.
        """

        path_fragments = [cls.resource_fragment]

        if id:
            id = int(id)
            assert id > 0, 'Resource ID must be greater than zero'
            path_fragments.append(id)
        elif access_token:
            path_fragments.append(access_token)
        else:
            raise AssertionError, 'You must supply either an id or '\
                                  'an access_token to delete'

        resource_url = build_url(host, path_fragments)
        params = {
            'method': 'DELETE',
            'access_token': access_token,
        }
        headers = {'Host': host}
        response = requests.post(resource_url, params=params, headers=headers)

        try:
            resource = response.json()
        except ValueError:
            raise APIException(
                'The API has returned invalid json: %s' % response.content,
                500)

        if resource['error']:
            raise APIException(resource['error'], response.status_code)
Exemplo n.º 15
0
    def update(cls, host, data, id, access_token):
        """
        Update an API resource with PUT.
        """

        id = int(id)
        assert id > 0, 'Resource ID must be greater than zero'
        path_fragments = [cls.resource_fragment, id]
        resource_url = build_url(host, path_fragments)

        headers = {
            'Content-Type': 'application/json',
            'Host': host,
        }
        params = {
            'method': 'PUT',
            'access_token': access_token,
        }

        response = requests.post(
            resource_url,
            data=json.dumps(data, cls=DateTimeEncoder),
            headers=headers,
            params=params
        )

        try:
            resource = response.json()
        except ValueError:
            raise APIException('The API has returned invalid json: %s' % response.content, 500)

        if resource['error']:
            raise APIException(resource['error'], response.status_code)

        if not resource['data']:
            raise APIException('No data returned at: %s' % resource_url)

        return resource['data']
Exemplo n.º 16
0
    def update(cls, host, data, id, access_token):
        """
        Update an API resource with PUT.
        """

        id = int(id)
        assert id > 0, 'Resource ID must be greater than zero'
        path_fragments = [cls.resource_fragment, id]
        resource_url = build_url(host, path_fragments)

        headers = {
            'Content-Type': 'application/json',
            'Host': host,
        }
        params = {
            'method': 'PUT',
            'access_token': access_token,
        }

        response = requests.post(resource_url,
                                 data=json.dumps(data, cls=DateTimeEncoder),
                                 headers=headers,
                                 params=params)

        try:
            resource = response.json()
        except ValueError:
            raise APIException(
                'The API has returned invalid json: %s' % response.content,
                500)

        if resource['error']:
            raise APIException(resource['error'], response.status_code)

        if not resource['data']:
            raise APIException('No data returned at: %s' % resource_url)

        return resource['data']
Exemplo n.º 17
0
    def login(request):
        """
        Log a user in. Creates an access_token using a persona
        assertion and the client secret. Sets this access token as a cookie.
        'target_url' based as a GET parameter determines where the user is
        redirected.
        """

        target_url = request.POST.get('target_url')
        assertion = request.POST.get('Assertion')
        client_secret = settings.CLIENT_SECRET

        data = {
            "Assertion": assertion,
            "ClientSecret": client_secret
        }
        headers= {'Host': request.META.get('HTTP_HOST')}

        access_token = requests.post(build_url(request.META['HTTP_HOST'], ['auth']), data=data, headers=headers).json()['data']

        response = HttpResponseRedirect(target_url if target_url != '' else '/')
        response.set_cookie('access_token', access_token, httponly=True)
        return response
Exemplo n.º 18
0
    def logout(request):
        """
        Log a user out. Issues a DELETE request to the backend for the
        user's access_token, and issues a delete cookie header in response to
        clear the user's access_token cookie.
        """

        view_data = {
            'site': request.site,
        }

        response = render(request, 'logout.html', view_data)

        if request.COOKIES.has_key('access_token'):
            response.delete_cookie('access_token')
            url = build_url(request.META['HTTP_HOST'],
                            ['auth', request.access_token])
            requests.post(url,
                          params={
                              'method': 'DELETE',
                              'access_token': request.access_token
                          })

        return response
Exemplo n.º 19
0
    def login(request):
        """
        Log a user in. Creates an access_token using a persona
        assertion and the client secret. Sets this access token as a cookie.
        'target_url' based as a GET parameter determines where the user is
        redirected.
        """

        target_url = request.POST.get('target_url')
        assertion = request.POST.get('Assertion')
        client_secret = settings.CLIENT_SECRET

        data = {"Assertion": assertion, "ClientSecret": client_secret}
        headers = {'Host': request.META.get('HTTP_HOST')}

        access_token = requests.post(build_url(request.META['HTTP_HOST'],
                                               ['auth']),
                                     data=data,
                                     headers=headers).json()['data']

        response = HttpResponseRedirect(
            target_url if target_url != '' else '/')
        response.set_cookie('access_token', access_token, httponly=True)
        return response
Exemplo n.º 20
0
    def delete(cls, host, id, access_token):
        """
        DELETE an API resource. ID must be supplied.

        A 'data' object is never returned by a DELETE, so this
        method will raise an exception on failure. In normal
        operation the method simply returns.
        """

        path_fragments = [cls.resource_fragment]

        if id:
            id = int(id)
            assert id > 0, 'Resource ID must be greater than zero'
            path_fragments.append(id)
        elif access_token:
            path_fragments.append(access_token)
        else:
            raise AssertionError, 'You must supply either an id or '\
                                  'an access_token to delete'

        resource_url = build_url(host, path_fragments)
        params = {
            'method': 'DELETE',
            'access_token': access_token,
        }
        headers = {'Host': host}
        response = requests.post(resource_url, params=params, headers=headers)

        try:
            resource = response.json()
        except ValueError:
            raise APIException('The API has returned invalid json: %s' % response.content, 500)

        if resource['error']:
            raise APIException(resource['error'], response.status_code)
Exemplo n.º 21
0
    def create(cls, host, data, access_token, headers=None):
        """
        Create an API resource with POST.
        """

        resource_url = build_url(host, [cls.resource_fragment])
        params = {'access_token': access_token}

        if headers:
            headers['Content-Type'] = 'application/json'
            headers['Host'] = host
        else:
            headers = {
                'Content-Type': 'application/json',
                'Host': host
            }

        response = requests.post(
            resource_url,
            data=json.dumps(data, cls=DateTimeEncoder),
            headers=headers,
            params=params
        )

        try:
            resource = response.json()
        except ValueError:
            raise APIException('The API has returned invalid json: %s' % response.content, 500)

        if resource['error']:
            raise APIException(resource['error'], response.status_code)

        if not resource['data']:
            raise APIException('No data returned at: %s' % resource_url)

        return resource['data']
Exemplo n.º 22
0
 def testFailCustomDomains(self):
     with self.assertRaises(AssertionError):
         build_url('a.example.org', ['resource', '1', 'ex/tra'])
Exemplo n.º 23
0
 def testInvalidFragment(self):
     with self.assertRaises(AssertionError):
         build_url('a.microco.sm', ['resource', '1', 'ex/tra'])
Exemplo n.º 24
0
 def testIntFragment(self):
     url = build_url('a.microco.sm', [1, 2, 3])
     assert url == 'https://a.microco.sm/api/v1/1/2/3'
Exemplo n.º 25
0
 def testEmptyFragments(self):
     url = build_url('a.microco.sm', [])
     assert url == 'https://a.microco.sm/api/v1'
Exemplo n.º 26
0
 def testWithNoSeparator(self):
     url = build_url('a.microco.sm', ['resource', '1', 'extra'])
     assert url == 'https://a.microco.sm/api/v1/resource/1/extra'
Exemplo n.º 27
0
 def testWithDuplicateSeparator(self):
     url = build_url('a.microco.sm', ['resource/', '/1/', '/extra/'])
     assert url == 'https://a.microco.sm/api/v1/resource/1/extra'
Exemplo n.º 28
0
 def testWithPrependedSeparator(self):
     url = build_url('a.microco.sm', ['/resource', '/1', '/extra'])
     assert url == 'https://a.microco.sm/api/v1/resource/1/extra'