diff --git a/core/src/main/java/hudson/model/User.java b/core/src/main/java/hudson/model/User.java
index 22aa5bb37af61a25bb392bf996c92e198383a3be..5f302fe0c9daa61f858cd5c05d9c99df3a74f34a 100644
--- a/core/src/main/java/hudson/model/User.java
+++ b/core/src/main/java/hudson/model/User.java
@@ -48,6 +48,7 @@ import org.kohsuke.stapler.export.ExportedBean;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.FileFilter;
@@ -302,6 +303,7 @@ public class User extends AbstractModelObject implements AccessControlled, Savea
}
private static volatile long lastScanned;
+
/**
* Gets all the users.
*/
@@ -406,6 +408,19 @@ public class User extends AbstractModelObject implements AccessControlled, Savea
SaveableListener.fireOnChange(this, getConfigFile());
}
+ /**
+ * Deletes the data directory and removes this user from Hudson.
+ *
+ * @throws IOException
+ * if we fail to delete.
+ */
+ public synchronized void delete() throws IOException {
+ synchronized (byName) {
+ byName.remove(id);
+ Util.deleteRecursive(new File(getRootDir(), id));
+ }
+ }
+
/**
* Exposed remote API.
*/
@@ -447,6 +462,22 @@ public class User extends AbstractModelObject implements AccessControlled, Savea
rsp.sendRedirect(".");
}
+ /**
+ * Deletes this user from Hudson.
+ */
+ public void doDoDelete(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException {
+ requirePOST();
+ checkPermission(Hudson.ADMINISTER);
+ if (id.equals(Hudson.getAuthentication().getName())) {
+ rsp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Cannot delete self");
+ return;
+ }
+
+ delete();
+
+ rsp.sendRedirect2("../..");
+ }
+
public void doRssAll( StaplerRequest req, StaplerResponse rsp ) throws IOException, ServletException {
rss(req, rsp, " all builds", RunList.fromRuns(getBuilds()));
}
@@ -528,6 +559,14 @@ public class User extends AbstractModelObject implements AccessControlled, Savea
return getACL().hasPermission(permission);
}
+ /**
+ * With ADMINISTER permission, can delete users with persisted data but can't delete self.
+ */
+ public boolean canDelete() {
+ return hasPermission(Hudson.ADMINISTER) && !id.equals(Hudson.getAuthentication().getName())
+ && new File(getRootDir(), id).exists();
+ }
+
public Object getDynamic(String token) {
for (UserProperty property: getProperties().values()) {
if (property instanceof Action) {
diff --git a/core/src/main/resources/hudson/model/User/delete.jelly b/core/src/main/resources/hudson/model/User/delete.jelly
new file mode 100644
index 0000000000000000000000000000000000000000..2b227b349d2612462f78d8adae96f4d7f878259e
--- /dev/null
+++ b/core/src/main/resources/hudson/model/User/delete.jelly
@@ -0,0 +1,35 @@
+
+
+