threatstack 0.2.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +32 -51
- data/lib/threatstack/client.rb +104 -28
- data/lib/threatstack/entities/agent.rb +14 -0
- data/lib/threatstack/entities/alert.rb +15 -9
- data/lib/threatstack/entities/cve.rb +9 -0
- data/lib/threatstack/entities/{log.rb → generic_object.rb} +1 -3
- data/lib/threatstack/entities/rule.rb +5 -3
- data/lib/threatstack/entities/ruleset.rb +12 -0
- data/lib/threatstack/response.rb +22 -19
- data/lib/threatstack/serializable.rb +10 -4
- data/lib/threatstack/version.rb +1 -1
- metadata +5 -8
- data/lib/threatstack/entities/event.rb +0 -13
- data/lib/threatstack/entities/organization.rb +0 -7
- data/lib/threatstack/entities/policy.rb +0 -12
- data/lib/threatstack/entities/user_identity.rb +0 -32
- data/threatstack-0.1.0.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74577f2d9484d086e874ca7e040cd1091e4a50a8
|
4
|
+
data.tar.gz: 159fa0747f42351a160133662896e4de9466febb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a54cf4e5e7b6b5fffb2d624391129b1b836692f98cab6d0a6bf2ae74a8c2ec3d009d999ad8d3d01478ee322619ebf4494b636122dd5c7ac4278a1770ef2c48e6
|
7
|
+
data.tar.gz: faf63d2859b2e75f18916c2005cba0d488c8a35f9720b4355d2bdfd0704f5270010144be3090188f4136e8bf91208833478a05139bafae70c5e5d4cb3abafe14
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Threatstack
|
2
2
|
|
3
|
-
Threatstack is a tool for monitoring your infrastructure and hosts for malicious or suspicious activity. They have this handy little API that I decided to write a Ruby wrapper for. This is a very thin wrapper that only transforms keys for the purpose of changing them to snake_case like the rest of the ruby world. Otherwise, this maps very closely to the API docs found here: https://
|
3
|
+
Threatstack is a tool for monitoring your infrastructure and hosts for malicious or suspicious activity. They have this handy little API that I decided to write a Ruby wrapper for. This is a very thin wrapper that only transforms keys for the purpose of changing them to snake_case like the rest of the ruby world. Otherwise, this maps very closely to the API docs found here: https://apidocs.threatstack.com/v2
|
4
|
+
|
5
|
+
### NOTE: From version 1.0.0 onward, only Threatstack API v2 is supported
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
@@ -23,30 +25,33 @@ Or install it yourself as:
|
|
23
25
|
You can access all attributes on responses thanks to the method_missing function in Ruby. We only munged the attributes that don't correspond to snake_case. If you want to see a list of all available attributes for a serializable response object, simply do something like this:
|
24
26
|
|
25
27
|
```
|
26
|
-
client = Threatstack::Client.new(API_TOKEN)
|
27
|
-
|
28
|
-
=> [:
|
29
|
-
:
|
30
|
-
:
|
28
|
+
client = Threatstack::Client.new(API_TOKEN, organization_id: ORG_ID)
|
29
|
+
[threatstack] main> ts.alerts.first.attrs
|
30
|
+
=> [:id,
|
31
|
+
:title,
|
32
|
+
:type,
|
31
33
|
:created_at,
|
32
|
-
:
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
34
|
+
:event_count,
|
35
|
+
:is_dismissed,
|
36
|
+
:dismissed_at,
|
37
|
+
:dismissed_reason,
|
38
|
+
:dismissed_reason_text,
|
39
|
+
:dismissed_by,
|
40
|
+
:severity,
|
41
|
+
:agent_id,
|
42
|
+
:rule_id,
|
43
|
+
:ruleset_id,
|
44
|
+
:event_ids]
|
45
|
+
|
41
46
|
```
|
42
47
|
|
43
48
|
### Alerts
|
44
49
|
|
45
50
|
```
|
46
|
-
client = Threatstack::Client.new(API_TOKEN)
|
51
|
+
client = Threatstack::Client.new(API_TOKEN, organization_id: ORG_ID)
|
47
52
|
## All these are optional url params. See the Threatstack API Docs
|
48
53
|
alert = client.alerts(start: 3.days.ago, end: Time.now, count: 5).last
|
49
|
-
=> #<Threatstack::Alert
|
54
|
+
=> #<Threatstack::Alert:0x007fde0b01cbd8
|
50
55
|
@raw=
|
51
56
|
{"created_at"=>1496850520000,
|
52
57
|
"expires_at"=>1496936920000,
|
@@ -54,22 +59,15 @@ alert = client.alerts(start: 3.days.ago, end: Time.now, count: 5).last
|
|
54
59
|
"count"=>4,
|
55
60
|
"title"=>"CloudTrail Activity : EC2 Service Policy Changes : CreateVolume by ryan_canty",
|
56
61
|
...
|
57
|
-
|
58
|
-
=>
|
59
|
-
@raw=
|
60
|
-
{"user"=>"ryan_canty",
|
61
|
-
"userType"=>"IAMUser",
|
62
|
-
...
|
63
|
-
user_that_caused_the_event = event.user_identity.arn
|
64
|
-
=> "arn:aws:iam::1234567890:user/ryan_canty"
|
65
|
-
|
62
|
+
count = alert.count
|
63
|
+
=> 4
|
66
64
|
```
|
67
65
|
|
68
66
|
You can also limit the response if that's important to you:
|
69
67
|
|
70
68
|
```
|
71
69
|
client.alerts(fields: ['title', 'alerts'])
|
72
|
-
=> [#<Threatstack::Alert
|
70
|
+
=> [#<Threatstack::Alert:0x007fd61348c768
|
73
71
|
@raw={"title"=>"CloudTrail Activity (IAM Policy Changes) : CreateAccessKey by ryan_canty", "severity"=>2}>]
|
74
72
|
```
|
75
73
|
|
@@ -83,36 +81,19 @@ client.alert('1234567890')
|
|
83
81
|
|
84
82
|
```
|
85
83
|
client.agents
|
86
|
-
=> [#<Threatstack::
|
87
|
-
client.agent
|
88
|
-
=> #<Threatstack::Agent
|
84
|
+
=> [#<Threatstack::Response:0x007fa262b0b2e0 @raw={...}> ]
|
85
|
+
client.agent('123123123')
|
86
|
+
=> #<Threatstack::Agent:0x007fa262b0b2e0 @raw={...}>
|
89
87
|
```
|
90
88
|
|
91
|
-
|
92
|
-
### Policies
|
89
|
+
### Vulnerabilities
|
93
90
|
|
94
91
|
```
|
95
|
-
client.
|
96
|
-
|
97
|
-
client.policy
|
98
|
-
=> #<Threatstack::Policy::Policy:0x007fa262b0b2e0 @raw={...}>
|
92
|
+
client.vulnerabilities
|
93
|
+
client.vulnerability('CVE-123')
|
99
94
|
```
|
95
|
+
## TODO: Write docs for all the things (contributions welcome)
|
100
96
|
|
101
|
-
### Organizations
|
102
|
-
|
103
|
-
```
|
104
|
-
client.organizations
|
105
|
-
=> [#<Threatstack::Organization::Organization:0x007fa262b0b2e0 @raw={...}> ]
|
106
|
-
```
|
107
|
-
|
108
|
-
### Audit Logs
|
109
|
-
|
110
|
-
```
|
111
|
-
client.logs
|
112
|
-
=> [#<Threatstack::Log::Log:0x007fa262b0b2e0 @raw={...}>]
|
113
|
-
client.search('query')
|
114
|
-
=> [#<Threatstack::Log::Log:0x007fa262b0b2e0 @raw={...}>]
|
115
|
-
```
|
116
97
|
|
117
98
|
## Development
|
118
99
|
|
data/lib/threatstack/client.rb
CHANGED
@@ -3,77 +3,154 @@ require 'httparty'
|
|
3
3
|
require 'threatstack/response'
|
4
4
|
require 'threatstack/entities/agent'
|
5
5
|
require 'threatstack/entities/alert'
|
6
|
-
require 'threatstack/entities/
|
7
|
-
require 'threatstack/entities/
|
8
|
-
|
6
|
+
require 'threatstack/entities/ruleset'
|
7
|
+
require 'threatstack/entities/rule'
|
8
|
+
|
9
9
|
|
10
10
|
module Threatstack
|
11
11
|
class ThreatstackError < StandardError; end
|
12
12
|
|
13
13
|
class Client
|
14
|
-
THREATSTACK_API = 'https://
|
15
|
-
|
16
|
-
attr_reader :token, :org_id, :api_version
|
14
|
+
THREATSTACK_API = 'https://api.threatstack.com'.freeze
|
15
|
+
attr_reader :token, :org_id, :api_version, :last_pagination_token
|
17
16
|
|
18
|
-
def initialize(token, api_version
|
17
|
+
def initialize(token, organization_id: nil, api_version: 'v2')
|
19
18
|
@api_version = api_version
|
20
19
|
@token = token
|
20
|
+
@org_id = organization_id
|
21
|
+
if api_version == 'v1'
|
22
|
+
raise ThreatstackError, "This version of threatstack-ruby does not support Threatstack API v1"
|
23
|
+
end
|
21
24
|
end
|
22
25
|
|
26
|
+
### ALERTS ###
|
27
|
+
|
23
28
|
def agents(params = {})
|
24
29
|
response = do_request(:get, 'agents', params)
|
25
|
-
Response.new(:agent
|
30
|
+
Response.new(response['agents'], self, entity: :agent).agents
|
26
31
|
end
|
27
32
|
|
28
33
|
def agent(agent_id, params = {})
|
29
34
|
raise ThreatstackError, "Must specify agent id" unless agent_id
|
30
35
|
response = do_request(:get, "agents/#{agent_id}", params)
|
31
|
-
Agent.new(response)
|
36
|
+
Agent.new(response, self)
|
32
37
|
end
|
33
38
|
|
39
|
+
### ALERTS ###
|
34
40
|
def alerts(params = {})
|
35
41
|
response = do_request(:get, 'alerts', params)
|
36
|
-
Response.new(:alert
|
42
|
+
Response.new(response['alerts'], self, entity: :alert).alerts
|
43
|
+
end
|
44
|
+
|
45
|
+
def dismissed_alerts(params = {})
|
46
|
+
response = do_request(:get, 'alerts/dismissed', params)
|
47
|
+
Response.new(response['alerts'], self, entity: :alert).alerts
|
37
48
|
end
|
38
49
|
|
39
50
|
def alert(alert_id, params = {})
|
40
51
|
raise ThreatstackError, "Must specify alert id" unless alert_id
|
41
52
|
response = do_request(:get, "alerts/#{alert_id}", params)
|
42
|
-
Alert.new(response)
|
53
|
+
Alert.new(response, self)
|
54
|
+
end
|
55
|
+
|
56
|
+
def severity_counts(params = {})
|
57
|
+
response = do_request(:get, "alerts/severity-counts", params)
|
58
|
+
Response.new(response['severityCounts'], self, entity: :severity_count).list
|
59
|
+
end
|
60
|
+
|
61
|
+
def event(alert_id, event_id, params = {})
|
62
|
+
response = do_request(:get, "alerts/#{alert_id}/events/#{event_id}", params)
|
63
|
+
GenericObject.new(response['details'], self, entity: :event)
|
43
64
|
end
|
44
65
|
|
45
|
-
|
46
|
-
|
47
|
-
|
66
|
+
### CVEs ###
|
67
|
+
|
68
|
+
def vulnerabilities(params = {})
|
69
|
+
uri = "vulnerabilities"
|
70
|
+
uri += "/suppressed" if params[:suppressed]
|
71
|
+
response = do_request(:get, uri, params)
|
72
|
+
Response.new(response['cves'], self, entity: :cve).cves
|
48
73
|
end
|
49
74
|
|
50
|
-
def
|
51
|
-
raise ThreatstackError, "Must specify
|
52
|
-
response = do_request(:get, "
|
53
|
-
|
75
|
+
def vulnerability(vuln_id, params = {})
|
76
|
+
raise ThreatstackError, "Must specify vulnerability id" unless vuln_id
|
77
|
+
response = do_request(:get, "vulnerabilities/#{vuln_id}", params)
|
78
|
+
Cve.new(response, self)
|
54
79
|
end
|
55
80
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
81
|
+
def package_vulnerabilities(package, params = {})
|
82
|
+
raise ThreatstackError, "Must specify package" unless package
|
83
|
+
uri = "vulnerabilities/package/#{package}"
|
84
|
+
uri += "/suppressed" if params[:suppressed]
|
85
|
+
response = do_request(:get, uri, params)
|
86
|
+
Response.new(response['packages'], self, entity: :package).list
|
59
87
|
end
|
60
88
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
89
|
+
def server_vulnerabilities(server, params = {})
|
90
|
+
raise ThreatstackError, "Must specify server" unless server
|
91
|
+
uri = "vulnerabilities/server/#{server}"
|
92
|
+
uri += "/suppressed" if params[:suppressed]
|
93
|
+
response = do_request(:get, uri, params)
|
94
|
+
response['cves']
|
64
95
|
end
|
65
96
|
|
66
|
-
def
|
67
|
-
|
97
|
+
def cves_by_agent(agent, params = {})
|
98
|
+
raise ThreatstackError, "Must specify agent" unless agent
|
99
|
+
uri = "vulnerabilities/agent/#{agent}"
|
100
|
+
uri += "/suppressed" if params[:suppressed]
|
101
|
+
response = do_request(:get, uri, params)
|
102
|
+
response['cves']
|
103
|
+
end
|
104
|
+
|
105
|
+
def vulnerability_suppressions(params = {})
|
106
|
+
response = do_request(:get, "vulnerabilities/suppressions", params)
|
107
|
+
Response.new(response['suppressions'], self, entity: :suppression).list
|
108
|
+
end
|
109
|
+
|
110
|
+
### Rulesets ###
|
111
|
+
|
112
|
+
def rulesets(params = {})
|
113
|
+
response = do_request(:get, 'rulesets', params)
|
114
|
+
Response.new(response['rulesets'], self, entity: :ruleset).rulesets
|
115
|
+
end
|
116
|
+
|
117
|
+
def ruleset(ruleset_id, params = {})
|
118
|
+
raise ThreatstackError, "Must specify ruleset id" unless ruleset_id
|
119
|
+
response = do_request(:get, "rulesets/#{ruleset_id}", params)
|
120
|
+
Ruleset.new(response, self)
|
121
|
+
end
|
122
|
+
|
123
|
+
### Rules ###
|
124
|
+
|
125
|
+
def rules(ruleset_id, params = {})
|
126
|
+
response = do_request(:get, "rulesets/#{ruleset_id}/rules", params)
|
127
|
+
Response.new(response['rules'], self, entity: :rule).rules
|
128
|
+
end
|
129
|
+
|
130
|
+
def rule(ruleset_id, rule_id, params = {})
|
131
|
+
raise ThreatstackError, "Must specify ruleset id and rule id" unless ruleset_id && rule_id
|
132
|
+
response = do_request(:get, "rulesets/#{ruleset_id}/rules/#{rule_id}", params)
|
133
|
+
Rule.new(response, self)
|
134
|
+
end
|
135
|
+
|
136
|
+
### Servers ###
|
137
|
+
|
138
|
+
def servers(monitored = true, params = {})
|
139
|
+
uri = "servers"
|
140
|
+
uri += "/non-monitored" unless monitored
|
141
|
+
response = do_request(:get, uri, params)
|
142
|
+
Response.new(response['servers'], self, entity: :server).list
|
68
143
|
end
|
69
144
|
|
70
145
|
private
|
71
146
|
|
72
147
|
def do_request(method, path, params = {})
|
73
|
-
|
148
|
+
headers = { "Authorization" => token, "Organization-Id" => org_id }
|
149
|
+
response = HTTParty.public_send(method, build_uri(path, params), headers: headers).parsed_response
|
74
150
|
if response.instance_of?(Hash) && response['status'] == 'error'
|
75
151
|
raise ThreatstackError, response['message']
|
76
152
|
end
|
153
|
+
@last_pagination_token = response['token']
|
77
154
|
response
|
78
155
|
end
|
79
156
|
|
@@ -87,6 +164,5 @@ module Threatstack
|
|
87
164
|
uri += "?#{URI::encode(query)}" if params.any?
|
88
165
|
uri
|
89
166
|
end
|
90
|
-
|
91
167
|
end
|
92
168
|
end
|
@@ -3,5 +3,19 @@ require 'threatstack/serializable'
|
|
3
3
|
module Threatstack
|
4
4
|
class Agent
|
5
5
|
include Serializable
|
6
|
+
attributes :id, :instance_id, :status, :activated_at, :last_reported_at,
|
7
|
+
:version, :name, :description, :hostname, :tags, :agent_type
|
8
|
+
|
9
|
+
def tags
|
10
|
+
raw['tags'].map{ |t| Tag.new(t) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def ruleset_ids
|
14
|
+
raw['rulesets']
|
15
|
+
end
|
16
|
+
|
17
|
+
def rulesets
|
18
|
+
ruleset_ids.each { |id| client.ruleset(id) }
|
19
|
+
end
|
6
20
|
end
|
7
21
|
end
|
@@ -1,20 +1,26 @@
|
|
1
|
-
require 'threatstack/entities/event'
|
2
|
-
require 'threatstack/entities/rule'
|
3
1
|
require 'threatstack/serializable'
|
4
2
|
|
5
3
|
module Threatstack
|
6
4
|
class Alert
|
7
5
|
include Serializable
|
8
|
-
attributes :
|
6
|
+
attributes :id, :title, :type, :created_at, :event_count, :is_dismissed, :dismissed_at,
|
7
|
+
:dismissed_reason, :dismissed_reason_text, :dismissed_by, :severity, :agent_id,
|
8
|
+
:rule_id, :ruleset_id, :event_ids
|
9
9
|
|
10
|
-
def
|
11
|
-
|
12
|
-
Event.new(event)
|
13
|
-
end
|
10
|
+
def rule
|
11
|
+
client.rule(rule_id)
|
14
12
|
end
|
15
13
|
|
16
|
-
def
|
17
|
-
|
14
|
+
def agent
|
15
|
+
client.agent(agent_id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def ruleset
|
19
|
+
client.ruleset(ruleset_id)
|
20
|
+
end
|
21
|
+
|
22
|
+
def events
|
23
|
+
event_ids&.map{ |event_id| client.event(id, event_id)}
|
18
24
|
end
|
19
25
|
end
|
20
26
|
end
|
@@ -3,10 +3,12 @@ require 'threatstack/serializable'
|
|
3
3
|
module Threatstack
|
4
4
|
class Rule
|
5
5
|
include Serializable
|
6
|
-
attributes :
|
6
|
+
attributes :id, :ruleset_id, :name, :type, :severity_of_alerts, :alert_description,
|
7
|
+
:aggregate_fields, :filter, :frequency, :threshold, :suppressions, :ignore_files,
|
8
|
+
:file_integrity_paths, :events_to_monitor
|
7
9
|
|
8
|
-
def
|
9
|
-
|
10
|
+
def ruleset
|
11
|
+
client.ruleset(ruleset_id)
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
data/lib/threatstack/response.rb
CHANGED
@@ -1,41 +1,44 @@
|
|
1
|
+
require 'threatstack/serializable'
|
1
2
|
require 'threatstack/entities/agent'
|
2
3
|
require 'threatstack/entities/alert'
|
3
|
-
require 'threatstack/entities/
|
4
|
-
require 'threatstack/entities/
|
5
|
-
require 'threatstack/entities/
|
4
|
+
require 'threatstack/entities/cve'
|
5
|
+
require 'threatstack/entities/generic_object'
|
6
|
+
require 'threatstack/entities/ruleset'
|
7
|
+
require 'threatstack/entities/rule'
|
6
8
|
|
7
9
|
module Threatstack
|
8
10
|
class InvalidEntity < StandardError; end
|
9
11
|
class Response
|
10
|
-
attr_reader :entity, :raw
|
11
|
-
|
12
|
-
@raw = raw
|
13
|
-
@entity = entity
|
14
|
-
end
|
12
|
+
attr_reader :entity, :raw, :client
|
13
|
+
include Serializable
|
15
14
|
|
16
15
|
def agents
|
17
16
|
raise InvalidEntity unless entity == :agent
|
18
|
-
raw.map{ |a| Agent.new(a) }
|
17
|
+
raw.map{ |a| Agent.new(a, client) }
|
19
18
|
end
|
20
19
|
|
21
20
|
def alerts
|
22
21
|
raise InvalidEntity unless entity == :alert
|
23
|
-
raw.map{ |a| Alert.new(a) }
|
22
|
+
raw.map{ |a| Alert.new(a, client) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def cves
|
26
|
+
raise InvalidEntity unless entity == :cve
|
27
|
+
raw.map{ |a| Cve.new(a, client) }
|
24
28
|
end
|
25
29
|
|
26
|
-
def
|
27
|
-
raise InvalidEntity unless entity == :
|
28
|
-
raw.map{ |
|
30
|
+
def rulesets
|
31
|
+
raise InvalidEntity unless entity == :ruleset
|
32
|
+
raw.map{ |r| Ruleset.new(r, client) }
|
29
33
|
end
|
30
34
|
|
31
|
-
def
|
32
|
-
raise InvalidEntity unless entity == :
|
33
|
-
raw.map{ |
|
35
|
+
def rules
|
36
|
+
raise InvalidEntity unless entity == :rule
|
37
|
+
raw.map{ |r| Rule.new(r, client) }
|
34
38
|
end
|
35
39
|
|
36
|
-
def
|
37
|
-
|
38
|
-
raw.map{ |a| Policy.new(a) }
|
40
|
+
def list
|
41
|
+
raw.map { |g| GenericObject.new(g, client) }
|
39
42
|
end
|
40
43
|
end
|
41
44
|
end
|
@@ -1,23 +1,29 @@
|
|
1
1
|
module Threatstack
|
2
2
|
module Serializable
|
3
|
-
attr_reader :raw
|
3
|
+
attr_reader :client, :raw
|
4
4
|
|
5
5
|
def self.included(base)
|
6
6
|
base.extend ClassMethods
|
7
7
|
end
|
8
8
|
|
9
|
-
def initialize(raw)
|
9
|
+
def initialize(raw, client, entity: nil)
|
10
|
+
@client = client
|
10
11
|
@raw = raw
|
12
|
+
@entity = entity
|
11
13
|
end
|
12
14
|
|
13
15
|
def method_missing(m, *args)
|
14
|
-
raw[m.to_s]
|
16
|
+
raw[m.to_s] || raw[camelize(m.to_s)]
|
15
17
|
end
|
16
18
|
|
17
19
|
def attrs
|
18
|
-
@attrs ||= self.class.default_attrs
|
20
|
+
@attrs ||= self.class.default_attrs
|
19
21
|
end
|
20
22
|
|
23
|
+
def camelize(str)
|
24
|
+
string = str.sub(/^(?:(?=\b|[A-Z_])|\w)/) { $&.downcase }
|
25
|
+
string.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub('/', '::')
|
26
|
+
end
|
21
27
|
module ClassMethods
|
22
28
|
def attributes(*args)
|
23
29
|
@default_attrs = args
|
data/lib/threatstack/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: threatstack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Canty
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -99,16 +99,13 @@ files:
|
|
99
99
|
- lib/threatstack/client.rb
|
100
100
|
- lib/threatstack/entities/agent.rb
|
101
101
|
- lib/threatstack/entities/alert.rb
|
102
|
-
- lib/threatstack/entities/
|
103
|
-
- lib/threatstack/entities/
|
104
|
-
- lib/threatstack/entities/organization.rb
|
105
|
-
- lib/threatstack/entities/policy.rb
|
102
|
+
- lib/threatstack/entities/cve.rb
|
103
|
+
- lib/threatstack/entities/generic_object.rb
|
106
104
|
- lib/threatstack/entities/rule.rb
|
107
|
-
- lib/threatstack/entities/
|
105
|
+
- lib/threatstack/entities/ruleset.rb
|
108
106
|
- lib/threatstack/response.rb
|
109
107
|
- lib/threatstack/serializable.rb
|
110
108
|
- lib/threatstack/version.rb
|
111
|
-
- threatstack-0.1.0.gem
|
112
109
|
- threatstack.gemspec
|
113
110
|
homepage: https://github.com/getoutreach/threatstack
|
114
111
|
licenses:
|
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'threatstack/serializable'
|
2
|
-
|
3
|
-
module Threatstack
|
4
|
-
class UserIdentity
|
5
|
-
include Serializable
|
6
|
-
attributes :user_name, :session_context, :invoked_by, :account_id, :access_key_id, :principal_id
|
7
|
-
|
8
|
-
def user_name
|
9
|
-
raw['userName']
|
10
|
-
end
|
11
|
-
|
12
|
-
def session_context
|
13
|
-
raw['sessionContext']
|
14
|
-
end
|
15
|
-
|
16
|
-
def invoked_by
|
17
|
-
raw['invokedBy']
|
18
|
-
end
|
19
|
-
|
20
|
-
def account_id
|
21
|
-
raw['accountId']
|
22
|
-
end
|
23
|
-
|
24
|
-
def access_key_id
|
25
|
-
raw['accessKeyId']
|
26
|
-
end
|
27
|
-
|
28
|
-
def principal_id
|
29
|
-
raw['principalId']
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
data/threatstack-0.1.0.gem
DELETED
Binary file
|