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 @@ + + + + + + +
+ ${%Are you sure about deleting the user from Hudson?} + + +
+
+
diff --git a/core/src/main/resources/hudson/model/User/sidepanel.jelly b/core/src/main/resources/hudson/model/User/sidepanel.jelly index 1c5230b838bcf5c27183b1e6310e72888a72a4c4..ce3050a8afd61ea55f7c3892588fca9b6794ba33 100644 --- a/core/src/main/resources/hudson/model/User/sidepanel.jelly +++ b/core/src/main/resources/hudson/model/User/sidepanel.jelly @@ -33,8 +33,11 @@ THE SOFTWARE. - + + + + - \ No newline at end of file + diff --git a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly index 1d92b01f244779db65ba1eeeea926d9b7b526076..77553dd1225726b47b4ad18f2ba785fc52325ca8 100644 --- a/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly +++ b/core/src/main/resources/hudson/security/HudsonPrivateSecurityRealm/index.jelly @@ -39,7 +39,12 @@ THE SOFTWARE. ${user} - Setting + + Setting + + Delete + +