diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 98abf990f9d7b7b34df5632b510c8a9f8ff4a39e..86d995b3395a45d48f26c2cd3299483a4503ea2f 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -37,6 +37,16 @@ class Admin::UsersController < Admin::ApplicationController
     end
   end
 
+  def unlock
+    if @user.access_locked? || @user.max_login_attempts?
+      @user.unlock_access!
+      @user.unlock_mfa!
+      redirect_back(fallback_location: [:admin, @user], notice: 'User account was successfully unlocked.')
+    else
+      redirect_back(fallback_location: [:admin, @user], alert: 'User account was not locked.')
+    end
+  end
+
   def destroy
     @user.destroy
     redirect_to admin_users_url, notice: "User was successfully destroyed."
diff --git a/app/views/admin/users/_lock.html.erb b/app/views/admin/users/_lock.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..02a9f27e919881c718bdecec6908ac6206dcbe36
--- /dev/null
+++ b/app/views/admin/users/_lock.html.erb
@@ -0,0 +1,17 @@
+<% if @user.max_login_attempts? %>
+  <div class="alert alert-danger">
+    This user account is currently <i>locked</i> due to too many MFA attempts.
+    <%= link_to  'Unlock it now!', unlock_admin_user_path(@user), method: :patch, class: 'alert-link' if can?(:update, @user) %>
+  </div>
+<% end %>
+
+<% if @user.access_locked? %>
+  <div class="alert alert-danger">
+    This user account is currently <i>locked</i>.
+    <% if [:time, :both].include?(Rails.configuration.devise.unlock_strategy) %>
+      <% distance = distance_of_time_in_words(@user.locked_at + Rails.configuration.devise.unlock_in - Time.now.utc) %>
+      <%= "It will unlock automatically in <i>#{distance}</i>.".html_safe %>
+    <% end %>
+    <%= link_to  'Unlock it now!', unlock_admin_user_path(@user), method: :patch, class: 'alert-link' if can?(:update, @user) %>
+  </div>
+<% end %>
diff --git a/app/views/admin/users/edit.html.erb b/app/views/admin/users/edit.html.erb
index f4f273fddd3ac869eb76ad5f28eb11c457d8b131..8b2e76b84d2226034867d8a8dfcc0543d0e777ef 100644
--- a/app/views/admin/users/edit.html.erb
+++ b/app/views/admin/users/edit.html.erb
@@ -1,3 +1,5 @@
 <% content_for :title, @user %>
 
+<%= render 'lock' %>
+
 <%= render 'form', user: @user %>
diff --git a/app/views/admin/users/show.html.erb b/app/views/admin/users/show.html.erb
index 667f0b0c8878f2c2732d1c3097bffa567dd71218..6dc4aaca7f510814d69cde160be019cfaae351ca 100644
--- a/app/views/admin/users/show.html.erb
+++ b/app/views/admin/users/show.html.erb
@@ -1,5 +1,7 @@
 <% content_for :title, @user %>
 
+<%= render 'lock' %>
+
 <p>
   <strong>First name:</strong>
   <%= @user.first_name %>
diff --git a/config/routes.rb b/config/routes.rb
index 7612e90a35f2968074f16ceaafa3ddda25108f93..a1e9a7a4dc06563928746fd45775b59b61e0553b 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -10,7 +10,11 @@ Rails.application.routes.draw do
   resources :languages
 
   namespace :admin do
-    resources :users
+    resources :users do
+      member do
+        patch 'unlock' => 'users#unlock'
+      end
+    end
     draw 'education'
     draw 'research'
     draw 'communication'