コード例 #1
0
ファイル: auth.py プロジェクト: xbryanc/commcare-hq
    def testRepeatedFailedLogin(self):
        from auditcare.decorators import login
        login.FAILURE_LIMIT = 3
        login.LOCK_OUT_AT_FAILURE=True
        login.COOLOFF_TIME = timedelta(seconds=4)

        start_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
        response = self.client.post(reverse('auth_login'), {'username': '******', 'password': '******'})

        firstlogin_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
        self.assertEquals(start_count+1, firstlogin_count)


        first_audit = get_latest_access(['user', '*****@*****.**'])
        self.assertEquals(first_audit.access_type, models.ACCESS_FAILED)
        self.assertEquals(first_audit.failures_since_start, 1)
        start_failures = first_audit.failures_since_start

        for n in range(1, 3):
            #we are logging in within the cooloff period, so let's check to see if it doesn't increment.
            response = self.client.post(reverse('auth_login'), {'username': '******', 'password': '******'})
            next_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
            self.assertEquals(firstlogin_count, next_count)

            next_audit = get_latest_access(['user', '*****@*****.**'])
            self.assertEquals(next_audit.access_type, models.ACCESS_FAILED)
            self.assertEquals(next_audit.failures_since_start, n+start_failures)
            time.sleep(1)
        time.sleep(3)
        response = self.client.post(reverse('auth_login'), {'username': '******', 'password': '******'})
        cooled_audit = get_latest_access(['user', '*****@*****.**'])
        self.assertEquals(cooled_audit.failures_since_start, 1)
コード例 #2
0
ファイル: auth.py プロジェクト: dimagi/auditcare
    def testRepeatedFailedLogin(self):
        from auditcare.decorators import login
        login.FAILURE_LIMIT = 3
        login.LOCK_OUT_AT_FAILURE=True
        login.COOLOFF_TIME = timedelta(seconds=4)

        start_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
        response = self.client.post(reverse('auth_login'), {'username': '******', 'password': '******'})

        firstlogin_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
        self.assertEquals(start_count+1, firstlogin_count)


        first_audit = get_latest_access(['user', '*****@*****.**'])
        self.assertEquals(first_audit.access_type, models.ACCESS_FAILED)
        self.assertEquals(first_audit.failures_since_start, 1)
        start_failures = first_audit.failures_since_start

        for n in range(1,3):
            #we are logging in within the cooloff period, so let's check to see if it doesn't increment.
            response = self.client.post(reverse('auth_login'), {'username': '******', 'password': '******'})
            next_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
            self.assertEquals(firstlogin_count, next_count)

            next_audit = get_latest_access(['user', '*****@*****.**'])
            self.assertEquals(next_audit.access_type, models.ACCESS_FAILED)
            self.assertEquals(next_audit.failures_since_start, n+start_failures)
            time.sleep(1)
        time.sleep(3)
        response = self.client.post(reverse('auth_login'), {'username': '******', 'password': '******'})
        cooled_audit = get_latest_access(['user', '*****@*****.**'])
        self.assertEquals(cooled_audit.failures_since_start,1)
コード例 #3
0
ファイル: auth.py プロジェクト: xbryanc/commcare-hq
    def testLogin(self):

        #login
        start_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
        response = self.client.post(reverse('auth_login'), {'username': '******', 'password': '******'})
        login_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
        self.assertEqual(start_count+1, login_count)

        latest_audit = get_latest_access(['user', '*****@*****.**'])
        self.assertEquals(latest_audit.access_type, models.ACCESS_LOGIN)
コード例 #4
0
ファイル: auth.py プロジェクト: dimagi/auditcare
    def testLogin(self):

        #login
        start_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
        response = self.client.post(reverse('auth_login'), {'username': '******', 'password': '******'})
        login_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
        self.assertEqual(start_count+1, login_count)

        latest_audit = get_latest_access(['user', '*****@*****.**'])
        self.assertEquals(latest_audit.access_type, models.ACCESS_LOGIN)
コード例 #5
0
ファイル: auth.py プロジェクト: dimagi/auditcare
    def testSingleFailedLogin(self):
        start_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
        response = self.client.post(reverse('auth_login'), {'username': '******', 'password': '******'})

        login_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
        self.assertEquals(start_count+1, login_count)
        #got the basic count, now let's inspect this value to see what kind of result it is.

        latest_audit = get_latest_access(['user', '*****@*****.**'])
        self.assertEquals(latest_audit.access_type, models.ACCESS_FAILED)
        self.assertEquals(latest_audit.failures_since_start, 1)
コード例 #6
0
ファイル: auth.py プロジェクト: xbryanc/commcare-hq
    def testSingleFailedLogin(self):
        start_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
        response = self.client.post(reverse('auth_login'), {'username': '******', 'password': '******'})

        login_count = AccessAudit.view('auditcare/login_events', key=['user', '*****@*****.**']).count()
        self.assertEquals(start_count+1, login_count)
        #got the basic count, now let's inspect this value to see what kind of result it is.

        latest_audit = get_latest_access(['user', '*****@*****.**'])
        self.assertEquals(latest_audit.access_type, models.ACCESS_FAILED)
        self.assertEquals(latest_audit.failures_since_start, 1)
コード例 #7
0
def get_user_attempt(request):
    """
    Returns access attempt record if it exists.
    Otherwise return None.
    """
    ip = request.META.get('REMOTE_ADDR', '')
    if USE_USER_AGENT:
        ua = request.META.get('HTTP_USER_AGENT', '<unknown>')

        attempts = AccessAudit.view('auditcare/login_events',
                                    key=['ip_ua', ip, ua],
                                    include_docs=True,
                                    limit=25).all()

        #attempts = AccessAttempt.objects.filter( user_agent=ua, ip_address=ip )
    else:
        attempts = AccessAudit.view('auditcare/login_events',
                                    key=['ip', ip],
                                    include_docs=True,
                                    limit=25).all()
        #attempts = AccessAttempt.objects.filter( ip_address=ip )

    attempts = sorted(attempts, key=lambda x: x.event_date, reverse=True)
    if not attempts:
        log.info("No attempts for given access, creating new attempt")
        return None

    #walk the attempts
    attempt = None
    for at in attempts:
        if at.access_type == models.ACCESS_FAILED:
            attempt = at
            break
        elif at.access_type == models.ACCESS_LOGIN:
            attempt = None
            break
        elif at.access_type == models.ACCESS_LOGOUT:
            attempt = None
            break

    if COOLOFF_TIME and attempt and datetime.utcnow(
    ) - attempt.event_date < COOLOFF_TIME:
        log.info(
            "Last login failure is still within the cooloff time, incrementing last access attempt."
        )
    else:
        log.info(
            "Last login failure is outside the cooloff time, creating new access attempt."
        )
        return None
    return attempt
コード例 #8
0
ファイル: views.py プロジェクト: andile2012/logistics
def auditor(request, template="ewsghana/auditor.html"):
    auditEvents = AccessAudit.view("auditcare/by_date_access_events", descending=True, include_docs=True).all()
    realEvents = []
    for a in auditEvents:
        designation = organization = facility = location = first_name = last_name = ''
        try:
            user = User.objects.get(username=a.user)
        except User.DoesNotExist:
            # OK - anonymous user
            pass
        else:
            first_name = user.first_name
            last_name = user.last_name
            try:
                profile = user.get_profile()
            except LogisticsProfile.DoesNotExist:
                profile = None
            else:
                designation = profile.designation if profile.designation else '' 
                organization = profile.organization if profile.organization else ''
                facility = profile.supply_point if profile.supply_point else ''
                location = profile.location if profile.location else ''
        realEvents.append({'user': a.user, 
                           'date': a.event_date, 
                           'class': a.doc_type, 
                           'access_type': a.access_type, 
                           'first_name': first_name,
                           'last_name': last_name,
                           'designation': designation, 
                           'organization': organization, 
                           'facility': facility, 
                           'location': location })
    return render_to_response(template, 
                              {"audit_table": AuditLogTable(realEvents, request=request)}, 
                              context_instance=RequestContext(request))
コード例 #9
0
ファイル: views.py プロジェクト: dimagi/auditcare
def audited_views(request, *args, **kwargs):
    db = AccessAudit.get_db()
    views = db.view('auditcare/urlpath_by_user_date', reduce=False).all()
    template = "auditcare/audit_views.html"
    return render_to_response(template,
            {"audit_views": views},
        context_instance=RequestContext(request))
コード例 #10
0
def audited_views(request, *args, **kwargs):
    db = AccessAudit.get_db()
    views = db.view('auditcare/urlpath_by_user_date', reduce=False).all()
    template = "auditcare/audit_views.html"
    return render_to_response(template,
            {"audit_views": views},
        context_instance=RequestContext(request))
コード例 #11
0
ファイル: testutils.py プロジェクト: ye-man/commcare-hq
def get_latest_access(key):
    access_events = AccessAudit.view('auditcare/login_events',
                                     key=key,
                                     include_docs=True).all()
    access_events = sorted(access_events,
                           key=lambda x: x.event_date,
                           reverse=True)
    return access_events[0]
コード例 #12
0
ファイル: views.py プロジェクト: dimagi/auditcare
def single_model_history(request, model_name, *args, **kwargs):
    # it's for a particular model
    context=RequestContext(request)
    db = AccessAudit.get_db()
    vals = db.view('auditcare/model_actions_by_id', group=True, startkey=[model_name,u''], endkey=[model_name,u'z']).all()
    model_dict= dict((x['key'][1], x['value']) for x in vals)
    context['instances_dict']=model_dict
    context['model'] = model_name
    return render_to_response('auditcare/single_model_changes.html', context)
コード例 #13
0
ファイル: views.py プロジェクト: dimagi/auditcare
def auditAll(request, template="auditcare/index.html"):
    auditEvents = AccessAudit.view("auditcare/by_date_access_events", descending=True, include_docs=True).all()
    realEvents = [{'user': a.user, 
                   'date': a.event_date, 
                   'class': a.doc_type, 
                   'access_type': a.access_type } for a in auditEvents]
    return render_to_response(template, 
                              {"audit_table": AuditLogTable(realEvents, request=request)}, 
                              context_instance=RequestContext(request))
コード例 #14
0
def export_all(request):
    auditEvents = AccessAudit.view("auditcare/by_date_access_events", descending=True, include_docs=True).all()
    response = HttpResponse()
    response['Content-Disposition'] = 'attachment; filename="AuditAll.xls"'
    writer = csv.UnicodeWriter(response)
    writer.writerow(['User', 'Access Type', 'Date'])
    for a in auditEvents:
        writer.writerow([a.user, a.access_type, a.event_date])
    return response
コード例 #15
0
ファイル: views.py プロジェクト: dimagi/auditcare
def export_all(request):
    auditEvents = AccessAudit.view("auditcare/by_date_access_events", descending=True, include_docs=True).all()
    response = HttpResponse()
    response['Content-Disposition'] = 'attachment; filename="AuditAll.xls"'
    writer = csv.UnicodeWriter(response)
    writer.writerow(['User', 'Access Type', 'Date'])
    for a in auditEvents:
        writer.writerow([a.user, a.access_type, a.event_date])
    return response
コード例 #16
0
def single_model_history(request, model_name, *args, **kwargs):
    # it's for a particular model
    context=RequestContext(request)
    db = AccessAudit.get_db()
    vals = db.view('auditcare/model_actions_by_id', group=True, startkey=[model_name,u''], endkey=[model_name,u'z']).all()
    model_dict= dict((x['key'][1], x['value']) for x in vals)
    context['instances_dict']=model_dict
    context['model'] = model_name
    return render_to_response('auditcare/single_model_changes.html', context)
コード例 #17
0
def model_histories(request, *args, **kwargs):
    """
    Looks at all the audit model histories and shows for a given model
    """
    db = AccessAudit.get_db()
    vals = db.view('auditcare/model_actions_by_id', group=True, group_level=1).all()
    # do a dict comprehension here because we know all the keys in this reduce are unique
    model_dict = dict((x['value'][0], x['value']) for x in vals)
    context = {'model_dict': model_dict}
    return render(request, 'auditcare/model_changes.html', context)
コード例 #18
0
def get_user_attempt(request):
    """
    Returns access attempt record if it exists.
    Otherwise return None.
    """
    ip = request.META.get('REMOTE_ADDR', '')
    if USE_USER_AGENT:
        ua = request.META.get('HTTP_USER_AGENT', '<unknown>')

        attempts = AccessAudit.view('auditcare/login_events', key=['ip_ua',ip, ua], include_docs=True, limit=25).all()

        #attempts = AccessAttempt.objects.filter( user_agent=ua, ip_address=ip )
    else:
        attempts = AccessAudit.view('auditcare/login_events',key=['ip', ip], include_docs=True, limit=25).all()
        #attempts = AccessAttempt.objects.filter( ip_address=ip )

    attempts = sorted(attempts, key=lambda x: x.event_date, reverse=True)
    if not attempts:
        log.info("No attempts for given access, creating new attempt")
        return None

    #walk the attempts
    attempt = None
    for at in attempts:
        if at.access_type == models.ACCESS_FAILED:
            attempt = at
            break
        elif at.access_type == models.ACCESS_LOGIN:
            attempt = None
            break
        elif at.access_type == models.ACCESS_LOGOUT:
            attempt = None
            break



    if COOLOFF_TIME and attempt and datetime.utcnow() - attempt.event_date < COOLOFF_TIME:
        log.info("Last login failure is still within the cooloff time, incrementing last access attempt.")
    else:
        log.info("Last login failure is outside the cooloff time, creating new access attempt.")
        return None
    return attempt
コード例 #19
0
ファイル: views.py プロジェクト: dimagi/auditcare
def model_instance_history(request, model_name, model_uuid, *args, **kwargs):
    # it's for a particular model
    context=RequestContext(request)
    db = AccessAudit.get_db()

    if ContentType.objects.filter(name=model_name).count() == 0:
        # it's couchdbkit
        obj = db.get(model_uuid)
    else:
        obj = ContentType.objects.filter(name=model_name)[0].model_class().objects.get(id=model_uuid)

    context['change_history'] = history_for_doc(obj)
    context['model'] = model_name
    context['model_uuid'] = model_uuid
    return render_to_response('auditcare/model_instance_history.html', context)
コード例 #20
0
def model_instance_history(request, model_name, model_uuid, *args, **kwargs):
    # it's for a particular model
    context=RequestContext(request)
    db = AccessAudit.get_db()

    if ContentType.objects.filter(name=model_name).count() == 0:
        # it's couchdbkit
        obj = db.get(model_uuid)
    else:
        obj = ContentType.objects.filter(name=model_name)[0].model_class().objects.get(id=model_uuid)

    context['change_history'] = history_for_doc(obj)
    context['model'] = model_name
    context['model_uuid'] = model_uuid
    return render_to_response('auditcare/model_instance_history.html', context)
コード例 #21
0
ファイル: views.py プロジェクト: unicefuganda/auditcare
def model_instance_history(request, model_name, model_uuid, *args, **kwargs):
    #it's for a particular model
    context=RequestContext(request)
    db = AccessAudit.get_db()
    changes=db.view('auditcare/model_actions_by_id', reduce=False, key=[model_name, model_uuid], include_docs=True).all()
    #context['changes']= sorted([(x['doc']['_id'], x['doc']) for x in changes], key=lambda y: y[1]['event_date'], reverse=True)

    if ContentType.objects.filter(name=model_name).count() == 0:
        #it's couchdbkit
        obj = db.get(model_uuid)
    else:
        obj = ContentType.objects.filter(name=model_name)[0].model_class().objects.get(id=model_uuid)

    context['change_history'] = history_for_doc(obj)
    context['model'] = model_name
    context['model_uuid'] = model_uuid
    return render_to_response('auditcare/model_instance_history.html', context)
コード例 #22
0
def auditor(request, template="ewsghana/auditor.html"):
    auditEvents = AccessAudit.view("auditcare/by_date_access_events",
                                   descending=True,
                                   include_docs=True).all()
    realEvents = []
    for a in auditEvents:
        designation = organization = facility = location = first_name = last_name = ''
        try:
            user = User.objects.get(username=a.user)
        except User.DoesNotExist:
            # OK - anonymous user
            pass
        else:
            first_name = user.first_name
            last_name = user.last_name
            try:
                profile = user.get_profile()
            except LogisticsProfile.DoesNotExist:
                profile = None
            else:
                designation = profile.designation if profile.designation else ''
                organization = profile.organization if profile.organization else ''
                facility = profile.supply_point if profile.supply_point else ''
                location = profile.location if profile.location else ''
        realEvents.append({
            'user': a.user,
            'date': a.event_date,
            'class': a.doc_type,
            'access_type': a.access_type,
            'first_name': first_name,
            'last_name': last_name,
            'designation': designation,
            'organization': organization,
            'facility': facility,
            'location': location
        })
    return render_to_response(
        template, {"audit_table": AuditLogTable(realEvents, request=request)},
        context_instance=RequestContext(request))
コード例 #23
0
def audited_logout(request, *args, **kwargs):
    # share some useful information
    func = auth_views.logout
    logging.info("Function: %s" % (func.__name__))
    logging.info("Logged logout for user %s" % (request.user.username))
    user = request.user
    # it's a successful login.
    ip = request.META.get('REMOTE_ADDR', '')
    ua = request.META.get('HTTP_USER_AGENT', '<unknown>')
    attempt = AccessAudit()
    attempt.doc_type = AccessAudit.__name__
    attempt.access_type = models.ACCESS_LOGOUT
    attempt.user_agent = ua
    attempt.user = user.username
    attempt.session_key = request.session.session_key
    attempt.ip_address = ip
    attempt.get_data = []
    attempt.post_data = []
    attempt.http_accept = request.META.get('HTTP_ACCEPT', '<unknown>')
    attempt.path_info = request.META.get('PATH_INFO', '<unknown>')
    attempt.failures_since_start = 0
    attempt.save()

    # call the logout function
    response = func(request, *args, **kwargs)
    return response
コード例 #24
0
def log_request(request, login_unsuccessful):
    failures = 0
    attempt = get_user_attempt(request)

    if attempt:
        failures = attempt.failures_since_start

    # no matter what, we want to lock them out
    # if they're past the number of attempts allowed
    if failures > FAILURE_LIMIT and LOCK_OUT_AT_FAILURE:
        # We log them out in case they actually managed to enter
        # the correct password.
        logout(request)
        log.warning('AXES: locked out %s after repeated login attempts.',
                    attempt.ip_address)
        return False

    if login_unsuccessful:
        #interpret the auth form to get the user in question
        if request.method == "POST":
            form = AuthenticationForm(data=request.POST)
            if form.is_valid():
                attempted_username = form.get_user().username
            else:
                attempted_username = form.data.get('username')
                attempted_password = form.data.get('password')

        # add a failed attempt for this user
        failures += 1

        # Create an AccessAttempt record if the login wasn't successful
        # has already attempted, update the info
        if attempt:
            #attempt.get_data.append(query2str(request.GET.items()))
            #attempt.post_data.append(query2str(request.POST.items()))
            attempt.access_type = models.ACCESS_FAILED
            attempt.user = attempted_username
            attempt.http_accept = request.META.get('HTTP_ACCEPT', '<unknown>')
            attempt.path_info = request.META.get('PATH_INFO', '<unknown>')
            attempt.failures_since_start = failures
            attempt.event_date = datetime.utcnow()  #why do we do this?
            attempt.save()
            log.info(
                'AXES: Repeated login failure by %s. Updating access '
                'record. Count = %s', attempt.ip_address, failures)
        else:
            ip = request.META.get('REMOTE_ADDR', '')
            ua = request.META.get('HTTP_USER_AGENT', '<unknown>')
            attempt = AccessAudit()
            attempt.event_date = datetime.utcnow()
            attempt.doc_type = AccessAudit.__name__
            attempt.access_type = models.ACCESS_FAILED
            attempt.user_agent = ua
            attempt.user = attempted_username
            attempt.ip_address = ip
            #attempt.get_data = [query2str(request.GET.items())]
            #attempt.post_data= [query2str(request.POST.items())]
            attempt.http_accept = request.META.get('HTTP_ACCEPT', '<unknown>')
            attempt.path_info = request.META.get('PATH_INFO', '<unknown>')
            attempt.failures_since_start = failures
            attempt.save()
            log.info('AXES: New login failure by %s. Creating access record.',
                     ip)

    return True
コード例 #25
0
def audited_views(request, *args, **kwargs):
    db = AccessAudit.get_db()
    views = db.view('auditcare/urlpath_by_user_date', reduce=False).all()
    template = "auditcare/audit_views.html"
    context = {"audit_views": views}
    return render(request, template, context)
コード例 #26
0
    def handle(self, **options):
        recompute = options['recompute']
        print recompute
        db = AccessAudit.get_db()
        vals = db.view('auditcare/model_actions_by_id',
                       group=True,
                       group_level=1).all()

        #get all model types
        #python 2.7 dict comprehension
        #model_dict= {x['key'][0]: x['value'] for x in vals}
        model_dict = dict((x['key'][0], x['value']) for x in vals)

        for model, count in model_dict.items():
            #for each model type, query ALL audit instances.
            print "### %s" % (model)
            model_counts = db.view('auditcare/model_actions_by_id',
                                   group=True,
                                   startkey=[model, u''],
                                   endkey=[model, u'z']).all()
            #within a given model, query ALL instances

            #sort the models by id, then by rev descending
            #{u'value': <num>, u'key': [u'model', u'uuid']}
            for mc in model_counts:
                num = mc['value']
                model_uuid = mc['key'][1]
                #now for each model uuid, do a query again to get all the rev numbers
                item_revs = db.view('auditcare/model_actions_by_id',
                                    reduce=False,
                                    startkey=[model, model_uuid],
                                    endkey=[model, model_uuid]).all()
                revs = sorted([(x['id'], x['value']) for x in item_revs],
                              key=lambda y: y[1],
                              reverse=True)
                #tuples of (audit_id, rev_id)
                #print "%s:%s -> %s" % (model, model_uuid, revs)

                #ok, for each arr of revs, if it's length greater than 1, then do it
                #we're going backwards, so...yeah
                if len(revs) > 1:
                    for i, t in enumerate(revs):
                        audit_id = t[0]
                        current = ModelActionAudit.get(audit_id)

                        if i + 1 == len(revs):
                            current.prev_id = None
                            current.save()
                            break

                        prev_audit_id = revs[i + 1][0]
                        prev_rev = ModelActionAudit.get(prev_audit_id)

                        if i == 0:
                            current.next_id = None

                        if current.prev_id != prev_rev._id:
                            current.prev_id = prev_rev._id
                            #current saves later
                        if prev_rev.next_id != current._id:
                            prev_rev.next_id = current._id
                            prev_rev.save()

#                        #sanity check
#                        if prev_rev.revision_checksum == current.revision_checksum:
#                            continue
#
#                        if (current.archived_data.get('doc_type', None) =='XFormInstance' and prev_rev.archived_data.get('doc_type', None) == 'XFormInstance'):
#                            #it's an xforminstance
#                            removed, added, changed = utils.dict_diff(current.archived_data['form'], prev_rev.archived_data['form'])
#                        else:
#                            removed, added, changed = utils.dict_diff(current.archived_data, prev_rev.archived_data)
#                        current.removed = removed
#                        current.added = added
#                        current.changed = changed
#                        current.save()
                        current.compute_changes(save=True)
コード例 #27
0
ファイル: compute_diffs.py プロジェクト: dimagi/auditcare
    def handle(self, **options):
        recompute = options['recompute']
        print recompute
        db = AccessAudit.get_db()
        vals = db.view('auditcare/model_actions_by_id', group=True, group_level=1).all()

        #get all model types
        #python 2.7 dict comprehension
        #model_dict= {x['key'][0]: x['value'] for x in vals}
        model_dict= dict((x['key'][0], x['value']) for x in vals)

        for model, count in model_dict.items():
            #for each model type, query ALL audit instances.
            print "### %s" % (model)
            model_counts = db.view('auditcare/model_actions_by_id', group=True, startkey=[model,u''], endkey=[model,u'z']).all()
            #within a given model, query ALL instances

            #sort the models by id, then by rev descending
            #{u'value': <num>, u'key': [u'model', u'uuid']}
            for mc in model_counts:
                num = mc['value']
                model_uuid = mc['key'][1]
                #now for each model uuid, do a query again to get all the rev numbers
                item_revs = db.view('auditcare/model_actions_by_id', reduce=False, startkey=[model,model_uuid], endkey=[model,model_uuid]).all()
                revs = sorted([(x['id'], x['value']) for x in item_revs], key=lambda y: y[1], reverse=True)
                #tuples of (audit_id, rev_id)
                #print "%s:%s -> %s" % (model, model_uuid, revs)


                #ok, for each arr of revs, if it's length greater than 1, then do it
                #we're going backwards, so...yeah
                if len(revs) > 1:
                    for i, t in enumerate(revs):
                        audit_id = t[0]
                        current = ModelActionAudit.get(audit_id)

                        if i+1 == len(revs):
                            current.prev_id = None
                            current.save()
                            break

                        prev_audit_id = revs[i+1][0]
                        prev_rev = ModelActionAudit.get(prev_audit_id)

                        if i == 0:
                            current.next_id = None

                        if current.prev_id != prev_rev._id:
                            current.prev_id = prev_rev._id
                            #current saves later
                        if prev_rev.next_id != current._id:
                            prev_rev.next_id = current._id
                            prev_rev.save()

#                        #sanity check
#                        if prev_rev.revision_checksum == current.revision_checksum:
#                            continue
#
#                        if (current.archived_data.get('doc_type', None) =='XFormInstance' and prev_rev.archived_data.get('doc_type', None) == 'XFormInstance'):
#                            #it's an xforminstance
#                            removed, added, changed = utils.dict_diff(current.archived_data['form'], prev_rev.archived_data['form'])
#                        else:
#                            removed, added, changed = utils.dict_diff(current.archived_data, prev_rev.archived_data)
#                        current.removed = removed
#                        current.added = added
#                        current.changed = changed
#                        current.save()
                        current.compute_changes(save=True)
コード例 #28
0
    def decorated_logout (request, *args, **kwargs):
        # share some useful information
        if func.__name__ != 'decorated_logout' and VERBOSE:
            log.info('AXES: Calling decorated logout function: %s', func.__name__)
            if args: log.info('args: %s', args)
            if kwargs: log.info('kwargs: %s', kwargs)
        log.info("Function: %s", func.__name__)
        log.info("Logged logout for user %s", request.user.username)
        user = request.user
        #it's a successful login.
        ip = request.META.get('REMOTE_ADDR', '')
        ua = request.META.get('HTTP_USER_AGENT', '<unknown>')
        attempt = AccessAudit()
        attempt.doc_type=AccessAudit.__name__
        attempt.access_type = models.ACCESS_LOGOUT
        attempt.user_agent=ua
        attempt.user = user.username
        attempt.session_key = request.session.session_key
        attempt.ip_address=ip
        attempt.get_data=[] #[query2str(request.GET.items())]
        attempt.post_data=[]
        attempt.http_accept=request.META.get('HTTP_ACCEPT', '<unknown>')
        attempt.path_info=request.META.get('PATH_INFO', '<unknown>')
        attempt.failures_since_start=0
        attempt.save()

        # call the logout function
        response = func(request, *args, **kwargs)

        if func.__name__ == 'decorated_logout':
            # if we're dealing with this function itself, don't bother checking
            # for invalid login attempts.  I suppose there's a bunch of
            # recursion going on here that used to cause one failed login
            # attempt to generate 10+ failed access attempt records (with 3
            # failed attempts each supposedly)
            return response
        return response
コード例 #29
0
def log_request(request, login_unsuccessful):
    failures = 0
    attempt = get_user_attempt(request)

    if attempt:
        failures = attempt.failures_since_start

    # no matter what, we want to lock them out
    # if they're past the number of attempts allowed
    if failures > FAILURE_LIMIT and LOCK_OUT_AT_FAILURE:
        # We log them out in case they actually managed to enter
        # the correct password.
        logout(request)
        log.warning('AXES: locked out %s after repeated login attempts.', attempt.ip_address)
        return False

    if login_unsuccessful:
        #interpret the auth form to get the user in question
        if request.method == "POST":
            form = AuthenticationForm(data=request.POST)
            if form.is_valid():
                attempted_username = form.get_user().username
            else:
                attempted_username = form.data.get('username')
                attempted_password = form.data.get('password')

        # add a failed attempt for this user
        failures += 1

        # Create an AccessAttempt record if the login wasn't successful
        # has already attempted, update the info
        if attempt:
            #attempt.get_data.append(query2str(request.GET.items()))
            #attempt.post_data.append(query2str(request.POST.items()))
            attempt.access_type = models.ACCESS_FAILED
            attempt.user = attempted_username
            attempt.http_accept = request.META.get('HTTP_ACCEPT', '<unknown>')
            attempt.path_info = request.META.get('PATH_INFO', '<unknown>')
            attempt.failures_since_start = failures
            attempt.event_date = datetime.utcnow() #why do we do this?
            attempt.save()
            log.info('AXES: Repeated login failure by %s. Updating access '
                     'record. Count = %s', attempt.ip_address, failures)
        else:
            ip = request.META.get('REMOTE_ADDR', '')
            ua = request.META.get('HTTP_USER_AGENT', '<unknown>')
            attempt = AccessAudit()
            attempt.event_date = datetime.utcnow()
            attempt.doc_type=AccessAudit.__name__
            attempt.access_type = models.ACCESS_FAILED
            attempt.user_agent=ua
            attempt.user = attempted_username
            attempt.ip_address=ip
            #attempt.get_data = [query2str(request.GET.items())]
            #attempt.post_data= [query2str(request.POST.items())]
            attempt.http_accept=request.META.get('HTTP_ACCEPT', '<unknown>')
            attempt.path_info=request.META.get('PATH_INFO', '<unknown>')
            attempt.failures_since_start=failures
            attempt.save()
            log.info('AXES: New login failure by %s. Creating access record.', ip)
    else:
        #it's a successful login.

        #if we're django 1.3, this will have already been logged.
        if django.get_version() < '1.3':
            AccessAudit.audit_login(request, request.user)

    return True
コード例 #30
0
ファイル: views.py プロジェクト: kkrampa/commcare-hq
def audited_views(request, *args, **kwargs):
    db = AccessAudit.get_db()
    views = db.view('auditcare/urlpath_by_user_date', reduce=False).all()
    template = "auditcare/audit_views.html"
    context = {"audit_views": views}
    return render(request, template, context)
コード例 #31
0
ファイル: views.py プロジェクト: dimagi/auditcare
def audited_logout (request, *args, **kwargs):
    # share some useful information
    func = auth_views.logout
    logging.info("Function: %s" %(func.__name__))
    logging.info("Logged logout for user %s" % (request.user.username))
    user = request.user
    # it's a successful login.
    ip = request.META.get('REMOTE_ADDR', '')
    ua = request.META.get('HTTP_USER_AGENT', '<unknown>')
    attempt = AccessAudit()
    attempt.doc_type=AccessAudit.__name__
    attempt.access_type = models.ACCESS_LOGOUT
    attempt.user_agent=ua
    attempt.user = user.username
    attempt.session_key = request.session.session_key
    attempt.ip_address=ip
    attempt.get_data=[]
    attempt.post_data=[]
    attempt.http_accept=request.META.get('HTTP_ACCEPT', '<unknown>')
    attempt.path_info=request.META.get('PATH_INFO', '<unknown>')
    attempt.failures_since_start=0
    attempt.save()

    # call the logout function
    response = func(request, *args, **kwargs)
    return response
コード例 #32
0
ファイル: testutils.py プロジェクト: dimagi/auditcare
def get_latest_access(key):
    access_events = AccessAudit.view('auditcare/login_events', key=key, include_docs=True).all()
    access_events = sorted(access_events, key=lambda x: x.event_date, reverse=True)
    return access_events[0]
コード例 #33
0
    def decorated_logout(request, *args, **kwargs):
        # share some useful information
        if func.__name__ != 'decorated_logout' and VERBOSE:
            log.info('AXES: Calling decorated logout function: %s',
                     func.__name__)
            if args: log.info('args: %s', args)
            if kwargs: log.info('kwargs: %s', kwargs)
        log.info("Function: %s", func.__name__)
        log.info("Logged logout for user %s", request.user.username)
        user = request.user
        #it's a successful login.
        ip = request.META.get('REMOTE_ADDR', '')
        ua = request.META.get('HTTP_USER_AGENT', '<unknown>')
        attempt = AccessAudit()
        attempt.doc_type = AccessAudit.__name__
        attempt.access_type = models.ACCESS_LOGOUT
        attempt.user_agent = ua
        attempt.user = user.username
        attempt.session_key = request.session.session_key
        attempt.ip_address = ip
        attempt.get_data = []  #[query2str(request.GET.items())]
        attempt.post_data = []
        attempt.http_accept = request.META.get('HTTP_ACCEPT', '<unknown>')
        attempt.path_info = request.META.get('PATH_INFO', '<unknown>')
        attempt.failures_since_start = 0
        attempt.save()

        # call the logout function
        response = func(request, *args, **kwargs)

        if func.__name__ == 'decorated_logout':
            # if we're dealing with this function itself, don't bother checking
            # for invalid login attempts.  I suppose there's a bunch of
            # recursion going on here that used to cause one failed login
            # attempt to generate 10+ failed access attempt records (with 3
            # failed attempts each supposedly)
            return response
        return response