Improved circuit breaker admin UI
This commit is contained in:
parent
117d42615f
commit
ba11039732
1
circuitBreaker.txt
Normal file
1
circuitBreaker.txt
Normal file
@ -0,0 +1 @@
|
||||
Disabled sign-up temporarily
|
5
pom.xml
5
pom.xml
@ -78,6 +78,11 @@
|
||||
<artifactId>activation</artifactId>
|
||||
<version>1.1.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.kohsuke.stapler</groupId>
|
||||
<artifactId>stapler</artifactId>
|
||||
<version>1.233</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.kohsuke.stapler</groupId>
|
||||
<artifactId>stapler-openid-server</artifactId>
|
||||
|
@ -16,6 +16,8 @@ but it should look something like the following:
|
||||
recaptchaPublicKey=6Ld--8ASAAAAANHmHaM1sdSYshtmXTin1BNtaw86
|
||||
recaptchaPrivateKey=*****
|
||||
managerPassword=*****
|
||||
circuitBreakerFile=./circuitBreaker.txt
|
||||
url=http://localhost:8080/account/
|
||||
|
||||
Finally, run the application with Jetty, then access `http://localhost:8080/`:
|
||||
|
||||
|
@ -29,6 +29,13 @@ public class AdminUI {
|
||||
this.app = app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes the circuit breaker to UI.
|
||||
*/
|
||||
public CircuitBreaker getCircuitBreaker() {
|
||||
return app.circuitBreaker;
|
||||
}
|
||||
|
||||
public HttpResponse doSearch(@QueryParameter String word) throws NamingException {
|
||||
List<User> all = new ArrayList<User>();
|
||||
LdapContext con = app.connect();
|
||||
|
@ -68,9 +68,13 @@ public class Application {
|
||||
*/
|
||||
public final JenkinsOpenIDServer openid;
|
||||
|
||||
// not exposing this to UI
|
||||
/*package*/ final CircuitBreaker circuitBreaker;
|
||||
|
||||
public Application(Parameters params) throws IOException {
|
||||
this.params = params;
|
||||
this.openid = new JenkinsOpenIDServer(this);
|
||||
this.circuitBreaker = new CircuitBreaker(params);
|
||||
}
|
||||
|
||||
public Application(Properties config) throws IOException {
|
||||
@ -141,7 +145,7 @@ public class Application {
|
||||
return maybeSpammer(userid, firstName, lastName, email, ip, null);
|
||||
}
|
||||
|
||||
checkCircuitBreakerOn(userid);
|
||||
circuitBreaker.check();
|
||||
|
||||
String password = createRecord(userid, firstName, lastName, email);
|
||||
LOGGER.info("User "+userid+" is from "+ip);
|
||||
@ -151,20 +155,6 @@ public class Application {
|
||||
return new HttpRedirect("doneMail");
|
||||
}
|
||||
|
||||
/**
|
||||
* We allow ourselves to temporarily shut down the sign up, primarily to combat spam.
|
||||
*/
|
||||
private void checkCircuitBreakerOn(String userid) throws IOException {
|
||||
String f = params.circuitBreakerFile();
|
||||
if (f!=null) {
|
||||
File breaker = new File(f);
|
||||
if (System.currentTimeMillis() < breaker.lastModified()) {
|
||||
LOGGER.info("Rejecting sign up for "+userid+" due to circuit breaker");
|
||||
throw new UserError(FileUtils.readFileToString(breaker));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private HttpResponse maybeSpammer(String userid, String firstName, String lastName, String email, String ip, Answer a) throws MessagingException, UnsupportedEncodingException {
|
||||
String text = String.format(
|
||||
"Rejecting, likely spam: %s / ip=%s email=%s userId=%s lastName=%s firstName=%s",
|
||||
|
73
src/main/java/org/jenkinsci/account/CircuitBreaker.java
Normal file
73
src/main/java/org/jenkinsci/account/CircuitBreaker.java
Normal file
@ -0,0 +1,73 @@
|
||||
package org.jenkinsci.account;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.kohsuke.stapler.HttpResponse;
|
||||
import org.kohsuke.stapler.HttpResponses;
|
||||
import org.kohsuke.stapler.QueryParameter;
|
||||
import org.kohsuke.stapler.interceptor.RequirePOST;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Temporarily shut-off valve to disable sign-up.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class CircuitBreaker {
|
||||
private final File file;
|
||||
|
||||
public CircuitBreaker(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public CircuitBreaker(Parameters params) {
|
||||
String f = params.circuitBreakerFile();
|
||||
if (f!=null)
|
||||
this.file = new File(f);
|
||||
else
|
||||
this.file = new File("/no-such-file");
|
||||
}
|
||||
|
||||
public boolean isOn() {
|
||||
return System.currentTimeMillis() < file.lastModified();
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if the circuit breaker is on.
|
||||
*/
|
||||
public void check() throws IOException {
|
||||
if (isOn()) {
|
||||
LOGGER.info("Rejecting sign up due to circuit breaker");
|
||||
throw new UserError(FileUtils.readFileToString(file));
|
||||
}
|
||||
}
|
||||
|
||||
@RequirePOST
|
||||
public HttpResponse doSet(@QueryParameter String time) throws ParseException {
|
||||
Date t = makeFormatter().parse(time.trim());
|
||||
file.setLastModified(t.getTime());
|
||||
return HttpResponses.plainText("Successfully set");
|
||||
}
|
||||
|
||||
/**
|
||||
* Current effective date
|
||||
*/
|
||||
public String getDate() {
|
||||
long dt = file.lastModified();
|
||||
if (dt<=0)
|
||||
return "(none)";
|
||||
else
|
||||
return makeFormatter().format(new Date(dt));
|
||||
}
|
||||
|
||||
private SimpleDateFormat makeFormatter() {
|
||||
return new SimpleDateFormat("yyyy/MM/dd HH:mm");
|
||||
}
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CircuitBreaker.class.getName());
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
<j:jelly xmlns:j="jelly:core" xmlns:t="/org/jenkinsci/backend/taglib/layout">
|
||||
<t:layout title="Administration">
|
||||
<h1>Manage Users</h1>
|
||||
<p>
|
||||
Type the user name or the e-mail address to find the user.
|
||||
</p>
|
||||
@ -9,5 +10,23 @@
|
||||
|
||||
<input type="submit" style="margin-top:2em; display:block"/>
|
||||
</form>
|
||||
|
||||
<h1 style="margin-top:2em">Set Circuit Breaker</h1>
|
||||
<p>
|
||||
Temporarily disable sign-up to fight spam until a certain time.
|
||||
All times are in US Eastern Time, where the server is.
|
||||
</p>
|
||||
<j:if test="${it.circuitBreaker.isOn()}">
|
||||
<p>
|
||||
Circuit breaker is currently on until ${it.circuitBreaker.date}.
|
||||
To disable it, set it to the time in the past, such as 2000/01/01 00:00.
|
||||
</p>
|
||||
</j:if>
|
||||
<form method="post" action="circuitBreaker/set">
|
||||
<h5>Circuit breaker is on until when? (YYYY/MM/DD HH:MM)</h5>
|
||||
<input type="text" name="time" class="text"/>
|
||||
|
||||
<input type="submit" style="margin-top:2em; display:block"/>
|
||||
</form>
|
||||
</t:layout>
|
||||
</j:jelly>
|
||||
|
Loading…
Reference in New Issue
Block a user