-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #178 from grendel-consulting/implement-auth-logs
feat: implement GET /auth_logs/ and /auth_logs/{id}
- Loading branch information
Showing
10 changed files
with
294 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# Table: kolide_auth_log | ||
|
||
Lists the authentication attempts occurring when a user tries to sign into an App protected by Kolide Device Trust. | ||
|
||
## Examples | ||
|
||
### Basic info | ||
|
||
```sql | ||
select | ||
timestamp, | ||
person_name, | ||
initial_status, | ||
result | ||
from | ||
kolide_auth_log; | ||
``` | ||
|
||
### List all attempts from the past day | ||
|
||
```sql | ||
select | ||
timestamp, | ||
person_name, | ||
initial_status, | ||
result | ||
from | ||
kolide_auth_log | ||
where | ||
timestamp > date_trunc('day', current_date) - interval '1 day'; | ||
``` | ||
|
||
### List all failed attempts performed by a specific user | ||
|
||
```sql | ||
select | ||
timestamp, | ||
initial_status, | ||
result | ||
from | ||
kolide_auth_log | ||
where | ||
person_name = 'Dennis Nedry' | ||
and | ||
result = 'Fail'; | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package kolide_client | ||
|
||
import ( | ||
"time" | ||
) | ||
|
||
type AuthLogListResponse struct { | ||
AuthLogs []AuthLog `json:"data"` | ||
Pagination Pagination `json:"pagination"` | ||
} | ||
type AuthLog struct { | ||
Id string `json:"id"` | ||
Timestamp time.Time `json:"timestamp"` | ||
PersonName string `json:"person_name"` | ||
PersonEmail string `json:"person_email"` | ||
PersonInfo PersonInformation `json:"person_info"` | ||
DeviceInfo DeviceInformation `json:"device_information,omitempty"` | ||
Result string `json:"result"` | ||
InitialStatus string `json:"initial_status"` | ||
IpAddress string `json:"ip_address"` | ||
AgentVersion string `json:"agent_version,omitempty"` | ||
Country string `json:"country,omitempty"` | ||
City string `json:"city,omitempty"` | ||
BrowserName string `json:"browser_name"` | ||
BrowserUserAgent string `json:"browser_user_agent"` | ||
IssuesDisplayed []DetailedIssueInformation `json:"issues_displayed"` | ||
Events []EventInformation `json:"events"` | ||
} | ||
|
||
type PersonInformation struct { | ||
Identifier string `json:"identifier,omitempty"` | ||
} | ||
|
||
type DetailedIssueInformation struct { | ||
Title string `json:"title,omitempty"` | ||
BlockingStatus string `json:"blocking_status,omitempty"` | ||
Identifier string `json:"identifier,omitempty"` | ||
} | ||
|
||
type EventInformation struct { | ||
Timestamp time.Time `json:"timestamp"` | ||
EventType string `json:"event_type,omitempty"` | ||
EventDescription string `json:"event_description,omitempty"` | ||
} | ||
|
||
func (c *Client) GetAuthLogs(cursor string, limit int32, searches ...Search) (interface{}, error) { | ||
return c.fetchCollection("/auth_logs/", cursor, limit, searches, new(AuthLogListResponse)) | ||
} | ||
|
||
func (c *Client) GetAuthLogById(id string) (interface{}, error) { | ||
return c.fetchResource("/auth_logs/", id, new(AuthLog)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package kolide | ||
|
||
import ( | ||
"context" | ||
|
||
kolide "github.com/grendel-consulting/steampipe-plugin-kolide/kolide/client" | ||
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto" | ||
"github.com/turbot/steampipe-plugin-sdk/v5/plugin" | ||
"github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform" | ||
) | ||
|
||
//// TABLE DEFINITION | ||
|
||
func tableKolideAuthLog(_ context.Context) *plugin.Table { | ||
return &plugin.Table{ | ||
Name: "kolide_auth_log", | ||
Description: "Authentication events occurring when a user tries to sign into an App protected by Kolide Device Trust.", | ||
Columns: []*plugin.Column{ | ||
// Filterable "top" columns | ||
{Name: "id", Description: "Canonical identifier for this auth event.", Type: proto.ColumnType_STRING}, | ||
{Name: "timestamp", Description: "When this event started.", Type: proto.ColumnType_TIMESTAMP}, | ||
{Name: "ip_address", Description: "IP address of the request intiating this auth event, may be IPv4 or IPv6.", Type: proto.ColumnType_STRING}, | ||
{Name: "agent_version", Description: "Version of the Kolide Agent running on the endpoint, if known.", Type: proto.ColumnType_STRING}, | ||
{Name: "country", Description: "Name of the country that the session originated from, determined by IP addres and subject to the limitations of IP geocoding.", Type: proto.ColumnType_STRING}, | ||
{Name: "city", Description: "Name of the city that the session originated from, determined by IP addres and subject to the limitations of IP geocoding.", Type: proto.ColumnType_STRING}, | ||
{Name: "browser_name", Description: "Common name of the browser used to initiate the session, subject to the limitations and accuracy of browser detection.", Type: proto.ColumnType_STRING}, | ||
// Other columns | ||
{Name: "person_name", Description: "Name of the user triggering this auth event.", Type: proto.ColumnType_STRING}, | ||
{Name: "person_email", Description: "Email of the user triggering this auth event.", Type: proto.ColumnType_STRING}, | ||
{Name: "person_id", Description: "Canonical identifier for the user this auth event relates to.", Type: proto.ColumnType_STRING, Transform: transform.FromField("PersonInformation.Identifier")}, | ||
{Name: "device_id", Description: "Canonical identifier for the device this auth event relates to.", Type: proto.ColumnType_STRING, Transform: transform.FromField("DeviceInformation.Identifier")}, | ||
{Name: "result", Description: "Result of the authentication attempt, either Success or Fail.", Type: proto.ColumnType_STRING}, | ||
{Name: "initial_status", Description: "Initial auth status of the device attempting authentication, one of All_Good, Will_Block, Blocked or Unknown if no device was detected.", Type: proto.ColumnType_STRING}, | ||
{Name: "browser_user_agent", Description: "User agent information for the browser used to initiatie this session, subject to the limitations and accuracy of browser detection.", Type: proto.ColumnType_STRING}, | ||
{Name: "issues_displayed", Description: "List of issue titles and blocking status that were displayed to the end user", Type: proto.ColumnType_JSON, Transform: transform.FromField("IssuesDisplayed")}, | ||
{Name: "events", Description: "Events that occured during this authentication session", Type: proto.ColumnType_JSON, Transform: transform.FromField("Events")}, | ||
// Steampipe standard columns | ||
{Name: "title", Description: "Display name for this event.", Type: proto.ColumnType_STRING, Transform: transform.FromField("Result")}, | ||
}, | ||
List: &plugin.ListConfig{ | ||
KeyColumns: []*plugin.KeyColumn{ | ||
// Using Kolide API query feature, can be combined with AND (and OR) | ||
{Name: "timestamp", Require: plugin.Optional, Operators: []string{"=", ">", "<"}}, | ||
{Name: "city", Require: plugin.Optional, Operators: []string{"=", "~~"}}, | ||
{Name: "country", Require: plugin.Optional, Operators: []string{"=", "~~"}}, | ||
{Name: "ip_address", Require: plugin.Optional, Operators: []string{"=", "~~"}}, | ||
{Name: "agent_version", Require: plugin.Optional, Operators: []string{"=", "~~"}}, | ||
{Name: "browser_name", Require: plugin.Optional, Operators: []string{"=", "~~"}}, | ||
}, | ||
Hydrate: listAuthLogs, | ||
}, | ||
Get: &plugin.GetConfig{ | ||
KeyColumns: plugin.SingleColumn("id"), | ||
Hydrate: getAuthLog, | ||
}, | ||
} | ||
} | ||
|
||
//// LIST FUNCTION | ||
|
||
func listAuthLogs(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { | ||
var visitor ListPredicate = func(client *kolide.Client, cursor string, limit int32, searches ...kolide.Search) (interface{}, error) { | ||
return client.GetAuthLogs(cursor, limit, searches...) | ||
} | ||
|
||
return listAnything(ctx, d, h, "kolide_auth_log.listAuthLogs", visitor, "AuthLogs") | ||
} | ||
|
||
//// GET FUNCTION | ||
|
||
func getAuthLog(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { | ||
var visitor GetPredicate = func(client *kolide.Client, id string) (interface{}, error) { | ||
return client.GetAuthLogById(id) | ||
} | ||
|
||
return getAnything(ctx, d, h, "kolide_auth_log.getAuthLog", "id", visitor) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
select | ||
timestamp, | ||
person_name, | ||
initial_status, | ||
result | ||
from | ||
kolide_auth_log | ||
order by | ||
timestamp asc; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
select | ||
timestamp, | ||
person_name, | ||
initial_status, | ||
result | ||
from | ||
kolide_auth_log | ||
where | ||
id = '1234'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#!/usr/bin/env bash | ||
|
||
define_test_results(){ | ||
export EXPECTED_COUNT="0" | ||
# export ID="" | ||
# export PERSON_NAME="" | ||
# export INITIAL_STATUS="" | ||
# export RESULT="" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# bats file_tags=table:kolide_auth_log, output:auth_log | ||
|
||
setup_file() { | ||
load "${BATS_TEST_DIRNAME}/_support/globals.bash" | ||
define_file_globals | ||
|
||
define_common_test_results | ||
|
||
if [[ -f $EXPECTED_RESULTS ]]; then | ||
load $EXPECTED_RESULTS | ||
fi | ||
} | ||
|
||
setup() { | ||
load "${BATS_TEST_DIRNAME}/_support/extensions.bash" | ||
load_helpers | ||
} | ||
|
||
#bats test_tags=scope:smoke | ||
@test "can_execute_query_via_steampipe" { | ||
steampipe query $QUERY_UNDER_TEST --output json > $QUERY_RESULTS | ||
assert_exists $QUERY_RESULTS | ||
} | ||
|
||
@test "has_expected_number_of_results" { | ||
run bash -c "cat $QUERY_RESULTS | jq -r '.rows | length'" | ||
|
||
if [[ -z "$EXPECTED_COUNT" ]]; then assert_output $EXPECTED_COUNT ; else assert [ "$output" -ge "1" ] ; fi | ||
} | ||
|
||
#bats test_tags=exactness:fuzzy | ||
@test "has_expected_timestamp" { | ||
run bash -c "cat $QUERY_RESULTS | jq -r '.rows.[0].timestamp'" | ||
if [[ -z "$TIMESTAMP" ]]; then assert_output --partial $TIMESTAMP ; else assert_success ; fi | ||
} | ||
|
||
#bats test_tags=exactness:fuzzy | ||
@test "has_expected_person_name" { | ||
run bash -c "cat $QUERY_RESULTS | jq -r '.rows.[0].person_name'" | ||
if [[ -z "$PERSON_NAME" ]]; then assert_output --partial $PERSON_NAME ; else assert_success ; fi | ||
} | ||
|
||
#bats test_tags=exactness:default | ||
@test "has_expected_initial_status" { | ||
run bash -c "cat $QUERY_RESULTS | jq -r '.rows.[0].initial_status'" | ||
if [[ -z "$INITIAL_STATUS" ]]; then assert_output $INITIAL_STATUS ; else assert_output "full" ; fi | ||
} | ||
|
||
#bats test_tags=exactness:default | ||
@test "has_expected_result" { | ||
run bash -c "cat $QUERY_RESULTS | jq -r '.rows.[0].result'" | ||
if [[ -z "$RESULT" ]]; then assert_output $RESULT ; else assert_output "full" ; fi | ||
} | ||
|
||
teardown_file(){ | ||
if [[ -f $QUERY_RESULTS ]]; then | ||
rm -f $QUERY_RESULTS | ||
fi | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# bats file_tags=table:kolide_auth_log, output:auth_log | ||
|
||
setup_file() { | ||
load "${BATS_TEST_DIRNAME}/_support/globals.bash" | ||
define_file_globals | ||
} | ||
|
||
setup() { | ||
load "${BATS_TEST_DIRNAME}/_support/extensions.bash" | ||
load_helpers | ||
} | ||
|
||
#bats test_tags=scope:smoke | ||
@test "can_execute_query_via_steampipe" { | ||
steampipe query $QUERY_UNDER_TEST --output json > $QUERY_RESULTS | ||
assert_exists $QUERY_RESULTS | ||
} | ||
|
||
@test "has_no_more_than_one_result" { | ||
run bash -c "cat $QUERY_RESULTS | jq -r '.rows | length'" | ||
assert [ "$output" -le "1" ] | ||
} | ||
|
||
# Remaining functionality covered in kolide_auth_log.bats | ||
|
||
teardown_file(){ | ||
if [[ -f $QUERY_RESULTS ]]; then | ||
rm -f $QUERY_RESULTS | ||
fi | ||
} |