Skip to content

Instantly share code, notes, and snippets.

@klondikemarlen
Last active February 4, 2025 21:44
Show Gist options
  • Save klondikemarlen/61cb36f4e3eb418eee5bf6195e5eb979 to your computer and use it in GitHub Desktop.
Save klondikemarlen/61cb36f4e3eb418eee5bf6195e5eb979 to your computer and use it in GitHub Desktop.
A handy script to walk the user through cleaning up and re-permissioning a user in Proof.
##
# proof_user_cleanup_and_repermission.rb
#
# A handy script to walk the user through cleaning up and re-permissioning a user in Proof.
#
# Ensure this script is run within the Rails environment.
#
# Usage:
# require 'open-uri'; eval(URI.open('https://gist.github.com/klondikemarlen/61cb36f4e3eb418eee5bf6195e5eb979/raw').read); UserCleanupAndRepermission.call
#
# For updates do:
# UserCleanupAndRepermission.update_from_web; UserCleanupAndRepermission.call
#
class UserCleanupAndRepermission
def self.update_from_web
Object.send(:remove_const, :UserCleanupAndRepermission) if defined?(UserCleanupAndRepermission)
gist_url = "https://gist.github.com/klondikemarlen/61cb36f4e3eb418eee5bf6195e5eb979/raw"
script = URI.open(gist_url).read
eval(script)
puts "Successfully updated UserCleanupAndRepermission class from the web."
end
def self.call
new.call
end
def call
menu_options = {
"1" => "List Active Directory Profiles",
"2" => "Re-permission",
"3" => "Deactivate",
"4" => "Manage Administration Privileges",
"5" => "Exit",
}.freeze
loop do
user = select_user
return unless user
puts "\nYou have selected: #{user.full_name} (#{user.email})"
action = prompt_action_choice(menu_options)
case action
when "1"
list_active_directory_profiles(user)
when "2"
repermission_user(user)
when "3"
deactivate_user(user)
when "4"
manage_administration_privileges(user)
when "5"
puts "Exiting."
exit
else
puts "Invalid choice. Please select a valid option."
end
# After performing the action, prompt to select a new user
puts "\nAction completed. Returning to user selection."
end
end
protected
def list_active_directory_profiles(user)
puts "\nFetching Active Directory profiles for the user..."
active_directory_profiles = ActiveDirectoryProfile.where(user_id: user.id)
if active_directory_profiles.empty?
puts "No Active Directory profiles found."
return
end
puts "\nUser Active Directory Profiles:"
active_directory_profiles.each_with_index do |adp, index|
puts "#{index + 1}. #{active_directory_profile_description(adp)}"
end
end
def repermission_user(user)
puts "\nYou have chosen to re-permission the user."
clean_up_units(user)
clean_up_active_directory_profiles(user)
reset_remote_permissions(user)
puts "\nRe-permission process completed for user '#{user.full_name}'."
end
def deactivate_user(user)
puts "\nYou have chosen to deactivate the user."
return unless confirm_action("Proceed with deactivation?")
Users::DeactivateFlow.new(user: user).call!
puts "User '#{user.full_name}' has been deactivated."
end
def clean_up_units(user)
loop do
units = user.units.reload
if units.empty?
puts "\nUser is not associated with any units."
return
end
puts "\nSelect a unit to remove."
puts "User Units:"
unit =
prompt_selection(
units,
->(unit, index) { puts "#{index + 1}. #{unit.name} (ID: #{unit.id})" },
)
return unless unit.present?
return unless confirm_action("Remove unit '#{unit.name}' from user?")
Units::SetUserPrivilegeFlow.new(unit: unit, user: user, privilege: :none).call!
puts "Removed unit '#{unit.name}' from user."
end
end
def clean_up_active_directory_profiles(user)
loop do
puts "\nFetching Active Directory profiles for the user..."
active_directory_profiles = ActiveDirectoryProfile.where(user_id: user.id)
if active_directory_profiles.empty?
puts "No Active Directory profiles found."
return
end
puts "\nSelect an Active Directory profile to remove."
puts "User Active Directory Profiles:"
adp =
prompt_selection(
active_directory_profiles,
->(adp, index) { puts "#{index + 1}. #{active_directory_profile_description(adp)}" },
)
return unless adp.present?
unless confirm_action(
"Remove Active Directory Profile #{active_directory_profile_description(adp)}?",
)
return
end
adp.destroy
puts "Active Directory Profile #{active_directory_profile_description(adp)} has been removed."
end
end
def reset_connection_with_sharepoint(user)
end
def reset_remote_permissions(user)
return unless confirm_action("Reset remote permissions for user #{user.full_name}?")
input = prompt("Enter the number of months to go back for resetting permissions (default: 2):")
months_ago = input.empty? ? 2 : input.to_i
return if months_ago <= 0
sp_users = SharepointUser.where(user_id: user.id, sharepoint_server_id: 40)
if sp_users.exists?
sp_users.find_each do |sp_user|
sp_user.destroy
puts "SharepointUser ID #{sp_user.id} has been soft-deleted."
end
else
puts "No SharepointUser records found for the user."
end
user.update skip_external_permissioning: false,
skip_document_storage_permissioning_enabled_at: nil
Participant
.where(user_id: user.id, entity_type: "Routing")
.where("created_at > ?", months_ago.months.ago)
.find_each do |participant|
participant.update(remote_permissions_established_at: nil)
routing = Routing.find(participant.entity_id)
DocumentStore::AuthorizeParticipantJob.perform_now(
participant: participant,
entity: routing,
)
end
puts "\nRemote permissions have been reset for user '#{user.full_name}' for participants created in the last #{months_ago} months."
end
def manage_administration_privileges(user)
menu_options = {
"1" => "Add a new privilege",
"2" => "Remove an existing privilege",
"3" => "Exit",
}.freeze
loop do
administration_privileges = user.administration_privileges.reload
if administration_privileges.empty?
puts "\nUser has no administration privileges."
else
puts "\nCurrent Administration Privileges:"
administration_privileges.each_with_index do |privilege, index|
puts "#{index + 1}. #{privilege_description(privilege)}, Created At: #{privilege.created_at.iso8601}"
end
end
action = prompt_action_choice(menu_options)
case action
when "1"
add_administration_privilege(user)
when "2"
remove_administration_privilege(user, administration_privileges)
when "3"
puts "Exiting administration privilege management."
return
else
puts "Invalid choice. Please select a valid option."
end
end
end
def add_administration_privilege(user)
puts "\nAdding a new administration privilege for user #{user.full_name}..."
# Prompt for admin level
admin_level =
prompt("\nSelect the administrative level:\n1. Branch\n2. Division\n3. Department\n> ")
case admin_level
when "1"
assign_privilege(user, level: :branch)
when "2"
assign_privilege(user, level: :division)
when "3"
assign_privilege(user, level: :department)
else
puts "\nInvalid selection. No privilege assigned."
end
end
def remove_administration_privilege(user, administration_privileges)
return puts "User has no administration privileges." if administration_privileges.empty?
puts "\nSelect an administration privilege to remove."
privilege =
prompt_selection(
administration_privileges,
->(privilege, index) do
puts "#{index + 1}. #{privilege_description(privilege)}, Created At: #{privilege.created_at.iso8601}"
end,
)
return unless privilege.present?
confirm_message = [
"Remove administration privilege for:",
privilege_description(privilege),
].join("\n")
return unless confirm_action(confirm_message)
privilege.destroy
puts "Removed administration privilege for #{privilege_description(privilege)}."
end
private
# Utility Methods
def assign_privilege(user, level:)
case level
when :branch
branch = user.branch
unless branch.present?
puts "Branch information not available for this user."
return
end
division = user.division
unless division.present?
puts "Division information not available for this user."
return
end
privilege =
UserAdministrationPrivilege.find_or_create_by!(
user: user,
department: user.department,
division: division,
branch: branch,
)
puts "\nAdded branch-level administration privilege for department: #{privilege.department}, division: #{privilege.division}, branch: #{privilege.branch}."
when :division
division = user.division
unless division.present?
puts "Division information not available for this user."
return
end
privilege =
UserAdministrationPrivilege.find_or_create_by!(
user: user,
department: user.department,
division: division,
branch: nil,
)
puts "\nAdded division-level administration privilege for department: #{privilege.department}, division: #{division}."
when :department
privilege =
UserAdministrationPrivilege.find_or_create_by!(
user: user,
department: user.department,
division: nil,
branch: nil,
)
puts "\nAdded department-level administration privilege for department: #{privilege.department}."
end
end
def active_directory_profile_description(adp)
[
"ID: #{adp.id}",
"Email: #{adp.email}",
"SAM Account: #{adp.samaccountname}",
"Department: #{adp.department}",
"CN: #{adp.cn}",
"DN: #{adp.dn}",
"Created At: #{adp.created_at.iso8601}",
].join(", ")
end
def privilege_description(privilege)
[
"Department: #{privilege.department}",
privilege.division.presence && "Division: #{privilege.division}",
privilege.branch.presence && "Branch: #{privilege.branch}",
].compact.join(", ")
end
def prompt_action_choice(options)
puts "\nWhat would you like to do?"
options.each { |key, value| puts "#{key}. #{value}" }
prompt("> ")
end
# General method to display and select an item from a list
def prompt_selection(items, display_method)
items.each_with_index(&display_method)
input = prompt("\nEnter the number to select an item, or press Enter to skip:")
return if input.empty?
selected_index = input.to_i - 1
return items[selected_index] if valid_index?(selected_index, items.size)
puts "Invalid selection."
nil
end
def select_user
search_query = prompt("Enter email or name to search for users, or press Enter to exit:")
return unless search_query.present?
users = User.search(search_query).limit(10)
if users.empty?
puts "No users found."
return nil
end
prompt_selection(
users,
->(user, index) { puts "#{index + 1}. #{user.full_name} (#{user.email})" },
)
end
def prompt(message)
puts message
print "> "
gets.chomp.strip
end
def confirm_action(message)
input = prompt("#{message} (y/n)")
input.casecmp("y").zero?
end
def valid_index?(index, size)
index.between?(0, size - 1)
end
end
# Start the script if this file is executed directly
UserCleanupAndRepermission.call if __FILE__ == $PROGRAM_NAME
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment