diff options
| -rw-r--r-- | lib/tasks/users.rake | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/lib/tasks/users.rake b/lib/tasks/users.rake new file mode 100644 index 00000000..cdee7fc8 --- /dev/null +++ b/lib/tasks/users.rake | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | namespace :users do | ||
| 2 | desc "Clear a user's second factor from the shell. LOGIN=name. " \ | ||
| 3 | "The recovery path when an admin loses their device: elevation " \ | ||
| 4 | "requires a code, resetting someone else's factor requires " \ | ||
| 5 | "elevation, and self-service disable requires a current code -- so " \ | ||
| 6 | "with every admin locked out there is no in-app way back." | ||
| 7 | task :clear_otp => :environment do | ||
| 8 | login = ENV["LOGIN"].to_s.strip.downcase | ||
| 9 | abort "usage: LOGIN=name rake users:clear_otp" if login.empty? | ||
| 10 | |||
| 11 | user = User.find_by(:login => login) | ||
| 12 | abort "no such user: #{login}" if user.nil? | ||
| 13 | |||
| 14 | unless user.otp_enrolled? | ||
| 15 | puts "#{user.login} has no second factor enrolled; nothing to do." | ||
| 16 | next | ||
| 17 | end | ||
| 18 | |||
| 19 | # Witnessed with the user as their own actor: there is no logged-in | ||
| 20 | # admin to attribute it to, and an unattributed hole in the log is worse | ||
| 21 | # than one that says "from the shell". | ||
| 22 | user.disable_otp!(:actor => user) | ||
| 23 | puts "Cleared the second factor for #{user.login}. " \ | ||
| 24 | "They can re-enrol under My account; recorded in the action log." | ||
| 25 | end | ||
| 26 | end | ||
