class Object
Constants
- DEFAULT_BASE_RETRY_DELAY
- DEFAULT_MAX_RETRIES
- DEFAULT_MAX_RETRY_DELAY
- OKTA_CLIENT_ORGURL
- OKTA_CLIENT_TOKEN
- SDM_API_ACCESS_KEY
- SDM_API_SECRET_KEY
Public Instance Methods
main()
click to toggle source
panicButton.rb suspends all users except for one admin, in the fake use case of a critical break in or something usage: ruby panicButton.rb adminuser@email.com to revert back to pre-panic state: ruby panicButton.rb revert
# File examples/panicButton.rb, line 25 def main access_key = ENV["SDM_API_ACCESS_KEY"] secret_key = ENV["SDM_API_SECRET_KEY"] if access_key == nil or secret_key == nil puts "SDM_API_ACCESS_KEY and SDM_API_SECRET_KEY must be provided" return end client = SDM::Client.new(access_key, secret_key) if ARGV.size == 1 and ARGV[0] == "revert" state_file = File.open("state.json") state = JSON.load(state_file) reinstated_count = 0 users = client.accounts.list("") users.each { |user| if user.suspended reinstated_count += 1 user.suspended = false client.accounts.update(user) end } state["attachments"].each { |attachment| begin a = SDM::AccountAttachment.new() a.account_id = attachment["account_id"] a.role_id = attachment["role_id"] client.account_attachments.create(a) rescue SDM::AlreadyExistsError rescue => ex puts "skipping creation of attachment due to error: " + ex.to_s end } state["grants"].each { |attachment| begin g = SDM::AccountGrant.new() g.account_id = attachment["account_id"] g.resource_id = attachment["resource_id"] client.account_grants.create(g) rescue SDM::AlreadyExistsError rescue => ex puts "skipping creation of grant due to error: " + ex.to_s end } puts "reinstated " + reinstated_count.to_s + " users" puts "recreated " + state["attachments"].size.to_s + " account attachments" puts "recreated " + state["grants"].size.to_s + " account grants" return end admin_email = "" if ARGV.size == 1 admin_email = ARGV[0] else puts "please provide an admin email to preserve" return 1 end admin_user_id = "" users = client.accounts.list("email:?", admin_email) users.each { |user| admin_user_id = user.id } account_attachments = client.account_attachments.list("") account_grants = client.account_grants.list("") state = { 'attachments': account_attachments.map { |x| if x.account_id != admin_user_id out = { 'account_id': x.account_id, 'role_id': x.role_id, } end }.reject { |x| x == nil }, 'grants': account_grants.map { |x| if x.account_id != admin_user_id and x.valid_until == nil out = { 'account_id': x.account_id, 'resource_id': x.resource_id, } end }.reject { |x| x == nil }, } puts "storing " + state[:attachments].size.to_s + " account attachments in state" puts "storing " + state[:grants].size.to_s + " account grants in state" state_file = File.open("state.json", "w") state_file.write(state.to_json) suspended_count = 0 users = client.accounts.list("") users.each { |user| if user.instance_of? SDM::User and user.email == admin_email next end user.suspended = true begin client.accounts.update(user) suspended_count += 1 rescue StandardError => ex puts "skipping user " + user.id + " on account of error: " + ex.to_s end } puts "suspended " + suspended_count.to_s + " users" end
okta_sync()
click to toggle source
# File examples/okta-sync/oktaSync.rb, line 25 def okta_sync if SDM_API_ACCESS_KEY == "" || SDM_API_SECRET_KEY == "" || OKTA_CLIENT_TOKEN == "" || OKTA_CLIENT_ORGURL == "" puts "SDM_API_ACCESS_KEY, SDM_API_SECRET_KEY, OKTA_CLIENT_TOKEN, and OKTA_CLIENT_ORGURL must be set" exit end report = { :start => Time.now, :oktaUsersCount => 0, :oktaUsers => [], :sdmUsersCount => 0, :sdmUsers => [], :bothUsersCount => 0, :sdmResourcesCount => 0, :sdmResources => {}, :permissionsGranted => 0, :permissionsRevoked => 0, :grants => [], :revocations => [], :matchers => {}, } plan = false verbose = false OptionParser.new do |opts| opts.banner = "Usage oktaSync.rb [options]" opts.on("-p", "--plan", "calculate changes but do not apply them") do |p| plan = p end opts.on("-v", "--verbose", "print detailed report") do |v| verbose = v end end.parse! client = SDM::Client.new(SDM_API_ACCESS_KEY, SDM_API_SECRET_KEY) okta_client = Oktakit.new(token: OKTA_CLIENT_TOKEN, api_endpoint: OKTA_CLIENT_ORGURL + "/api/v1") matchers = YAML.load(File.read("matchers.yml")) report[:matchers] = matchers all_users = okta_client.list_users({ 'query': { 'search': "profile.department eq \"Engineering\" and (status eq \"ACTIVE\")", }, }) okta_users = Array.new() all_users[0].each { |u| groups = okta_client.get_member_groups(u.id) group_names = Array.new() groups[0].each { |ug| group_names.push(ug.profile.name) } okta_users.push({ :login => u.profile.login, :first_name => u.profile.firstName, :last_name => u.profile.LastName, :groups => group_names }) } report[:oktaUsers] = okta_users report[:oktaUsersCount] = okta_users.size accounts = client.accounts.list("type:user").map { |a| [a.email, a] }.to_h report[:sdmUsers] = accounts report[:sdmUsersCount] = accounts.size grants = client.account_grants.list("").map { |ag| ag } current = {} grants.each { |g| current[g.account_id] = [] if not current[g.account_id] current[g.account_id].push({ :resource_id => g.resource_id, :id => g.id }) } desired = {} overlapping = 0 matchers["groups"].each { |group| group["resources"].each { |resourceQuery| client.resources.list(resourceQuery).each { |res| report[:sdmResources][res.id] = res okta_users.each { |u| if u[:groups].include? group["name"] account = accounts[u[:login]] if account != nil overlapping += 1 desired[account.id] = [] if not desired[account.id] desired[account.id].push(res.id) end end } } } } report[:bothUsersCount] = overlapping report[:sdmResourcesCount] = report[:sdmResources].size revocations = 0 current.each { |aid, curRes| desRes = desired[aid] desRes = [] if not desired[aid] curRes.each { |r| if not(desRes.include? r[:resource_id]) if plan puts "Plan: revoke %s from user %s\n" % [r[:resource_id], aid] else client.account_grants.delete(r[:id]) end report[:revocations].push(r[:id]) revocations += 1 end } } report[:permissionsRevoked] = revocations grants = 0 desired.each { |aid, desRes| curRes = current[aid] curRes = [] if not current[aid] desRes.each { |r| if not(curRes.map { |c| c[:resource_id] }.include? r) ag = SDM::AccountGrant.new() ag.account_id = aid ag.resource_id = r if plan puts "Plan: grant %s to user %s\n" % [r, aid] else client.account_grants.create(ag) end report[:grants].push(ag) grants += 1 end } } report[:permissionsGranted] = grants report[:complete] = Time.now if verbose puts report.to_json else puts "%d Okta users, %d strongDM users, %d overlapping users, %d grants, %d revocations" % [okta_users.size, accounts.size, overlapping, grants, revocations] end end