Giter Club home page Giter Club logo

Comments (7)

cavemanpi avatar cavemanpi commented on June 16, 2024 1

Hello!

The output of get_authentication_log when using api_version=2 contains two top level keys,authlogs and metadata. The next_offset key in metadata contains a list. If there are no subsequent pages, next_offset should contain something falsey. If there are subsequent pages, the first element is an epoch timestamp and the second is the event id.

When retrieving a page after the initial request, you should be able to just take next_offset contained in the first response and plug that into the next_offset argument of the next get_authentication_log call.

This is untested, but I think it would look something like:

...
authlogs = []
res = client.get_authentication_log(mintime=mintime, maxtime=maxtime, api_version=2)
authlogs.extend(res['authlogs'])
next_offset = res['metadata'].get('next_offset')
while next_offset:
    res = client.get_authentication_log(
        mintime=mintime,
        maxtime=maxtime,
        api_version=2,
        next_offset=next_offset
    )
    authlogs.extend(res['authlogs'])
    next_offset = res['metadata'].get('next_offset')

I hope this helps. Please let me know if this doesn't answer your question.

from duo_client_python.

guitarhero23 avatar guitarhero23 commented on June 16, 2024

I was able to use your example as a reference to get it working thanks. I didn't quite need it all for my use case but your next_offset line made it click for me.

`logs = admin_api.get_authentication_log(api_version=api_version, limit=limit, mintime=mintime, sort=sort)

next_offset = logs['metadata'].get('next_offset')

{Stuff gets done here to the logs}

logs = admin_api.get_authentication_log(api_version=api_version, limit=limit, mintime=mintime, sort=sort,next_offset=next_offset
{More Stuff}`

from duo_client_python.

arahej avatar arahej commented on June 16, 2024

@guitarhero23 @cavemanpi
I am also trying to get data from authentication API but stuck in next_offset part.

Here is my code:-

import base64, email, hmac, hashlib, urllib
import requests
import pprint

class Raheja:

    def sign(self, method, host, path, params, skey, ikey):
        """
        Return HTTP Basic Authentication ("Authorization" and "Date") headers.
        method, host, path: strings from request
        params: dict of request parameters
        skey: secret key
        ikey: integration key
        """
        # create canonical string
        now = email.Utils.formatdate()
        canon = [now, method.upper(), host.lower(), path]
        args = []
        for key in sorted(params.keys()):
            val = params[key]
            if isinstance(val, unicode):
                val = val.encode("utf-8")
            args.append(
                '%s=%s' % (urllib.quote(key, '~'), urllib.quote(val, '~')))
        canon.append('&'.join(args))
        canon = '\n'.join(canon)

        # sign canonical string
        sig = hmac.new(skey, canon, hashlib.sha1)
        auth = '%s:%s' % (ikey, sig.hexdigest())
        print auth

        # return headers
        headers = {'Date': now, 'Authorization': 'Basic %s' % base64.b64encode(auth)}
        return headers

    def get_data(self, headers):
        next_offset = []
        while next_offset is not None:
            url = "https://xxxxx.duosecurity.com/admin/v2/logs/authentication"

            querystring = {'mintime': '1614067200000', 'maxtime': '1614070800000', 'limit': '1000',
                           'next_offset': next_offset}

            headers = {
                'Authorization': headers.get('Authorization'),
                'Content-Type': "application/x-www-form-urlencoded",
                'Date': headers.get('Date'),
            }

            response = requests.request("GET", url, headers=headers, params=querystring)
            response_json = response.json()
            print response_json
            response = response_json.get('response')
            metadata = response.get('metadata')
            next_offset = metadata.get('next_offset')
            print next_offset

 r = Raheja()
headers = r.sign('GET', 'xxxxx.duosecurity.com', '/admin/v2/logs/authentication',
                 {'mintime': '1614067200000', 'maxtime': '1614070800000', 'limit': '1000'},
                 'xxx', 'xxxx')
data = r.get_data(headers)

I am able to get the response from when I did the first API call. But for the second I am trying to pass the offset from my above code but getting as :

{u'message': u'Invalid signature in request credentials', u'code': 40103, u'stat': u'FAIL'}

Please need help here. Thanks

from duo_client_python.

cavemanpi avatar cavemanpi commented on June 16, 2024

Hey @arahej,

There's a method in the client you should probably use instead of your hand rolled retrieval. The method name is get_authentication_log. Is there a reason you aren't using the client module?

I'm pretty sure you need to sign every request, especially when you change the parameters. The signature is derived from secrets as well as the parameters in the request. When you change the next_offset parameter, the signature will be different.

from duo_client_python.

arahej avatar arahej commented on June 16, 2024

@cavemanpi
Thanks for the inputs.
Can you share with me the link to the get_authentication_log method?

Also, I need to call the sign method again if I change my next_offset right?
and the data type of next_offset is a list or a string?.

Thanks

from duo_client_python.

cavemanpi avatar cavemanpi commented on June 16, 2024

@arahej The method you are looking for is in this repo. If your intent is to implement all the logic needed to run your requests, you will have implemented the client in this repo. I strongly suggest using this client in your project.

Here's the method in the client:

def get_authentication_log(self, api_version=1, **kwargs):

from duo_client_python.

cavemanpi avatar cavemanpi commented on June 16, 2024

Yes, you will need to sign your request each time you change parameters. Ideally also every time you make a call the the api endpoint, it should be signed. If you use the client libarary, you don't have to worry about signing the request correctly; it's built into the client.

On logging endpoints next_offset is a list.

from duo_client_python.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.