mirror of
https://github.com/theonedev/onedev.git
synced 2025-12-08 18:26:30 +00:00
Add task button to run cancellable long task from UI
This commit is contained in:
parent
b7a2ce17f3
commit
8a0c9d0060
@ -244,6 +244,7 @@ import io.onedev.server.web.avatar.DefaultAvatarManager;
|
||||
import io.onedev.server.web.component.diff.DiffRenderer;
|
||||
import io.onedev.server.web.component.markdown.SourcePositionTrackExtension;
|
||||
import io.onedev.server.web.component.markdown.emoji.EmojiExtension;
|
||||
import io.onedev.server.web.component.taskbutton.TaskButton;
|
||||
import io.onedev.server.web.editable.DefaultEditSupportRegistry;
|
||||
import io.onedev.server.web.editable.EditSupport;
|
||||
import io.onedev.server.web.editable.EditSupportLocator;
|
||||
@ -483,6 +484,8 @@ public class CoreModule extends AbstractPluginModule {
|
||||
bind(IssueEventBroadcaster.class);
|
||||
bind(BuildEventBroadcaster.class);
|
||||
|
||||
bind(TaskButton.TaskFutureManager.class);
|
||||
|
||||
contribute(MainNavContribution.class, new MainNavContribution() {
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
package io.onedev.server.web.behavior.testform;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.unbescape.html.HtmlEscape;
|
||||
import org.unbescape.javascript.JavaScriptEscape;
|
||||
|
||||
import io.onedev.server.web.behavior.AbstractPostAjaxBehavior;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class TestFormBehavior extends AbstractPostAjaxBehavior {
|
||||
|
||||
@Override
|
||||
protected void respond(AjaxRequestTarget target) {
|
||||
String feedbackHtml;
|
||||
TestResult result = test();
|
||||
if (result.isSuccessful()) {
|
||||
feedbackHtml = String.format(
|
||||
"<div class='test-feedback alert alert-success'>%s</div>",
|
||||
HtmlEscape.escapeHtml5(result.getMessage()));
|
||||
} else {
|
||||
feedbackHtml = String.format(
|
||||
"<div class='test-feedback alert alert-danger'>%s</div>",
|
||||
HtmlEscape.escapeHtml5(result.getMessage()));
|
||||
}
|
||||
feedbackHtml = StringUtils.replace(feedbackHtml, "\n", "<br>");
|
||||
target.appendJavaScript(String.format("var $button = $('#%s');"
|
||||
+ "$button.removeAttr('disabled');"
|
||||
+ "$button.val($button[0].prevValue);"
|
||||
+ "$button.html($button[0].prevHtml);"
|
||||
+ "$button.closest('form').append('%s');"
|
||||
+ "$button.removeClass('ajax-indicator');",
|
||||
getComponent().getMarkupId(), JavaScriptEscape.escapeJavaScript(feedbackHtml)));
|
||||
}
|
||||
|
||||
public void requestTest(AjaxRequestTarget target) {
|
||||
target.appendJavaScript(String.format("var $button = $('#%s');"
|
||||
+ "$button.attr('disabled', 'disabled');"
|
||||
+ "$button[0].prevValue = $button.val();"
|
||||
+ "$button[0].prevHtml = $button.html();"
|
||||
+ "$button.val($button.val() + ' in progress...');"
|
||||
+ "$button.html($button.html() + ' in progress...');"
|
||||
+ "$button.addClass('ajax-indicator');"
|
||||
+ "$button.closest('form').children('.test-feedback').remove();",
|
||||
getComponent().getMarkupId()));
|
||||
target.appendJavaScript(getCallbackScript());
|
||||
}
|
||||
|
||||
protected abstract TestResult test();
|
||||
|
||||
}
|
||||
@ -1,48 +0,0 @@
|
||||
package io.onedev.server.web.behavior.testform;
|
||||
|
||||
public interface TestResult {
|
||||
String getMessage();
|
||||
|
||||
boolean isSuccessful();
|
||||
|
||||
public static class Successful implements TestResult {
|
||||
|
||||
private final String message;
|
||||
|
||||
public Successful(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuccessful() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Failed implements TestResult {
|
||||
|
||||
private final String message;
|
||||
|
||||
public Failed(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuccessful() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,236 @@
|
||||
package io.onedev.server.web.component.taskbutton;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.wicket.Component;
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
|
||||
import org.apache.wicket.markup.head.CssHeaderItem;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.html.form.Form;
|
||||
import org.joda.time.DateTime;
|
||||
import org.quartz.ScheduleBuilder;
|
||||
import org.quartz.SimpleScheduleBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.unbescape.html.HtmlEscape;
|
||||
import org.unbescape.javascript.JavaScriptEscape;
|
||||
|
||||
import io.onedev.commons.launcher.loader.Listen;
|
||||
import io.onedev.commons.utils.ExceptionUtils;
|
||||
import io.onedev.commons.utils.WordUtils;
|
||||
import io.onedev.commons.utils.schedule.SchedulableTask;
|
||||
import io.onedev.commons.utils.schedule.TaskScheduler;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.event.system.SystemStarted;
|
||||
import io.onedev.server.event.system.SystemStopping;
|
||||
import io.onedev.server.web.component.modal.ModalPanel;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class TaskButton extends AjaxButton {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(TaskButton.class);
|
||||
|
||||
public TaskButton(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onError(AjaxRequestTarget target, Form<?> form) {
|
||||
target.add(form);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
setOutputMarkupPlaceholderTag(true);
|
||||
}
|
||||
|
||||
private Map<String, TaskFuture> getTaskFutures() {
|
||||
return TaskFutureManager.taskFutures;
|
||||
}
|
||||
|
||||
protected void submitTask(AjaxRequestTarget target) {
|
||||
target.appendJavaScript(String.format("$('#%s').closest('form').children('.task-feedback').remove();", getMarkupId()));
|
||||
String path = getPath();
|
||||
|
||||
ExecutorService executorService = OneDev.getInstance(ExecutorService.class);
|
||||
TaskFuture future = getTaskFutures().put(path, new TaskFuture(executorService.submit(new Callable<String>() {
|
||||
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return runTask();
|
||||
}
|
||||
|
||||
})));
|
||||
if (future != null)
|
||||
future.cancel(true);
|
||||
|
||||
new ModalPanel(target) {
|
||||
|
||||
@Override
|
||||
protected Component newContent(String id) {
|
||||
String message = WordUtils.uncamel(TaskButton.this.getId()).toLowerCase();
|
||||
return new TaskWaitPanel(id, StringUtils.capitalize(message) + " in progress...") {
|
||||
|
||||
@Override
|
||||
protected void check(AjaxRequestTarget target) {
|
||||
Future<String> future = getTaskFutures().get(path);
|
||||
if (future != null) {
|
||||
if (future.isDone()) {
|
||||
if (!future.isCancelled()) {
|
||||
String feedback;
|
||||
try {
|
||||
feedback = String.format(
|
||||
"<div class='task-feedback alert alert-success'>%s</div>",
|
||||
HtmlEscape.escapeHtml5(future.get()));
|
||||
} catch (Exception e) {
|
||||
logger.error("Error " + message, e);
|
||||
String suggestedSolution = ExceptionUtils.suggestSolution(e);
|
||||
if (suggestedSolution != null)
|
||||
logger.warn("!!! " + suggestedSolution);
|
||||
feedback = "Error " + message;
|
||||
if (e.getMessage() != null)
|
||||
feedback += ": " + e.getMessage();
|
||||
feedback += ", check server log for details.";
|
||||
feedback = String.format(
|
||||
"<div class='task-feedback alert alert-danger'>%s</div>",
|
||||
HtmlEscape.escapeHtml5(feedback));
|
||||
}
|
||||
feedback = StringUtils.replace(feedback, "\n", "<br>");
|
||||
target.appendJavaScript(String.format(""
|
||||
+ "var $form = $('#%s').closest('form');"
|
||||
+ "$form.append('%s');"
|
||||
+ "$form.children('.task-feedback')[0].scrollIntoView({behavior: 'smooth', block: 'center'})",
|
||||
TaskButton.this.getMarkupId(), JavaScriptEscape.escapeJavaScript(feedback)));
|
||||
}
|
||||
close();
|
||||
}
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCancel(AjaxRequestTarget target) {
|
||||
Future<?> future = getTaskFutures().remove(path);
|
||||
if (future != null)
|
||||
future.cancel(true);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderHead(IHeaderResponse response) {
|
||||
super.renderHead(response);
|
||||
response.render(CssHeaderItem.forReference(new TaskButtonCssResourceReference()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
|
||||
super.onSubmit(target, form);
|
||||
target.add(form);
|
||||
target.focusComponent(null);
|
||||
submitTask(target);
|
||||
}
|
||||
|
||||
protected abstract String runTask();
|
||||
|
||||
@Singleton
|
||||
public static class TaskFutureManager implements SchedulableTask {
|
||||
|
||||
private static final Map<String, TaskFuture> taskFutures = new ConcurrentHashMap<>();
|
||||
|
||||
private final TaskScheduler taskScheduler;
|
||||
|
||||
private String taskId;
|
||||
|
||||
@Inject
|
||||
public TaskFutureManager(TaskScheduler taskScheduler) {
|
||||
this.taskScheduler = taskScheduler;
|
||||
}
|
||||
|
||||
@Listen
|
||||
public void on(SystemStarted event) {
|
||||
taskId = taskScheduler.schedule(this);
|
||||
}
|
||||
|
||||
@Listen
|
||||
public void on(SystemStopping event) {
|
||||
taskScheduler.unschedule(taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
for (Iterator<Map.Entry<String, TaskFuture>> it = taskFutures.entrySet().iterator(); it.hasNext();) {
|
||||
if (it.next().getValue().isExpired())
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduleBuilder<?> getScheduleBuilder() {
|
||||
return SimpleScheduleBuilder.repeatHourlyForever();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TaskFuture implements Future<String> {
|
||||
|
||||
private final Date timestamp = new Date();
|
||||
|
||||
private final Future<String> wrapped;
|
||||
|
||||
public TaskFuture(Future<String> wrapped) {
|
||||
this.wrapped = wrapped;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
return wrapped.cancel(mayInterruptIfRunning);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return wrapped.isCancelled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return wrapped.isDone();
|
||||
}
|
||||
|
||||
public boolean isExpired() {
|
||||
return timestamp.before(new DateTime().minusHours(1).toDate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get() throws InterruptedException, ExecutionException {
|
||||
return wrapped.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String get(long timeout, TimeUnit unit)
|
||||
throws InterruptedException, ExecutionException, TimeoutException {
|
||||
return get(timeout, unit);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package io.onedev.server.web.component.taskbutton;
|
||||
|
||||
import io.onedev.server.web.page.base.BaseDependentCssResourceReference;
|
||||
|
||||
public class TaskButtonCssResourceReference extends BaseDependentCssResourceReference {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public TaskButtonCssResourceReference() {
|
||||
super(TaskButtonCssResourceReference.class, "task-button.css");
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
<wicket:panel>
|
||||
<div class="task-wait">
|
||||
<div class="modal-body">
|
||||
<div wicket:id="message"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button wicket:id="cancel" class="btn btn-default">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
</wicket:panel>
|
||||
@ -0,0 +1,48 @@
|
||||
package io.onedev.server.web.component.taskbutton;
|
||||
|
||||
import org.apache.wicket.ajax.AbstractAjaxTimerBehavior;
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.markup.html.AjaxLink;
|
||||
import org.apache.wicket.markup.html.basic.Label;
|
||||
import org.apache.wicket.markup.html.panel.Panel;
|
||||
import org.apache.wicket.util.time.Duration;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
abstract class TaskWaitPanel extends Panel {
|
||||
|
||||
private final String message;
|
||||
|
||||
public TaskWaitPanel(String id, String message) {
|
||||
super(id);
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
add(new Label("message", message));
|
||||
add(new AjaxLink<Void>("cancel") {
|
||||
|
||||
@Override
|
||||
public void onClick(AjaxRequestTarget target) {
|
||||
onCancel(target);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
add(new AbstractAjaxTimerBehavior(Duration.ONE_SECOND) {
|
||||
|
||||
@Override
|
||||
protected void onTimer(AjaxRequestTarget target) {
|
||||
check(target);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract void check(AjaxRequestTarget target);
|
||||
|
||||
protected abstract void onCancel(AjaxRequestTarget target);
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
.task-wait .modal-body {
|
||||
padding: 20px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
.task-wait .modal-footer {
|
||||
text-align: center;
|
||||
}
|
||||
form>.task-feedback {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@ -16,30 +16,24 @@ import org.apache.wicket.request.cycle.RequestCycle;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
import org.apache.wicket.util.visit.IVisit;
|
||||
import org.apache.wicket.util.visit.IVisitor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
|
||||
import io.onedev.commons.utils.ExceptionUtils;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.model.support.authenticator.Authenticated;
|
||||
import io.onedev.server.web.behavior.testform.TestFormBehavior;
|
||||
import io.onedev.server.web.behavior.testform.TestResult;
|
||||
import io.onedev.server.web.component.modal.ModalPanel;
|
||||
import io.onedev.server.web.component.taskbutton.TaskButton;
|
||||
import io.onedev.server.web.editable.BeanContext;
|
||||
import io.onedev.server.web.editable.BeanEditor;
|
||||
import io.onedev.server.web.editable.PropertyUpdating;
|
||||
import io.onedev.server.web.editable.PropertyContext;
|
||||
import io.onedev.server.web.editable.PropertyEditor;
|
||||
import io.onedev.server.web.editable.PropertyUpdating;
|
||||
import io.onedev.server.web.page.admin.AdministrationPage;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class AuthenticatorPage extends AdministrationPage {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AuthenticatorPage.class);
|
||||
|
||||
private AuthenticationToken token = new AuthenticationToken();
|
||||
|
||||
public AuthenticatorPage(PageParameters params) {
|
||||
@ -55,7 +49,6 @@ public class AuthenticatorPage extends AdministrationPage {
|
||||
|
||||
PropertyEditor<Serializable> editor =
|
||||
PropertyContext.edit("editor", bean, "authenticator");
|
||||
editor.setOutputMarkupId(true);
|
||||
Button saveButton = new Button("save") {
|
||||
|
||||
@Override
|
||||
@ -67,59 +60,7 @@ public class AuthenticatorPage extends AdministrationPage {
|
||||
}
|
||||
|
||||
};
|
||||
AjaxButton testButton = new AjaxButton("test") {
|
||||
|
||||
private TestFormBehavior testBehavior;
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
add(testBehavior = new TestFormBehavior() {
|
||||
|
||||
@Override
|
||||
protected TestResult test() {
|
||||
try {
|
||||
Authenticated authenticated = bean.getAuthenticator().authenticate(
|
||||
new UsernamePasswordToken(token.getUserName(), token.getPassword()));
|
||||
StringBuilder retrievedInfoBuilder = new StringBuilder();
|
||||
if (authenticated.getFullName() != null) {
|
||||
retrievedInfoBuilder.append("Full name: ")
|
||||
.append(authenticated.getFullName())
|
||||
.append("\n");
|
||||
}
|
||||
if (authenticated.getEmail() != null) {
|
||||
retrievedInfoBuilder.append("Email: ")
|
||||
.append(authenticated.getEmail())
|
||||
.append("\n");
|
||||
}
|
||||
if (authenticated.getGroupNames() != null) {
|
||||
retrievedInfoBuilder.append("Groups: ")
|
||||
.append(Joiner.on(", ").join(authenticated.getGroupNames()))
|
||||
.append("\n");
|
||||
}
|
||||
StringBuilder messageBuilder =
|
||||
new StringBuilder("Test successful: authentication passed");
|
||||
if (retrievedInfoBuilder.length() != 0) {
|
||||
messageBuilder.append(" with below information retrieved:\n")
|
||||
.append(retrievedInfoBuilder);
|
||||
}
|
||||
return new TestResult.Successful(messageBuilder.toString());
|
||||
} catch (AuthenticationException e) {
|
||||
return new TestResult.Successful("Test successful: authentication not passed: " + e.getMessage());
|
||||
} catch (Exception e) {
|
||||
logger.error("Error testing external authentication", e);
|
||||
String suggestedSolution = ExceptionUtils.suggestSolution(e);
|
||||
if (suggestedSolution != null)
|
||||
logger.warn("!!! " + suggestedSolution);
|
||||
return new TestResult.Failed("Error testing external authentication: "
|
||||
+ e.getMessage() + ", check server log for details.");
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
setOutputMarkupPlaceholderTag(true);
|
||||
}
|
||||
TaskButton testButton = new TaskButton("test") {
|
||||
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
@ -138,8 +79,6 @@ public class AuthenticatorPage extends AdministrationPage {
|
||||
|
||||
@Override
|
||||
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
|
||||
super.onSubmit(target, form);
|
||||
|
||||
new ModalPanel(target) {
|
||||
|
||||
@Override
|
||||
@ -162,7 +101,7 @@ public class AuthenticatorPage extends AdministrationPage {
|
||||
target.add(tokenEditor);
|
||||
target.focusComponent(null);
|
||||
close();
|
||||
testBehavior.requestTest(target);
|
||||
submitTask(target);
|
||||
}
|
||||
|
||||
};
|
||||
@ -189,11 +128,41 @@ public class AuthenticatorPage extends AdministrationPage {
|
||||
}
|
||||
|
||||
};
|
||||
target.add(form);
|
||||
target.focusComponent(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onError(AjaxRequestTarget target, Form<?> form) {
|
||||
target.add(editor);
|
||||
protected String runTask() {
|
||||
try {
|
||||
Authenticated authenticated = bean.getAuthenticator().authenticate(
|
||||
new UsernamePasswordToken(token.getUserName(), token.getPassword()));
|
||||
StringBuilder retrievedInfoBuilder = new StringBuilder();
|
||||
if (authenticated.getFullName() != null) {
|
||||
retrievedInfoBuilder.append("Full name: ")
|
||||
.append(authenticated.getFullName())
|
||||
.append("\n");
|
||||
}
|
||||
if (authenticated.getEmail() != null) {
|
||||
retrievedInfoBuilder.append("Email: ")
|
||||
.append(authenticated.getEmail())
|
||||
.append("\n");
|
||||
}
|
||||
if (authenticated.getGroupNames() != null) {
|
||||
retrievedInfoBuilder.append("Groups: ")
|
||||
.append(Joiner.on(", ").join(authenticated.getGroupNames()))
|
||||
.append("\n");
|
||||
}
|
||||
StringBuilder messageBuilder =
|
||||
new StringBuilder("Test successful: authentication passed");
|
||||
if (retrievedInfoBuilder.length() != 0) {
|
||||
messageBuilder.append(" with below information retrieved:\n")
|
||||
.append(retrievedInfoBuilder);
|
||||
}
|
||||
return messageBuilder.toString();
|
||||
} catch (AuthenticationException e) {
|
||||
return "Test successful: authentication not passed: " + e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<div wicket:id="editor"></div>
|
||||
<div class="actions">
|
||||
<button wicket:id="save" class="btn btn-primary dirty-aware">Save</button>
|
||||
<input wicket:id="test" type="submit" class="btn btn-primary" value="Test">
|
||||
<input wicket:id="testingExecutor" type="submit" class="btn btn-primary" value="Test">
|
||||
<button wicket:id="cancel" class="btn btn-default">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -15,15 +15,11 @@ import org.apache.wicket.markup.html.form.Form;
|
||||
import org.apache.wicket.markup.html.panel.Panel;
|
||||
import org.apache.wicket.util.visit.IVisit;
|
||||
import org.apache.wicket.util.visit.IVisitor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
|
||||
import io.onedev.commons.utils.ExceptionUtils;
|
||||
import io.onedev.server.model.support.JobExecutor;
|
||||
import io.onedev.server.web.behavior.testform.TestFormBehavior;
|
||||
import io.onedev.server.web.behavior.testform.TestResult;
|
||||
import io.onedev.server.web.component.beaneditmodal.BeanEditModalPanel;
|
||||
import io.onedev.server.web.component.taskbutton.TaskButton;
|
||||
import io.onedev.server.web.editable.BeanContext;
|
||||
import io.onedev.server.web.editable.BeanEditor;
|
||||
import io.onedev.server.web.editable.BeanUpdating;
|
||||
@ -33,8 +29,6 @@ import io.onedev.server.web.util.Testable;
|
||||
@SuppressWarnings("serial")
|
||||
abstract class JobExecutorEditPanel extends Panel {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(JobExecutorEditPanel.class);
|
||||
|
||||
private final List<JobExecutor> executors;
|
||||
|
||||
private final int executorIndex;
|
||||
@ -70,7 +64,6 @@ abstract class JobExecutorEditPanel extends Panel {
|
||||
bean.setExecutor(executors.get(executorIndex));
|
||||
|
||||
BeanEditor editor = BeanContext.edit("editor", bean);
|
||||
editor.setOutputMarkupId(true);
|
||||
|
||||
AjaxButton saveButton = new AjaxButton("save") {
|
||||
|
||||
@ -109,36 +102,9 @@ abstract class JobExecutorEditPanel extends Panel {
|
||||
|
||||
};
|
||||
|
||||
AjaxButton testButton = new AjaxButton("test") {
|
||||
TaskButton testButton = new TaskButton("testingExecutor") {
|
||||
|
||||
private TestFormBehavior testBehavior;
|
||||
|
||||
private Serializable testData;
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
add(testBehavior = new TestFormBehavior() {
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
protected TestResult test() {
|
||||
try {
|
||||
((Testable)bean.getExecutor()).test(testData);
|
||||
return new TestResult.Successful("Job executor tested successfully");
|
||||
} catch (Exception e) {
|
||||
logger.error("Error testing job executor", e);
|
||||
String suggestedSolution = ExceptionUtils.suggestSolution(e);
|
||||
if (suggestedSolution != null)
|
||||
logger.warn("!!! " + suggestedSolution);
|
||||
return new TestResult.Failed("Error testing job executor: " + e.getMessage() + ", check server log for details");
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
setOutputMarkupPlaceholderTag(true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
@ -182,8 +148,6 @@ abstract class JobExecutorEditPanel extends Panel {
|
||||
|
||||
@Override
|
||||
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
|
||||
super.onSubmit(target, form);
|
||||
|
||||
checkNameDuplication(editor, bean.getExecutor());
|
||||
if (!editor.hasErrors(true)) {
|
||||
if (testData != null) {
|
||||
@ -194,23 +158,25 @@ abstract class JobExecutorEditPanel extends Panel {
|
||||
close();
|
||||
target.add(editor);
|
||||
target.focusComponent(null);
|
||||
testBehavior.requestTest(target);
|
||||
submitTask(target);
|
||||
}
|
||||
|
||||
};
|
||||
} else {
|
||||
target.add(editor);
|
||||
target.focusComponent(null);
|
||||
testBehavior.requestTest(target);
|
||||
submitTask(target);
|
||||
}
|
||||
} else {
|
||||
target.add(form);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
protected void onError(AjaxRequestTarget target, Form<?> form) {
|
||||
target.add(editor);
|
||||
protected String runTask() {
|
||||
((Testable)bean.getExecutor()).test(testData);
|
||||
return "Job executor tested successfully";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<div wicket:id="editor"></div>
|
||||
<div class="actions">
|
||||
<input wicket:id="save" type="submit" class="btn btn-primary dirty-aware" value="Save setting">
|
||||
<input wicket:id="test" type="submit" class="btn btn-primary" value="Send test mail">
|
||||
<input wicket:id="sendingTestMail" type="submit" class="btn btn-primary" value="Send test mail">
|
||||
</div>
|
||||
</form>
|
||||
</wicket:extend>
|
||||
|
||||
@ -1,36 +1,28 @@
|
||||
package io.onedev.server.web.page.admin.mailsetting;
|
||||
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
|
||||
import org.apache.wicket.event.IEvent;
|
||||
import org.apache.wicket.markup.html.form.Button;
|
||||
import org.apache.wicket.markup.html.form.Form;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
import org.apache.wicket.util.visit.IVisit;
|
||||
import org.apache.wicket.util.visit.IVisitor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import io.onedev.commons.utils.ExceptionUtils;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.entitymanager.UserManager;
|
||||
import io.onedev.server.model.User;
|
||||
import io.onedev.server.notification.MailManager;
|
||||
import io.onedev.server.web.behavior.testform.TestFormBehavior;
|
||||
import io.onedev.server.web.behavior.testform.TestResult;
|
||||
import io.onedev.server.web.editable.BeanUpdating;
|
||||
import io.onedev.server.web.component.taskbutton.TaskButton;
|
||||
import io.onedev.server.web.editable.BeanContext;
|
||||
import io.onedev.server.web.editable.BeanEditor;
|
||||
import io.onedev.server.web.editable.BeanUpdating;
|
||||
import io.onedev.server.web.page.admin.AdministrationPage;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class MailSettingPage extends AdministrationPage {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MailSettingPage.class);
|
||||
|
||||
public MailSettingPage(PageParameters params) {
|
||||
super(params);
|
||||
}
|
||||
@ -55,37 +47,7 @@ public class MailSettingPage extends AdministrationPage {
|
||||
}
|
||||
|
||||
};
|
||||
AjaxButton testButton = new AjaxButton("test") {
|
||||
|
||||
private TestFormBehavior testBehavior;
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
add(testBehavior = new TestFormBehavior() {
|
||||
|
||||
@Override
|
||||
protected TestResult test() {
|
||||
User currentUser = OneDev.getInstance(UserManager.class).getCurrent();
|
||||
try {
|
||||
OneDev.getInstance(MailManager.class).sendMail(mailSettingHolder.getMailSetting(),
|
||||
Sets.newHashSet(currentUser.getEmail()),
|
||||
"Test email from OneDev", "Great, your mail setting is working!");
|
||||
return new TestResult.Successful("Test mail has been sent to " +
|
||||
currentUser.getEmail() + ", please check your mail box.");
|
||||
} catch (Exception e) {
|
||||
logger.error("Error sending test email", e);
|
||||
String suggestedSolution = ExceptionUtils.suggestSolution(e);
|
||||
if (suggestedSolution != null)
|
||||
logger.warn("!!! " + suggestedSolution);
|
||||
return new TestResult.Failed("Error sending test email: " + e.getMessage() + ", check server log for details.");
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
setOutputMarkupPlaceholderTag(true);
|
||||
}
|
||||
TaskButton testButton = new TaskButton("sendingTestMail") {
|
||||
|
||||
@Override
|
||||
protected void onConfigure() {
|
||||
@ -102,17 +64,12 @@ public class MailSettingPage extends AdministrationPage {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
|
||||
super.onSubmit(target, form);
|
||||
|
||||
target.add(editor);
|
||||
target.focusComponent(null);
|
||||
testBehavior.requestTest(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onError(AjaxRequestTarget target, Form<?> form) {
|
||||
target.add(editor);
|
||||
protected String runTask() {
|
||||
User currentUser = OneDev.getInstance(UserManager.class).getCurrent();
|
||||
OneDev.getInstance(MailManager.class).sendMail(mailSettingHolder.getMailSetting(),
|
||||
Sets.newHashSet(currentUser.getEmail()),
|
||||
"Test email from OneDev", "Great, your mail setting is working!");
|
||||
return "Test mail has been sent to " + currentUser.getEmail() + ", please check your mail box";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@ -105,10 +105,6 @@ form .required {
|
||||
color: #B94A48;
|
||||
}
|
||||
|
||||
form>.test-feedback {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.noselect {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
<wicket:extend>
|
||||
<div id="forget" class="center-box">
|
||||
<h1><img src="/img/logo.png" class="logo"></img> Reset Password</h1>
|
||||
<h1><img src="/img/logo.png" class="logo"> Reset Password</h1>
|
||||
<form wicket:id="form">
|
||||
<div wicket:id="feedback"></div>
|
||||
<div wicket:id="editor"></div>
|
||||
<div class="actions">
|
||||
<input wicket:id="reset" type="submit" value="Reset password" class="btn btn-primary"></input>
|
||||
<input wicket:id="resettingPassword" type="submit" value="Reset password" class="btn btn-primary">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@ -5,23 +5,19 @@ import java.util.Arrays;
|
||||
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.shiro.authc.credential.PasswordService;
|
||||
import org.apache.wicket.ajax.AjaxRequestTarget;
|
||||
import org.apache.wicket.ajax.markup.html.form.AjaxButton;
|
||||
import org.apache.wicket.markup.html.form.Form;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
import org.hibernate.validator.constraints.NotEmpty;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel;
|
||||
import io.onedev.commons.launcher.loader.AppLoader;
|
||||
import io.onedev.server.OneDev;
|
||||
import io.onedev.server.OneException;
|
||||
import io.onedev.server.entitymanager.SettingManager;
|
||||
import io.onedev.server.entitymanager.UserManager;
|
||||
import io.onedev.server.model.User;
|
||||
import io.onedev.server.notification.MailManager;
|
||||
import io.onedev.server.web.behavior.testform.TestFormBehavior;
|
||||
import io.onedev.server.web.behavior.testform.TestResult;
|
||||
import io.onedev.server.web.component.taskbutton.TaskButton;
|
||||
import io.onedev.server.web.editable.BeanContext;
|
||||
import io.onedev.server.web.editable.annotation.Editable;
|
||||
import io.onedev.server.web.page.base.BasePage;
|
||||
@ -33,81 +29,50 @@ public class ForgetPage extends BasePage {
|
||||
super(params);
|
||||
}
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ForgetPage.class);
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
final HelperBean bean = new HelperBean();
|
||||
HelperBean bean = new HelperBean();
|
||||
Form<?> form = new Form<Void>("form");
|
||||
form.add(new NotificationPanel("feedback", form));
|
||||
form.add(BeanContext.edit("editor", bean));
|
||||
|
||||
form.add(new AjaxButton("reset") {
|
||||
private TestFormBehavior testBehavior;
|
||||
form.add(new TaskButton("resettingPassword") {
|
||||
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
add(testBehavior = new TestFormBehavior() {
|
||||
protected String runTask() {
|
||||
UserManager userManager = OneDev.getInstance(UserManager.class);
|
||||
User user = userManager.findByName(bean.getUserNameOrEmailAddress());
|
||||
if (user == null) {
|
||||
user = userManager.findByEmail(bean.getUserNameOrEmailAddress());
|
||||
}
|
||||
if (user == null) {
|
||||
throw new OneException("No user found with name or email: " + bean.getUserNameOrEmailAddress());
|
||||
} else {
|
||||
SettingManager configManager = OneDev.getInstance(SettingManager.class);
|
||||
if (configManager.getMailSetting() != null) {
|
||||
String password = RandomStringUtils.random(10, true, true);
|
||||
user.setPassword(AppLoader.getInstance(PasswordService.class).encryptPassword(password));
|
||||
userManager.save(user);
|
||||
|
||||
MailManager mailManager = OneDev.getInstance(MailManager.class);
|
||||
String mailBody = String.format("Dear %s, "
|
||||
+ "<p style='margin: 16px 0;'>"
|
||||
+ "Per your request, password of your user \"%s\" has been reset to:<br>"
|
||||
+ "%s<br><br>"
|
||||
+ "Please login and change the password in your earliest convenience."
|
||||
+ "<p style='margin: 16px 0;'>"
|
||||
+ "-- Sent by OneDev",
|
||||
user.getDisplayName(), user.getName(), password);
|
||||
|
||||
@Override
|
||||
protected TestResult test() {
|
||||
UserManager userManager = OneDev.getInstance(UserManager.class);
|
||||
User user = userManager.findByName(bean.getUserNameOrEmailAddress());
|
||||
if (user == null) {
|
||||
user = userManager.findByEmail(bean.getUserNameOrEmailAddress());
|
||||
}
|
||||
if (user == null) {
|
||||
return new TestResult.Failed("No user found with name or email: " + bean.getUserNameOrEmailAddress());
|
||||
} else {
|
||||
SettingManager configManager = OneDev.getInstance(SettingManager.class);
|
||||
if (configManager.getMailSetting() != null) {
|
||||
String password = RandomStringUtils.random(10, true, true);
|
||||
user.setPassword(AppLoader.getInstance(PasswordService.class).encryptPassword(password));
|
||||
userManager.save(user);
|
||||
|
||||
MailManager mailManager = OneDev.getInstance(MailManager.class);
|
||||
try {
|
||||
String mailBody = String.format("Dear %s, "
|
||||
+ "<p style='margin: 16px 0;'>"
|
||||
+ "Per your request, password of your user \"%s\" has been reset to:<br>"
|
||||
+ "%s<br><br>"
|
||||
+ "Please login and change the password in your earliest convenience."
|
||||
+ "<p style='margin: 16px 0;'>"
|
||||
+ "-- Sent by OneDev",
|
||||
user.getDisplayName(), user.getName(), password);
|
||||
|
||||
mailManager.sendMail(configManager.getMailSetting(), Arrays.asList(user.getEmail()),
|
||||
"Your OneDev password has been reset", mailBody);
|
||||
return new TestResult.Successful("Please check your email " + user.getEmail() + " for the reset password.");
|
||||
} catch (Exception e) {
|
||||
logger.error("Error sending password reset email", e);
|
||||
return new TestResult.Failed("Error sending password reset email: " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
return new TestResult.Failed("Unable to send password reset email as smtp setting is not defined");
|
||||
}
|
||||
}
|
||||
mailManager.sendMail(configManager.getMailSetting(), Arrays.asList(user.getEmail()),
|
||||
"Your OneDev password has been reset", mailBody);
|
||||
return "Please check your email " + user.getEmail() + " for the reset password";
|
||||
} else {
|
||||
throw new OneException("Unable to send password reset email as smtp setting is not defined");
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
|
||||
super.onSubmit(target, form);
|
||||
|
||||
target.add(form);
|
||||
target.focusComponent(null);
|
||||
testBehavior.requestTest(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onError(AjaxRequestTarget target, Form<?> form) {
|
||||
target.add(form);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@ -1,3 +1,2 @@
|
||||
<wicket:extend>
|
||||
<a wicket:id="test">test</a>
|
||||
</wicket:extend>
|
||||
@ -3,7 +3,6 @@ package io.onedev.server.web.page.test;
|
||||
import org.apache.wicket.markup.head.IHeaderResponse;
|
||||
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
|
||||
import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
|
||||
import org.apache.wicket.markup.html.link.Link;
|
||||
import org.apache.wicket.request.mapper.parameter.PageParameters;
|
||||
|
||||
import io.onedev.server.web.page.base.BasePage;
|
||||
@ -18,14 +17,6 @@ public class TestPage extends BasePage {
|
||||
@Override
|
||||
protected void onInitialize() {
|
||||
super.onInitialize();
|
||||
|
||||
add(new Link<Void>("test") {
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user