sailpoint 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +157 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/sailpoint.rb +61 -0
- data/lib/sailpoint/config.rb +101 -0
- data/lib/sailpoint/helpers.rb +88 -0
- data/lib/sailpoint/rest.rb +81 -0
- data/lib/sailpoint/scim.rb +86 -0
- data/lib/sailpoint/version.rb +6 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8faa7517c8f7dc3f463e65c8fe1664c2bb114d1e0dea32a5de3c3daf3bf25501
|
4
|
+
data.tar.gz: 754bb1d74249fc947d6e72983270be4c96ff0433b787fc60a41d7ec36834bf92
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dc00288d246b3f26652e2a173f56617b73e3fababe07219f1e1df435e48ba2be5691e0c732d31a5f9ab0382bff28ffbeee399b62f1c31d556a982086c92c4c31
|
7
|
+
data.tar.gz: 7bc723c3372e745dcfd37a895a677e29b99ae7327f0c3c6b2896f5eedb8f7a87f65c5489073ab1da4338c9faf62da88a6251511f48f7d0f1cbac99bec59bb768
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 Brandon Hicks
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
# Sailpoint
|
2
|
+
|
3
|
+
This is an unofficial tool for interactiving with Sailpoints [IdentityIQ's](https://www.sailpoint.com/solutions/identityiq/?elqct=Website&elqchannel=OrganicDirect) API interface. This gem assumes your IdenityIQ API is setup to authenticate using [BasicAuth](https://developer.sailpoint.com/SCIM/index.html#authentication) headers. If you require credentials for your SailPoint (IdenitityIQ) interface, I suggest contacting your system administrator before continuing any farther.
|
4
|
+
|
5
|
+
**Note:** This gem doesn't include all possible IdentityIQ API requests, primarmly due to last of authorization to access much else. If you happen to have additional access to an IdentitiyIQ API it would be very much appreciated if you contributed any additional API requests.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
# Gemfile
|
13
|
+
gem 'sailpoint'
|
14
|
+
```
|
15
|
+
|
16
|
+
And then execute:
|
17
|
+
|
18
|
+
`bundle install`
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
Before attempting to use the Sailpoint API you'll need to contact your system admin and get a set of API credentials. Every application should have a unique set of credentials, that way if any one application is compromised you don't have to roll the credentials on a number of applications. I would also suggest setting these credentials in your rails encrypted credentials as the following.
|
23
|
+
|
24
|
+
```yaml
|
25
|
+
sailpoint:
|
26
|
+
username: sample_user
|
27
|
+
password: sample_password
|
28
|
+
```
|
29
|
+
|
30
|
+
To access these credentials throughout the application you can access them with the following references:
|
31
|
+
|
32
|
+
```ruby
|
33
|
+
Rails.application.credentials[:sailpoint][:username]
|
34
|
+
Rails.application.credentials[:sailpoint][:password]
|
35
|
+
```
|
36
|
+
|
37
|
+
### Running as a ruby script
|
38
|
+
|
39
|
+
If running from `irb` or wanting to call the IdentityIQ API from a ruby script use the following method to access the IdentityIQ API
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
require 'sailpoint'
|
43
|
+
|
44
|
+
# In order to make any API requests you need to specify the IdentityIQ API Host and set you API credentials
|
45
|
+
Sailpoint.set_credentials('foo','bar')
|
46
|
+
Sailpoint.set_host = 'https://example.com/';
|
47
|
+
Sailpoint.get_user('sample_user')
|
48
|
+
```
|
49
|
+
|
50
|
+
## Getting Started
|
51
|
+
|
52
|
+
By default this will pull users from the REST API
|
53
|
+
If you want to pull from the SCIM API there are a number of ways to do this as well
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
# First method
|
57
|
+
Sailpoint.get_user('sample_user', interface: 'scim')
|
58
|
+
|
59
|
+
# Second method
|
60
|
+
# Note: When reassigning the API interface future queries will hit the new API endpoint unless specified
|
61
|
+
Sailpoint::Config.interface = 'scim'
|
62
|
+
Sailpoint.get_user('sample_user')
|
63
|
+
|
64
|
+
# Third method (and my personal favorite to use without assigning the interface)
|
65
|
+
Sailpoint::Scim.get_user('sample_user')
|
66
|
+
```
|
67
|
+
|
68
|
+
### Using this gem with Rails
|
69
|
+
|
70
|
+
Lets first start by creating an initializer so you don't have to set the API configuration every time you want to make an API request.
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
# config/initializers/sailpoint.rb
|
74
|
+
if defined?(Sailpoint)
|
75
|
+
Sailpoint::Config.set_credentials('api_username', 'api_password')
|
76
|
+
Sailpoint::Config.host = 'http://example.com/'
|
77
|
+
end
|
78
|
+
|
79
|
+
# If you're using encrypted credentials
|
80
|
+
if defined?(Sailpoint)
|
81
|
+
Sailpoint::Config.set_credentials(Rails.application.credentials[:sailpoint][:username], Rails.application.credentials[:sailpoint][:password])
|
82
|
+
Sailpoint::Config.host = 'http://example.com/'
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
Now in your controller, models, or wherever required you should be able to make an API request with the following command
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
Sailpoint.get_user('sample_user')
|
90
|
+
```
|
91
|
+
|
92
|
+
# Misc
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
Sailpoint::Config.set_credentials('api_username', 'api_password'); Sailpoint::Config.host = 'http://example.com/';
|
96
|
+
# Sailpoint::Config.interface = 'rest'
|
97
|
+
# Sailpoint::Config.interface = 'scim'
|
98
|
+
Sailpoint.get_user('username')
|
99
|
+
```
|
100
|
+
|
101
|
+
## General function calls
|
102
|
+
|
103
|
+
Listed below are the majority of the functions used throughout the library and their intended purpose.
|
104
|
+
|
105
|
+
* `Sailpoint.get_user(identity)` - Search the API resources for the specified user identity
|
106
|
+
* `Sailpoint.set_credentials(username, password)` - Assign the credentials for accessing the IdentityIQ API
|
107
|
+
* `Sailpoint.set_host(host)` - Assign the IdentityIQ API base URL
|
108
|
+
|
109
|
+
## Configuration
|
110
|
+
|
111
|
+
* `Sailpoint::Config.auth_header` - Returns the BasicAuth Header for creating and API request
|
112
|
+
* `Sailpoint::Config.credentials` - A hash containing the API credentials when setting API requests headers
|
113
|
+
* `Sailpoint::Config.hashed_credentials` - A Base64 encoded string for the API request
|
114
|
+
* `Sailpoint::Config.host` - Returns the API base host
|
115
|
+
* `Sailpoint::Config.interface` - Returns the specified API interface (REST || SCIM)
|
116
|
+
* `Sailpoint::Config.interface_path` - Returns the API path dependant on the interface
|
117
|
+
* `Sailpoint::Config.password` - Returns the API password specified
|
118
|
+
* `Sailpoint::Config.set_credentials(username, password)` - Used for assigning credentials for accessing the IndentityIQ API
|
119
|
+
* `Sailpoint::Config.trimmed_host` - Returns the API base host with all trailing whitespace and slashs trimmed
|
120
|
+
* `Sailpoint::Config.url` - Returns the full API URL based on the `host+interface`
|
121
|
+
* `Sailpoint::Config.username` - If set, it returns the username credentials for API
|
122
|
+
|
123
|
+
## Interface specific function calls
|
124
|
+
|
125
|
+
### SCIM
|
126
|
+
|
127
|
+
* `Sailpoint::Scim.accounts` - Returns a massive list of all account entries in the IdeneityIQ sources
|
128
|
+
* `Sailpoint::Scim.appliations` - Returnsa list of all Applications and their associated attributes
|
129
|
+
* `Sailpoint::Scim.get_user(identity)` - Used to fetch the specified users associated data
|
130
|
+
* `Sailpoint::Scim.resource_types` - Fetch all resource types associated with the IdentityIQ API
|
131
|
+
* `Sailpoint::Scim.schemas` - Fetch the schemas for all resources types assocaited with the API's returning data
|
132
|
+
* `Sailpoint::Scim.service_providers` - Fetch a list of all ServiceProviders associated with the data being served by the API
|
133
|
+
* `Sailpoint::Scim.users` - Returns a list of all users from the associated organizations
|
134
|
+
* `Sailpoint::Scim.user_resource_types` - Returns a list of data attributes for the ResourceType -> Users
|
135
|
+
|
136
|
+
### REST
|
137
|
+
|
138
|
+
* `Sailpoint::Rest.authenticate` - Used to verify if the supplied credentials are valid
|
139
|
+
* `Sailpoint::Rest.check_roles` - Verify if the user has any policies set within the specified roles
|
140
|
+
* `Sailpoint::Rest.get_identity` - Used to fetch the specified user identiy from the REST API interface
|
141
|
+
* `Sailpoint::Rest.get_user(identity)` - Used to fetch the specified users associated data
|
142
|
+
* `Sailpoint::Rest.permitted_roles(identity)` - Get a users roles within the Organization
|
143
|
+
* `Sailpoint::Rest.ping` - Used to verify your credentials are valid and IdentityIQ reource is properly responding
|
144
|
+
|
145
|
+
## API Documentation
|
146
|
+
|
147
|
+
* [IdentityNow](https://api.identitynow.com/)
|
148
|
+
* [API Reference (SCIM)](https://developer.sailpoint.com/SCIM/index.html)
|
149
|
+
* [Admin Guide](https://myaccess.supervalu.com/identityiq/doc/pdf/7_0_IdentityIQ_Administration_Guide.pdf)
|
150
|
+
|
151
|
+
## Contributing
|
152
|
+
|
153
|
+
Bug reports and pull requests are welcome on Github at https://github.com/tarellel/sailpoint
|
154
|
+
|
155
|
+
## License
|
156
|
+
|
157
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'sailpoint'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/lib/sailpoint.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'sailpoint/version'
|
2
|
+
require 'sailpoint/config'
|
3
|
+
require 'sailpoint/helpers' # To override defaults and adding global helper functions
|
4
|
+
require 'sailpoint/rest'
|
5
|
+
require 'sailpoint/scim'
|
6
|
+
|
7
|
+
# Sailpoint Module to allow for easily accessing the Sailpoint API
|
8
|
+
module Sailpoint
|
9
|
+
# When generating a Standard Exception error
|
10
|
+
class Error < StandardError; end
|
11
|
+
|
12
|
+
# If a valid username and URL have been supplied a lookup requests will be send to determine if the user exists in the specified interface
|
13
|
+
# @param username [String] - the username that we are going to valid exists in the IdentityIQ listing
|
14
|
+
# @return [Hash] - If a user is found, it will return all the that identities attributes
|
15
|
+
def self.get_user(username, interface: nil)
|
16
|
+
raise ArgumentError, 'An invalid user lookup was specified.' if username.to_s.blank?
|
17
|
+
raise ArgumentError, 'Please specify a valid HOST/Interface before attemping a lookup.' unless valid_url?
|
18
|
+
raise ArgumentError, 'Valid credentials are required before attempting an API request.' unless valid_credentials?
|
19
|
+
raise ArgumentError, 'Invalid method type' unless valid_interface_type?(interface) || valid_interface_type?(Sailpoint::Config.interface)
|
20
|
+
|
21
|
+
if interface.nil?
|
22
|
+
Object.const_get("Sailpoint::#{Sailpoint::Config.interface.capitalize}").get_user(username)
|
23
|
+
elsif valid_interface_type?(interface)
|
24
|
+
Object.const_get("Sailpoint::#{interface.capitalize}").get_user(username)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Assign the credentials for accessing the IdentityIQ API
|
29
|
+
# @param username [String] - The Sailpoint username required for accessing the API
|
30
|
+
# @param password [String] - The Sailpoint password required for accessing the API
|
31
|
+
def self.set_credentials(username, password)
|
32
|
+
Sailpoint::Config.set_credentials(username, password) unless username.nil? && password.nil?
|
33
|
+
end
|
34
|
+
|
35
|
+
# Assign the IdentityIQ API base URL
|
36
|
+
# @param host [String] - The base URL in which the API calls will be built upon
|
37
|
+
def self.set_host(host)
|
38
|
+
Sailpoint::Config.host = host unless host.blank?
|
39
|
+
end
|
40
|
+
|
41
|
+
# Used to verify if any credentails were supplied for the API request
|
42
|
+
# @return [Boolean] if credentials were supplied or not
|
43
|
+
def self.valid_credentials?
|
44
|
+
return false if Sailpoint::Config.username.blank? && Sailpoint::Config.password.blank?
|
45
|
+
|
46
|
+
!Sailpoint::Config.hashed_credentials.blank?
|
47
|
+
end
|
48
|
+
|
49
|
+
# Used to verify if the specifed interface type is valid for the Sailpoint API
|
50
|
+
# @param interface [String] - A specified API interface endpoint, that can either be `Rest` or `Scim`
|
51
|
+
# @return [Boolean] - Returns weither the specifed interface is a a valid type allowed by the API.
|
52
|
+
def self.valid_interface_type?(interface)
|
53
|
+
%w[rest scim].include?(interface)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Used to verify if the URL string is blank or a URL was supplied
|
57
|
+
# @return [Boolean] - if a url for the API endpoint was supplied or not
|
58
|
+
def self.valid_url?
|
59
|
+
!Sailpoint::Config.url.blank?
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'sailpoint/helpers'
|
3
|
+
|
4
|
+
# Used for setting you Sailpoint API configuration and credentials
|
5
|
+
module Sailpoint
|
6
|
+
# Used for setting API configuration before creating API Requests
|
7
|
+
# Configuration can include: <code>username, password, interface, host, url</code>
|
8
|
+
class Config
|
9
|
+
attr_accessor :username, :password, :interface, :url
|
10
|
+
|
11
|
+
@username = nil
|
12
|
+
@password = nil
|
13
|
+
@interface = 'rest' # By default lets resort to using the Rest interface
|
14
|
+
@host = nil # Where the SailPoint server is hosted
|
15
|
+
|
16
|
+
class << self
|
17
|
+
attr_writer :username, :password, :interface, :host, :url
|
18
|
+
|
19
|
+
# Used to set the API requests BasicAuth credentails
|
20
|
+
# @param username [String] - Username for the API request
|
21
|
+
# @param password [String] - Password for the API request
|
22
|
+
def set_credentials(username, password)
|
23
|
+
@username = username unless username.nil?
|
24
|
+
@password = password unless password.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
# Used for setting if the interface type is Rest || SCIM
|
28
|
+
# @return [String] - Returns either the specified interface (Default: <code>rest</code>)
|
29
|
+
def interface
|
30
|
+
(@interface ||= 'rest')
|
31
|
+
end
|
32
|
+
|
33
|
+
# Used for fetching the API interface_path based on the API interface specification
|
34
|
+
# @return [String] - Returns the API's interface path, based on interface type
|
35
|
+
def interface_path
|
36
|
+
(@interface == 'scim' ? 'scim' : 'rest')
|
37
|
+
end
|
38
|
+
|
39
|
+
# Used to fetch the host for the API request
|
40
|
+
# @return [String] - If a valid host was specified, it will returned a trimmed string with trailing whitespaces and slashes removed
|
41
|
+
def host
|
42
|
+
return '' if @host.blank?
|
43
|
+
|
44
|
+
trimmed_host
|
45
|
+
end
|
46
|
+
|
47
|
+
# Used for fetching the requesting users entire URL (Host+Interface)
|
48
|
+
# @param interface [String] - used for when the user is specicically calling an API such as <code>Sailpoint::Scim.get_user('username')</code>
|
49
|
+
# @return [String] - Returns the entire requesting URL (based on host and interface type)
|
50
|
+
def url(interface = '')
|
51
|
+
return '' if @host.blank? || @interface.blank?
|
52
|
+
|
53
|
+
interface.blank? ? [trimmed_host, 'identityiq', interface_path].join('/') : [trimmed_host, 'identityiq', interface].join('/')
|
54
|
+
end
|
55
|
+
|
56
|
+
# Used for fetching credentails username (if it has been set)
|
57
|
+
# @return [String] - The credentails username
|
58
|
+
def username
|
59
|
+
@username || ''
|
60
|
+
end
|
61
|
+
|
62
|
+
# Used for fetching the requesting users credentials password (if it has been set)
|
63
|
+
# @return [String] - The password for the API credentials
|
64
|
+
def password
|
65
|
+
@password || ''
|
66
|
+
end
|
67
|
+
|
68
|
+
# Used for fetching the API credentials when setting API requests headers
|
69
|
+
# @return [String] - Return a hash of the current API credentils (for validation purposes)
|
70
|
+
def credentials
|
71
|
+
{ username: @username, password: @password }
|
72
|
+
end
|
73
|
+
|
74
|
+
# Remove trailing forward slashes from the end of the Host, that way hosts and interfaces can be properly joined
|
75
|
+
# => I also did this because you'd get the same results if something supplied `http://example.com` or `https://example.com/`
|
76
|
+
# @return [String] - Returns a cleaned up and trimmed host with trailing slashs removed
|
77
|
+
def trimmed_host
|
78
|
+
return '' if @host.blank?
|
79
|
+
|
80
|
+
@host.strip.gsub!(%r{\/?++$}, '')
|
81
|
+
end
|
82
|
+
|
83
|
+
# SailPoints auth requires a Base64 string of (username:password)
|
84
|
+
# This is how most BasicAuth authentication methods work
|
85
|
+
# @return [String] - It will either return an empty string or a Base64.encoded hash for the the API credentials (BasicAuth requires Base64)
|
86
|
+
def hashed_credentials
|
87
|
+
return '' if @username.blank? && @password.blank?
|
88
|
+
|
89
|
+
Base64.encode64("#{@username}:#{@password}").strip
|
90
|
+
end
|
91
|
+
|
92
|
+
# Used for generating the API BasicAuth Header when creating an API request
|
93
|
+
# @return [String] - Return the API Authorization header for the making API requests
|
94
|
+
def auth_header
|
95
|
+
return '' if @username.blank? && @password.blank?
|
96
|
+
|
97
|
+
{ 'Authorization' => "Basic #{Sailpoint::Config.hashed_credentials}" }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# Used to override and give String the blank? validation similar to Rails
|
2
|
+
class String
|
3
|
+
# Used to determine if the object is nil or empty ('')
|
4
|
+
# @return [true, false]
|
5
|
+
def blank?
|
6
|
+
self.nil? || self.strip.empty? || self.strip.length.zero?
|
7
|
+
end
|
8
|
+
|
9
|
+
# Used to determine if the object is not nil
|
10
|
+
# @return [true, false]
|
11
|
+
def present?
|
12
|
+
!self.nil?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Used to printout a [Red] message to STDOUT in case you want to print a message without causing an Exception.
|
17
|
+
# @param msg [String] - The excpetion message that should be printed out
|
18
|
+
def print_exception(msg = '')
|
19
|
+
puts "\e[31m#{msg}\e[0m"
|
20
|
+
end
|
21
|
+
|
22
|
+
# Similar to Rails imlemneation https://github.com/rails/rails/blob/66cabeda2c46c582d19738e1318be8d59584cc5b/activesupport/lib/active_support/core_ext/object/blank.rb#L56
|
23
|
+
class NilClass
|
24
|
+
# Used to determine if the object is blank? || empty?
|
25
|
+
# *Note:* If a nil value is specified it *should* always be blank? || empty?
|
26
|
+
# @return [true, false]
|
27
|
+
def blank?
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
# Used to determine if the object is not nil
|
32
|
+
# @return [true, false]
|
33
|
+
def present?
|
34
|
+
!blank?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Used to override and give Number the blank? validation similar to Rails
|
39
|
+
class Numeric
|
40
|
+
# Used to determine if the object is blank? || empty?
|
41
|
+
#
|
42
|
+
# *Note:* If a object is declared a Numerica valye, it shouldn't ever be blank
|
43
|
+
# @return [true, false]
|
44
|
+
def blank?
|
45
|
+
false
|
46
|
+
end
|
47
|
+
|
48
|
+
# Used to determine if the object is not nil
|
49
|
+
# @return [true, false]
|
50
|
+
def present?
|
51
|
+
!blank?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Used to override and give Array the blank? validation similar to Rails
|
56
|
+
class Array
|
57
|
+
# Used to determine if the object is blank? || empty?
|
58
|
+
# @return [true, false]
|
59
|
+
alias_method :blank?, :empty?
|
60
|
+
end
|
61
|
+
|
62
|
+
# Used to override and give Hash the blank? validation similar to Rails
|
63
|
+
class Hash
|
64
|
+
alias_method :blank?, :empty?
|
65
|
+
|
66
|
+
# Used to determine if the object is not nil
|
67
|
+
# @return [true, false]
|
68
|
+
def present?
|
69
|
+
!blank?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Used to generate an Exception error hen invalid credentails have been supplied
|
74
|
+
class AuthenticationException < StandardError
|
75
|
+
attr_reader :data
|
76
|
+
|
77
|
+
# Used to generate an ExceptionError message when Authenication has failed
|
78
|
+
# @param data [String] - The message in which you wish to send to STDOUT for the exception error
|
79
|
+
def initialize(data = 'An API Authentication error has occured.')
|
80
|
+
super
|
81
|
+
@data = data
|
82
|
+
end
|
83
|
+
|
84
|
+
# Specify the attribute in which to push to STDOUT when generating a Ruby ExceptionError
|
85
|
+
def message
|
86
|
+
@data
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
# Used for creating Sailpoint RESTS requests
|
5
|
+
module Sailpoint
|
6
|
+
# Used for created REST API calls to the organizations IdentityIQ source
|
7
|
+
class Rest
|
8
|
+
# Used to verify if the supplied credentials are valid
|
9
|
+
# @return [Hash] - The responses body as a JSON hash
|
10
|
+
def self.authenticate
|
11
|
+
response = HTTParty.get([Sailpoint::Config.url('rest'), 'authentication'].join('/'),
|
12
|
+
headers: Sailpoint::Config.auth_header,
|
13
|
+
output: 'json')
|
14
|
+
JSON.parse(response)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Verify if the user has any policies set within the specified roles
|
18
|
+
# @param identity [String] - The user in which you are requesting data for
|
19
|
+
# @param roles [String, Array] - Roles specified to validate against (either: <code>role</code> or <code>['role1','role2']</code>)
|
20
|
+
# @return [Hash] - Return data associated with there users roles
|
21
|
+
def self.check_roles(identity, roles)
|
22
|
+
# Values for both attributes are required in order to create the request
|
23
|
+
# And verify the user exists before attempting to create the request (this prevents IdentityIQ from making a long last query looking for a non-existant user)
|
24
|
+
return {} if identity.blank? || roles.blank? || get_user(identity).empty?
|
25
|
+
|
26
|
+
# the roles attribute should either be 'Contractor,Assistant' or ['Contractor', 'Assistant']
|
27
|
+
roles = roles.join(',') if roles.is_a?(Array)
|
28
|
+
response = HTTParty.get([Sailpoint::Config.url('rest'), "policies/checkRolePolicies?identity=#{identity}&roles=#{roles}"].join('/'),
|
29
|
+
headers: Sailpoint::Config.auth_header,
|
30
|
+
output: 'json')
|
31
|
+
JSON.parse(response&.body || '{}')
|
32
|
+
end
|
33
|
+
|
34
|
+
# Used to fetch the specified user identiy from the REST API interface
|
35
|
+
# @param identity [String] - The user in which you are requesting data for
|
36
|
+
# @return [Hash] - If no user if found an empty hash will be returned. If a a user is found, their parsed JSON will be returned as a result
|
37
|
+
def self.get_identity(identity)
|
38
|
+
response = HTTParty.get([Sailpoint::Config.url('rest'), 'identities', identity, 'managedIdentities'].join('/'),
|
39
|
+
headers: Sailpoint::Config.auth_header,
|
40
|
+
output: 'json')
|
41
|
+
return [] if response.code == '500'
|
42
|
+
|
43
|
+
JSON.parse(response&.body || '{}').first
|
44
|
+
end
|
45
|
+
|
46
|
+
# Used to fetch the specified users associated data
|
47
|
+
# @param identity [String] - The user in which you are requesting data for
|
48
|
+
# @return [Hash] - If no user if found an empty hash will be returned. If a a user is found, their parsed JSON will be returned as a result
|
49
|
+
def self.get_user(identity)
|
50
|
+
response = HTTParty.get([Sailpoint::Config.url('rest'), 'identities', identity].join('/'),
|
51
|
+
headers: Sailpoint::Config.auth_header,
|
52
|
+
output: 'json')
|
53
|
+
raise AuthenticationException, 'Invalid credentials, please try again.' if response.code == 401
|
54
|
+
|
55
|
+
JSON.parse(response&.body || '{}')
|
56
|
+
end
|
57
|
+
|
58
|
+
# Get a users roles within the Organization
|
59
|
+
# @return [Hash] - The users roles associated within the Organization
|
60
|
+
def self.permitted_roles(identity)
|
61
|
+
# Before requesting a users roles we need to verify if the identiy matches a valid user first
|
62
|
+
return {} if identity.blank? || get_user(identity).empty?
|
63
|
+
|
64
|
+
response = HTTParty.get([Sailpoint::Config.url('rest'), "roles/assignablePermits/?roleMode=assignable&identity=#{identity}"].join('/'),
|
65
|
+
headers: Sailpoint::Config.auth_header,
|
66
|
+
output: 'json')
|
67
|
+
response_body = JSON.parse(response&.body || '{}')
|
68
|
+
return response_body['objects'].map { |role| role['name'] } if response['status'].present? && response['status'] == 'success'
|
69
|
+
|
70
|
+
response_body
|
71
|
+
end
|
72
|
+
|
73
|
+
# Used to verify your credentials are valid and IdentityIQ reource is properly responding
|
74
|
+
# @return [Hash] - The head and body of the response
|
75
|
+
def self.ping
|
76
|
+
HTTParty.get([Sailpoint::Config.url('rest'), 'ping'].join('/'),
|
77
|
+
headers: Sailpoint::Config.auth_header,
|
78
|
+
output: 'json')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
# Used for creating Sailpoint SCIM requests
|
5
|
+
module Sailpoint
|
6
|
+
# Used for created SCIM API calls to the organizations IdentityIQ source
|
7
|
+
class Scim
|
8
|
+
# Returns a massive list of all account entries in the IdeneityIQ sources
|
9
|
+
# @return [Hash] - A hashed list of all IdenityIQ accounts [Service and User accounts]
|
10
|
+
def self.accounts
|
11
|
+
response = HTTParty.get([Sailpoint::Config.url('scim'), 'v2/Accounts'].join('/'),
|
12
|
+
headers: Sailpoint::Config.auth_header,
|
13
|
+
output: 'json')
|
14
|
+
JSON.parse(response&.body || '{}')
|
15
|
+
end
|
16
|
+
|
17
|
+
# Used to fetch a list of all Applications and their associated attributes
|
18
|
+
# @return [Hash] - A hash of all avaialble applications and their associated MetaData attributes
|
19
|
+
def self.applications
|
20
|
+
response = HTTParty.get([Sailpoint::Config.url('scim'), 'v2/Applications'].join('/'),
|
21
|
+
headers: Sailpoint::Config.auth_header,
|
22
|
+
output: 'json')
|
23
|
+
JSON.parse(response&.body || '{}')
|
24
|
+
end
|
25
|
+
|
26
|
+
# Used to fetch the specified users associated data
|
27
|
+
# @return [Hash] - The users hashed data attributes
|
28
|
+
def self.get_user(identity)
|
29
|
+
puts [Sailpoint::Config.url('scim'), 'v2/Users', identity].join('/')
|
30
|
+
response = HTTParty.get([Sailpoint::Config.url('scim'), 'v2/Users', identity].join('/'),
|
31
|
+
headers: Sailpoint::Config.auth_header,
|
32
|
+
output: 'json')
|
33
|
+
# NOTE: If invalid credentials are supplied or the user could not be found response bodies contain a status code.
|
34
|
+
# => But if a a user if found, a status code isn't returned, but all of their data attributes are returned instead.
|
35
|
+
raise AuthenticationException, 'Invalid credentials, please try again.' if response.body['status'] && response.body['status'] == '401'
|
36
|
+
return [] if response.body && response.body['status'] && response.body['status'] == '404'
|
37
|
+
|
38
|
+
JSON.parse(response&.body || '{}')
|
39
|
+
end
|
40
|
+
|
41
|
+
# Fetch all resource types associated with the IdentityIQ API
|
42
|
+
# @return [Hash] - A hash of all resources types [Users, Applications, Accounts, Roles, etc.]
|
43
|
+
def self.resource_types
|
44
|
+
response = HTTParty.get([Sailpoint::Config.url('scim'), 'v2/ResourceTypes'].join('/'),
|
45
|
+
headers: Sailpoint::Config.auth_header,
|
46
|
+
output: 'json')
|
47
|
+
JSON.parse(response&.body || '{}')
|
48
|
+
end
|
49
|
+
|
50
|
+
# Fetch the schemas for all resources types assocaited with the API's returning data
|
51
|
+
# @return [Hash] - A hash of all all ResourceType Schemas
|
52
|
+
def self.schemas
|
53
|
+
response = HTTParty.get([Sailpoint::Config.url('scim'), 'v2/Schemas'].join('/'),
|
54
|
+
headers: Sailpoint::Config.auth_header,
|
55
|
+
output: 'json')
|
56
|
+
JSON.parse(response&.body || '{}')
|
57
|
+
end
|
58
|
+
|
59
|
+
# Fetch a list of all ServiceProviders associated with the data being served by the API
|
60
|
+
# @return [Hash] - A hashed list of SailPoint service providers associated with the IdentityIQ Instance
|
61
|
+
def self.service_providers
|
62
|
+
response = HTTParty.get([Sailpoint::Config.url('scim'), 'v2/ServiceProviderConfig'].join('/'),
|
63
|
+
headers: Sailpoint::Config.auth_header,
|
64
|
+
output: 'json')
|
65
|
+
JSON.parse(response&.body || '{}')
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns a list of all users from the associated organizations
|
69
|
+
# @return [Hash] - All users entries from the organizations sources
|
70
|
+
def self.users
|
71
|
+
response = HTTParty.get([Sailpoint::Config.url('scim'), 'v2/Users'].join('/'),
|
72
|
+
headers: Sailpoint::Config.auth_header,
|
73
|
+
output: 'json')
|
74
|
+
JSON.parse(response&.body || '{}')
|
75
|
+
end
|
76
|
+
|
77
|
+
# Returns a list of data attributes for the ResourceType -> Users
|
78
|
+
# @return [Hash] - A hash to describe the user schema attributes
|
79
|
+
def self.user_resource_types
|
80
|
+
response = HTTParty.get([Sailpoint::Config.url('scim'), 'v2/ResourceTypes/User'].join('/'),
|
81
|
+
headers: Sailpoint::Config.auth_header,
|
82
|
+
output: 'json')
|
83
|
+
JSON.parse(response&.body || '{}')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sailpoint
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brandon Hicks
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-09-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.17.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.17.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.17'
|
34
|
+
- - "<"
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '3.0'
|
37
|
+
type: :development
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '1.17'
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '3.0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '10.0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '10.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rspec
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 3.8.0
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 3.8.0
|
75
|
+
description:
|
76
|
+
email:
|
77
|
+
- tarellel@gmail.com
|
78
|
+
executables: []
|
79
|
+
extensions: []
|
80
|
+
extra_rdoc_files:
|
81
|
+
- README.md
|
82
|
+
- LICENSE.txt
|
83
|
+
files:
|
84
|
+
- LICENSE.txt
|
85
|
+
- README.md
|
86
|
+
- bin/console
|
87
|
+
- bin/setup
|
88
|
+
- lib/sailpoint.rb
|
89
|
+
- lib/sailpoint/config.rb
|
90
|
+
- lib/sailpoint/helpers.rb
|
91
|
+
- lib/sailpoint/rest.rb
|
92
|
+
- lib/sailpoint/scim.rb
|
93
|
+
- lib/sailpoint/version.rb
|
94
|
+
homepage:
|
95
|
+
licenses:
|
96
|
+
- MIT
|
97
|
+
metadata: {}
|
98
|
+
post_install_message:
|
99
|
+
rdoc_options: []
|
100
|
+
require_paths:
|
101
|
+
- lib
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '2.5'
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
requirements: []
|
113
|
+
rubygems_version: 3.0.6
|
114
|
+
signing_key:
|
115
|
+
specification_version: 4
|
116
|
+
summary: A Sailpoint API helper
|
117
|
+
test_files: []
|