Permalink
Browse files

Merge pull request #1003 from mozilla/generic_logincounts

Generic logincounts
  • Loading branch information...
pwnbus committed Dec 17, 2018
2 parents 81b7901 + 92d5c79 commit 7dfc6ad9134d069a4368061a07b9d25270a2bf8d
Showing with 38 additions and 20 deletions.
  1. +22 −18 rest/plugins/{auth0_logincounts.py → logincounts.py}
  2. +16 −2 tests/rest/test_rest_index.py
@@ -9,7 +9,7 @@
from configlib import getConfig, OptionParser
from datetime import datetime, timedelta
from mozdef_util.elasticsearch_client import ElasticsearchClient
from mozdef_util.query_models import SearchQuery, TermMatch, QueryStringMatch, RangeMatch, Aggregation, ExistsMatch
from mozdef_util.query_models import SearchQuery, RangeMatch, Aggregation, ExistsMatch, PhraseMatch
from mozdef_util.utilities.toUTC import toUTC


@@ -36,12 +36,12 @@ def __init__(self):

self.registration = ['logincounts']
self.priority = 5
self.name = "auth0LoginCounts"
self.name = "loginCounts"
self.description = "count failures/success logins"

# set my own conf file
# relative path to the rest index.py file
self.configfile = './plugins/auth0_logincounts.conf'
self.configfile = './plugins/logincounts.conf'
self.options = None
if os.path.exists(self.configfile):
sys.stdout.write('found conf file {0}\n'.format(self.configfile))
@@ -54,7 +54,11 @@ def onMessage(self, request, response):
'''
# an ES query/facet to count success/failed logins
# oriented to the data sent via auth02mozdef.py
# oriented to the data having
# category: authentication
# details.success marked true/false for success/failed auth
# details.username as the user

begindateUTC=None
enddateUTC=None
resultsList = list()
@@ -70,10 +74,10 @@ def onMessage(self, request, response):
# a query to tally users with failed logins
date_range_match = RangeMatch('utctimestamp', begindateUTC, enddateUTC)
search_query.add_must(date_range_match)
search_query.add_must(TermMatch('tags', 'auth0'))
search_query.add_must(QueryStringMatch('failed'))
search_query.add_must(PhraseMatch('category', 'authentication'))
search_query.add_must(PhraseMatch('details.success','false'))
search_query.add_must(ExistsMatch('details.username'))
search_query.add_aggregation(Aggregation('details.type'))
search_query.add_aggregation(Aggregation('details.success'))
search_query.add_aggregation(Aggregation('details.username'))

results = search_query.execute(es_client, indices=['events','events-previous'])
@@ -93,17 +97,17 @@ def onMessage(self, request, response):

details_query = SearchQuery()
details_query.add_must(date_range_match)
details_query.add_must(TermMatch('tags', 'auth0'))
details_query.add_must(TermMatch('details.username', username))
details_query.add_aggregation(Aggregation('details.type'))

results = details_query.execute(es_client)
# details.type is usually "Success Login" or "Failed Login"
for t in results['aggregations']['details.type']['terms']:
if 'success' in t['key'].lower():
success = t['count']
if 'fail' in t['key'].lower():
failures = t['count']
details_query.add_must(PhraseMatch('category', 'authentication'))
details_query.add_must(PhraseMatch('details.username', username))
details_query.add_aggregation(Aggregation('details.success'))

details_results = details_query.execute(es_client)
# details.success is boolean. As an aggregate is an int (0/1)
for details_term in details_results['aggregations']['details.success']['terms']:
if details_term['key'] == 1:
success = details_term['count']
if details_term['key'] == 0:
failures = details_term['count']
resultsList.append(
dict(
username=username,
@@ -96,13 +96,13 @@ def test_route_endpoints(self):
assert json_resp == []


class TestLdapLoginsRoute(RestTestSuite):
class TestLoginCountsRoute(RestTestSuite):

routes = ['/logincounts', '/logincounts/']
status_code = 200

def setup(self):
super(TestLdapLoginsRoute, self).setup()
super(TestLoginCountsRoute, self).setup()

# ttesterson test events
for count in range(10):
@@ -114,10 +114,12 @@ def setup(self):
"auth0"
],
"timestamp": timestamp,
"category": "authentication",
"summary": "Failed login from ttesterson@mozilla.com srcIP=1.1.1.1",
"details": {
"username": "ttesterson@mozilla.com",
"type": "Failed Login",
"success": False,
}
}
self.populate_test_event(event)
@@ -130,10 +132,12 @@ def setup(self):
"auth0"
],
"timestamp": timestamp,
"category": "authentication",
"summary": "Success Login for ttesterson@mozilla.com srcIP=1.1.1.1",
"details": {
"username": "ttesterson@mozilla.com",
"type": "Success Login",
"success": True,
}
}
self.populate_test_event(event)
@@ -148,10 +152,12 @@ def setup(self):
"auth0"
],
"timestamp": timestamp,
"category": "authentication",
"summary": "Failed Login from ttester@mozilla.com srcIP=1.1.1.1",
"details": {
"username": "ttester@mozilla.com",
"type": "Failed Login",
"success": False,
}
}
self.populate_test_event(event)
@@ -164,10 +170,12 @@ def setup(self):
"auth0"
],
"timestamp": timestamp,
"category": "authentication",
"summary": "Success Login for ttester@mozilla.com srcIP=1.1.1.1",
"details": {
"username": "ttester@mozilla.com",
"type": "Success Login",
"success": True,
}
}
self.populate_test_event(event)
@@ -182,10 +190,12 @@ def setup(self):
"auth0"
],
"timestamp": timestamp,
"category": "authentication",
"summary": "Failed Login from qwerty@mozillafoundation.org srcIP=1.1.1.1",
"details": {
"username": "qwerty@mozillafoundation.org",
"type": "Failed Login",
"success": False,
}
}
self.populate_test_event(event)
@@ -198,10 +208,12 @@ def setup(self):
"auth0"
],
"timestamp": timestamp,
"category": "authentication",
"summary": "Success Login for qwerty@mozillafoundation.org",
"details": {
"username": "qwerty@mozillafoundation.org",
"type": "Success Login",
"success": True,
}
}
self.populate_test_event(event)
@@ -215,10 +227,12 @@ def setup(self):
"auth0"
],
"timestamp": timestamp,
"category": "authentication",
"summary": "Success Login for qwerty@mozillafoundation.org",
"details": {
"username": "qwerty@mozillafoundation.org",
"type": "Success Login",
"success": True,
}
}
self.populate_test_event(event)

0 comments on commit 7dfc6ad

Please sign in to comment.