-
Notifications
You must be signed in to change notification settings - Fork 3
/
pdk_deactivate.rb
executable file
·161 lines (145 loc) · 4.54 KB
/
pdk_deactivate.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/env ruby
# frozen_string_literal: true
# Usage:
#
# ./pdk_deactivate.rb people.json deactivation_emails.txt
#
# where:
#
# - "people.json" is a list of ALL the people, ALL the fields downloaded
# from pdk.io in JSON format:
# https://pdk.io/appliances/1071P6X/reports/people/saved-reports
#
# - "emails.txt" is the email addr of the person to deactivate, one email
# per line, e.g.
#
#
# - needs two environment variables
# PDK_CLIENT_ID=
# PDK_CLIENT_SECRET=
#
require 'json'
require 'httparty'
require 'base64'
class Person
attr_accessor :id, :first_name, :last_name, :email, :photo_url, :partition,
:enabled, :active_date, :expire_date, :pin,
:duress_pin, :custom_attributes,
:metadata, :groups, :credentials
def initialize(person)
person.keys.each do |key|
instance_variable_set("@#{to_snake_case(key)}", person[key])
end
end
def partition_id
raise 'Non-default partition Id' if @partition != 'Default'
0 # Default partition for us is "0"
end
# Contains only the _required_ components of the PUT request
def to_h
{
firstName: @first_name,
lastName: @last_name,
partition: partition_id,
enabled: @enabled,
activeDate: @active_date,
expireDate: @expire_date,
pin: @pin,
duressPin: @duress_pin,
email: @email
}
end
# e.g. '02/03/2024 11:11:14'
def disable!
# @expire_date ||= Time.now.strftime("%m/%d/%Y %H:%M:%S")
@enabled = false
end
def to_json(*_args)
JSON.generate(to_h)
end
end
def to_snake_case(string)
# Remove spaces and replace them with underscores
string.gsub(' ', '_').downcase
end
def id_token
client_id_secret = "#{ENV['PDK_CLIENT_ID']}:#{ENV['PDK_CLIENT_SECRET']}"
encoded_client_id_secret = Base64.strict_encode64(client_id_secret)
response = HTTParty.post(
'https://accounts.pdk.io/oauth2/token',
headers: {
'Authorization' => "Basic #{encoded_client_id_secret}",
'Content-Type' => 'application/x-www-form-urlencoded'
},
body: 'grant_type=client_credentials'
)
if response.code != 200
puts response.body, response.code, response.message, response.headers.inspect
raise "couldn't authenticate id_token!"
end
JSON.parse(response.body)['id_token']
end
def panel_token
panel_id = '1071P6X'
response = HTTParty.post(
"https://accounts.pdk.io/api/panels/#{panel_id}/token",
headers: {
'Authorization' => "Bearer #{id_token}"
},
body: 'grant_type=client_credentials'
)
if response.code != 200
puts response.body, response.code, response.message, response.headers.inspect
raise "couldn't authenticate panel_token!"
end
JSON.parse(response.body)['token']
end
def lock_out(user, panel_token)
panel_id = '1071P6X'
response = HTTParty.put(
"https://panel-#{panel_id}.pdk.io/api/persons/#{user.id}",
headers: {
'Authorization' => "Bearer #{panel_token}",
'Content-Type' => 'application/json'
},
body: user.to_json
)
if response.code == 204
"✅ Locked-out #{user.first_name} #{user.last_name} email: #{user.email} id: #{user.id}"
else
puts response.body, response.code, response.message, response.headers.inspect
"⛔️ Failed to lock-out #{user.first_name} #{user.last_name} email: #{user.email} id: #{user.id}"
end
end
raise 'Usage: deactivate.rb people.json deactivation_emails.txt' unless ARGV.length == 2
raise 'Must `export PDK_CLIENT_ID=<your PDK client id>`' if ENV['PDK_CLIENT_ID'].nil?
raise 'Must `export PDK_CLIENT_SECRET=<your PDK client secret>`' if ENV['PDK_CLIENT_SECRET'].nil?
token = panel_token
people_hash = JSON.parse(File.read(ARGV[0]))
people = people_hash.map do |person|
Person.new(person)
end
File.foreach(ARGV[1]) do |line|
deactivation_email = line.chomp
users = people.select { |person| person.email == deactivation_email }
if users.length < 1
puts "⛔️ email '#{deactivation_email}' doesn't have any corresponding users!"
next
end
if users.length > 1
puts "⛔️ email '#{deactivation_email}' has several users: " +
users.map { |user| "#{user.first_name} #{user.last_name}" }.join(', ')
next
end
user = users.first # by now we only have one user
puts "Should I lock out #{user.first_name} #{user.last_name} #{user.email}?"
puts `grep -i "#{user.last_name}" *.csv | sed 's/^/ /'`
response = $stdin.gets.chomp
if response.downcase.start_with?('y')
user.disable!
puts lock_out(user, token)
else
puts "⚠️ Skipping #{user.first_name} #{user.last_name} #{user.email}"
end
end