mirror of https://github.com/gophish/gophish
Added ability to allow admin to 'su' to other accounts (#1812)
* Added ability to allow admin to 'su' to other accounts * Naming convention and user message modifications * Removed debug statementpull/1557/merge
parent
26e82cb2e3
commit
38a6a77c9c
|
@ -130,6 +130,7 @@ func (as *AdminServer) registerRoutes() {
|
||||||
router.HandleFunc("/settings", mid.Use(as.Settings, mid.RequireLogin))
|
router.HandleFunc("/settings", mid.Use(as.Settings, mid.RequireLogin))
|
||||||
router.HandleFunc("/users", mid.Use(as.UserManagement, mid.RequirePermission(models.PermissionModifySystem), mid.RequireLogin))
|
router.HandleFunc("/users", mid.Use(as.UserManagement, mid.RequirePermission(models.PermissionModifySystem), mid.RequireLogin))
|
||||||
router.HandleFunc("/webhooks", mid.Use(as.Webhooks, mid.RequirePermission(models.PermissionModifySystem), mid.RequireLogin))
|
router.HandleFunc("/webhooks", mid.Use(as.Webhooks, mid.RequirePermission(models.PermissionModifySystem), mid.RequireLogin))
|
||||||
|
router.HandleFunc("/impersonate", mid.Use(as.Impersonate, mid.RequirePermission(models.PermissionModifySystem), mid.RequireLogin))
|
||||||
// Create the API routes
|
// Create the API routes
|
||||||
api := api.NewServer(api.WithWorker(as.worker))
|
api := api.NewServer(api.WithWorker(as.worker))
|
||||||
router.PathPrefix("/api/").Handler(api)
|
router.PathPrefix("/api/").Handler(api)
|
||||||
|
@ -269,6 +270,24 @@ func (as *AdminServer) Webhooks(w http.ResponseWriter, r *http.Request) {
|
||||||
getTemplate(w, "webhooks").ExecuteTemplate(w, "base", params)
|
getTemplate(w, "webhooks").ExecuteTemplate(w, "base", params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Impersonate allows an admin to login to a user account without needing the password
|
||||||
|
func (as *AdminServer) Impersonate(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
if r.Method == "POST" {
|
||||||
|
username := r.FormValue("username")
|
||||||
|
u, err := models.GetUserByUsername(username)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
http.Error(w, err.Error(), http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
session := ctx.Get(r, "session").(*sessions.Session)
|
||||||
|
session.Values["id"] = u.Id
|
||||||
|
session.Save(r, w)
|
||||||
|
}
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
}
|
||||||
|
|
||||||
// Login handles the authentication flow for a user. If credentials are valid,
|
// Login handles the authentication flow for a user. If credentials are valid,
|
||||||
// a session is created
|
// a session is created
|
||||||
func (as *AdminServer) Login(w http.ResponseWriter, r *http.Request) {
|
func (as *AdminServer) Login(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
|
@ -115,6 +115,55 @@ const deleteUser = (id) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const impersonate = (id) => {
|
||||||
|
var user = users.find(x => x.id == id)
|
||||||
|
if (!user) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Swal.fire({
|
||||||
|
title: "Are you sure?",
|
||||||
|
html: "You will be logged out of your account and logged in as <strong>" + escapeHtml(user.username) + "</strong>",
|
||||||
|
type: "warning",
|
||||||
|
animation: false,
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: "Swap User",
|
||||||
|
confirmButtonColor: "#428bca",
|
||||||
|
reverseButtons: true,
|
||||||
|
allowOutsideClick: false,
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.value) {
|
||||||
|
|
||||||
|
fetch('/impersonate', {
|
||||||
|
method: 'post',
|
||||||
|
body: "username=" + user.username + "&csrf_token=" + encodeURIComponent(csrf_token),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
}).then((response) => {
|
||||||
|
if (response.status == 200) {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Success!",
|
||||||
|
html: "Successfully changed to user <strong>" + escapeHtml(user.username) + "</strong>.",
|
||||||
|
type: "success",
|
||||||
|
showCancelButton: false,
|
||||||
|
confirmButtonText: "Home",
|
||||||
|
allowOutsideClick: false,
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.value) {
|
||||||
|
window.location.href = "/"
|
||||||
|
}});
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: "Error!",
|
||||||
|
type: "error",
|
||||||
|
html: "Failed to change to user <strong>" + escapeHtml(user.username) + "</strong>.",
|
||||||
|
showCancelButton: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const load = () => {
|
const load = () => {
|
||||||
$("#userTable").hide()
|
$("#userTable").hide()
|
||||||
|
@ -136,7 +185,11 @@ const load = () => {
|
||||||
userTable.row.add([
|
userTable.row.add([
|
||||||
escapeHtml(user.username),
|
escapeHtml(user.username),
|
||||||
escapeHtml(user.role.name),
|
escapeHtml(user.role.name),
|
||||||
"<div class='pull-right'><button class='btn btn-primary edit_button' data-toggle='modal' data-backdrop='static' data-target='#modal' data-user-id='" + user.id + "'>\
|
"<div class='pull-right'>\
|
||||||
|
<button class='btn btn-warning impersonate_button' data-user-id='" + user.id + "'>\
|
||||||
|
<i class='fa fa-retweet'></i>\
|
||||||
|
</button>\
|
||||||
|
<button class='btn btn-primary edit_button' data-toggle='modal' data-backdrop='static' data-target='#modal' data-user-id='" + user.id + "'>\
|
||||||
<i class='fa fa-pencil'></i>\
|
<i class='fa fa-pencil'></i>\
|
||||||
</button>\
|
</button>\
|
||||||
<button class='btn btn-danger delete_button' data-user-id='" + user.id + "'>\
|
<button class='btn btn-danger delete_button' data-user-id='" + user.id + "'>\
|
||||||
|
@ -180,4 +233,7 @@ $(document).ready(function () {
|
||||||
$("#userTable").on('click', '.delete_button', function (e) {
|
$("#userTable").on('click', '.delete_button', function (e) {
|
||||||
deleteUser($(this).attr('data-user-id'))
|
deleteUser($(this).attr('data-user-id'))
|
||||||
})
|
})
|
||||||
|
$("#userTable").on('click', '.impersonate_button', function (e) {
|
||||||
|
impersonate($(this).attr('data-user-id'))
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue