Skip to content
This repository has been archived by the owner on Jun 9, 2021. It is now read-only.

Commit

Permalink
Optionally allow users and admins to configure the plugin #25
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasbjerre committed Aug 17, 2015
1 parent 7e125b1 commit 325719d
Show file tree
Hide file tree
Showing 14 changed files with 269 additions and 88 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

Changelog of Pull Request Notifier for Stash.

## 1.20
* Optionally allow users and admins to configure the plugin.
* A common user, will have to browse to http://domain/stash/plugins/servlet/prnfs/admin to do configuration.

## 1.19
* Bugfix: Only ignore events on closed pull requests if its a COMMENT-event.

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ The Pull Request Notifier for Stash can:
* Authenticate with HTTP basic authentication.
* Send custom HTTP headers
* Can optionally use proxy to connect
* Can let users and/or admins do configuration. Or restrict configuration to just system admins. A user will have to browse to the configuration page at `http://domain/stash/plugins/servlet/prnfs/admin`.

The plugin has its own implementation to create the RESCOPED_FROM and RESCOPED_TO events. RESCOPED is transformed to RESCOPED_TO if target branch changed, RESCOPED_FROM if source branch, or both, changed.

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/se/bjurr/prnfs/admin/AdminFormValues.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ public final class AdminFormValues extends ArrayList<Map<String, String>> {
public static final String DEFAULT_NAME = "Unnamed trigger";

public enum FORM_TYPE {
BUTTON_CONFIG_FORM, TRIGGER_CONFIG_FORM
BUTTON_CONFIG_FORM, TRIGGER_CONFIG_FORM, GLOBAL_SETTINGS
};

public enum BUTTON_VISIBILITY {
NONE, SYSTEM_ADMIN, ADMIN, EVERYONE
};

public enum FIELDS {
user, password, events, FORM_IDENTIFIER, FORM_TYPE, url, filter_string, filter_regexp, method, post_content, proxy_user, proxy_password, proxy_server, proxy_port, header_name, header_value, name, button_title, button_visibility
user, password, events, FORM_IDENTIFIER, FORM_TYPE, url, filter_string, filter_regexp, method, post_content, proxy_user, proxy_password, proxy_server, proxy_port, header_name, header_value, name, button_title, button_visibility, admin_allowed, user_allowed
}
}
23 changes: 18 additions & 5 deletions src/main/java/se/bjurr/prnfs/admin/AdminServlet.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package se.bjurr.prnfs.admin;

import static com.google.common.base.Throwables.propagate;
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static se.bjurr.prnfs.admin.ConfigResource.isAdminAllowed;

import java.io.IOException;
import java.net.URI;
Expand All @@ -11,20 +13,27 @@
import javax.servlet.http.HttpServletResponse;

import com.atlassian.sal.api.auth.LoginUriProvider;
import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
import com.atlassian.sal.api.user.UserManager;
import com.atlassian.sal.api.user.UserProfile;
import com.atlassian.stash.user.SecurityService;
import com.atlassian.templaterenderer.TemplateRenderer;

public class AdminServlet extends HttpServlet {
private static final long serialVersionUID = 3846987953228399693L;
private final LoginUriProvider loginUriProvider;
private final TemplateRenderer renderer;
private final UserManager userManager;
private final SecurityService securityService;
private final PluginSettingsFactory pluginSettingsFactory;

public AdminServlet(UserManager userManager, LoginUriProvider loginUriProvider, TemplateRenderer renderer) {
public AdminServlet(UserManager userManager, LoginUriProvider loginUriProvider, TemplateRenderer renderer,
SecurityService securityService, PluginSettingsFactory pluginSettingsFactory) {
this.userManager = userManager;
this.loginUriProvider = loginUriProvider;
this.renderer = renderer;
this.securityService = securityService;
this.pluginSettingsFactory = pluginSettingsFactory;
}

@Override
Expand All @@ -34,10 +43,14 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) thro
response.sendRedirect(loginUriProvider.getLoginUri(getUri(request)).toASCIIString());
return;
}
if (!userManager.isSystemAdmin(user.getUserKey())) {
response.sendError(SC_FORBIDDEN, "Only 'System Admin':s are allowed to edit configuration "
+ loginUriProvider.getLoginUri(getUri(request)).toASCIIString());
return;
try {
if (!isAdminAllowed(userManager, request, securityService, pluginSettingsFactory)) {
response.sendError(SC_FORBIDDEN,
"You are not allowed to edit configuration " + loginUriProvider.getLoginUri(getUri(request)).toASCIIString());
return;
}
} catch (Exception e) {
propagate(e);
}
response.setContentType("text/html;charset=utf-8");
renderer.render("admin.vm", response.getWriter());
Expand Down
35 changes: 26 additions & 9 deletions src/main/java/se/bjurr/prnfs/admin/ConfigResource.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package se.bjurr.prnfs.admin;

import static com.atlassian.stash.user.Permission.ADMIN;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.Response.noContent;
import static javax.ws.rs.core.Response.ok;
Expand All @@ -11,6 +12,7 @@
import static se.bjurr.prnfs.settings.SettingsStorage.deleteSettings;
import static se.bjurr.prnfs.settings.SettingsStorage.getPrnfsButton;
import static se.bjurr.prnfs.settings.SettingsStorage.getPrnfsNotification;
import static se.bjurr.prnfs.settings.SettingsStorage.getPrnfsSettings;
import static se.bjurr.prnfs.settings.SettingsStorage.getSettingsAsFormValues;
import static se.bjurr.prnfs.settings.SettingsStorage.injectFormIdentifierIfNotSet;
import static se.bjurr.prnfs.settings.SettingsStorage.storeSettings;
Expand All @@ -29,32 +31,37 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import se.bjurr.prnfs.settings.PrnfsSettings;
import se.bjurr.prnfs.settings.ValidationException;

import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
import com.atlassian.sal.api.transaction.TransactionCallback;
import com.atlassian.sal.api.transaction.TransactionTemplate;
import com.atlassian.sal.api.user.UserManager;
import com.atlassian.sal.api.user.UserProfile;
import com.atlassian.stash.user.SecurityService;
import com.atlassian.stash.util.Operation;

@Path("/")
public class ConfigResource {
private static final Logger logger = LoggerFactory.getLogger(ConfigResource.class);
private final PluginSettingsFactory pluginSettingsFactory;
private final TransactionTemplate transactionTemplate;
private final UserManager userManager;
private final SecurityService securityService;

public ConfigResource(UserManager userManager, PluginSettingsFactory pluginSettingsFactory,
TransactionTemplate transactionTemplate) {
TransactionTemplate transactionTemplate, SecurityService securityService) {
this.userManager = userManager;
this.pluginSettingsFactory = pluginSettingsFactory;
this.transactionTemplate = transactionTemplate;
this.securityService = securityService;
}

@DELETE
@Path("{id}")
public Response delete(@PathParam("id") final String id, @Context HttpServletRequest request) {
if (!isSystemAdminLoggedIn(request)) {
public Response delete(@PathParam("id") final String id, @Context HttpServletRequest request) throws Exception {
if (!isAdminAllowed(userManager, request, securityService, pluginSettingsFactory)) {
return status(UNAUTHORIZED).build();
}

Expand All @@ -73,8 +80,8 @@ public Object doInTransaction() {
*/
@GET
@Produces(APPLICATION_JSON)
public Response get(@Context HttpServletRequest request) {
if (!isSystemAdminLoggedIn(request)) {
public Response get(@Context HttpServletRequest request) throws Exception {
if (!isAdminAllowed(userManager, request, securityService, pluginSettingsFactory)) {
return status(UNAUTHORIZED).build();
}

Expand All @@ -98,12 +105,22 @@ public UserManager getUserManager() {
return userManager;
}

private boolean isSystemAdminLoggedIn(HttpServletRequest request) {
static boolean isAdminAllowed(UserManager userManager, HttpServletRequest request, SecurityService securityService,
final PluginSettingsFactory pluginSettingsFactory) throws Exception {
final UserProfile user = userManager.getRemoteUser(request);
if (user == null) {
return false;
}
return userManager.isSystemAdmin(user.getUserKey());
PrnfsSettings settings = securityService.withPermission(ADMIN, "Getting config").call(
new Operation<PrnfsSettings, Exception>() {
@Override
public PrnfsSettings perform() throws Exception {
return getPrnfsSettings(pluginSettingsFactory.createGlobalSettings());
}
});
return userManager.isSystemAdmin(user.getUserKey()) //
|| settings.isUsersAllowed() //
|| settings.isAdminsAllowed() && userManager.isAdmin(user.getUserKey());
}

/**
Expand All @@ -112,8 +129,8 @@ private boolean isSystemAdminLoggedIn(HttpServletRequest request) {
@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public Response post(final AdminFormValues config, @Context HttpServletRequest request) {
if (!isSystemAdminLoggedIn(request)) {
public Response post(final AdminFormValues config, @Context HttpServletRequest request) throws Exception {
if (!isAdminAllowed(userManager, request, securityService, pluginSettingsFactory)) {
return status(UNAUTHORIZED).build();
}

Expand Down
15 changes: 14 additions & 1 deletion src/main/java/se/bjurr/prnfs/settings/PrnfsSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@
public class PrnfsSettings {
private List<PrnfsNotification> notifications = newArrayList();
private final List<PrnfsButton> buttons;
private final boolean usersAllowed;
private final boolean adminsAllowed;

public PrnfsSettings(List<PrnfsNotification> notifications, List<PrnfsButton> buttons) {
public PrnfsSettings(List<PrnfsNotification> notifications, List<PrnfsButton> buttons, boolean usersAllowed,
boolean adminsAllowed) {
this.notifications = checkNotNull(notifications);
this.buttons = checkNotNull(buttons);
this.usersAllowed = usersAllowed;
this.adminsAllowed = adminsAllowed;
}

public List<PrnfsNotification> getNotifications() {
Expand All @@ -21,4 +26,12 @@ public List<PrnfsNotification> getNotifications() {
public List<PrnfsButton> getButtons() {
return buttons;
}

public boolean isUsersAllowed() {
return usersAllowed;
}

public boolean isAdminsAllowed() {
return adminsAllowed;
}
}
22 changes: 21 additions & 1 deletion src/main/java/se/bjurr/prnfs/settings/PrnfsSettingsBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ public static PrnfsSettingsBuilder prnfsSettingsBuilder() {

private final List<PrnfsNotification> notifications = newArrayList();
private final List<PrnfsButton> buttons = newArrayList();
private boolean usersAllowed;
private boolean adminsAllowed;

private PrnfsSettingsBuilder() {
}

public PrnfsSettings build() {
return new PrnfsSettings(notifications, buttons);
return new PrnfsSettings(notifications, buttons, usersAllowed, adminsAllowed);
}

public PrnfsSettingsBuilder withNotification(PrnfsNotification notification) {
Expand All @@ -35,4 +37,22 @@ public List<PrnfsButton> getButtons() {
public List<PrnfsNotification> getNotifications() {
return notifications;
}

public PrnfsSettingsBuilder withUsersAllowed(boolean allowed) {
this.usersAllowed = allowed;
return this;
}

public PrnfsSettingsBuilder withAdminsAllowed(boolean allowed) {
this.adminsAllowed = allowed;
return this;
}

public boolean isAdminsAllowed() {
return adminsAllowed;
}

public boolean isUsersAllowed() {
return usersAllowed;
}
}
4 changes: 4 additions & 0 deletions src/main/java/se/bjurr/prnfs/settings/SettingsStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ public static PrnfsSettings getPrnfsSettings(PluginSettings pluginSettings) thro
} else {
prnfsSettingsBuilder.withButton(getPrnfsButton(adminFormValues));
}
prnfsSettingsBuilder
.withUsersAllowed(tryFind(adminFormValues, predicate(AdminFormValues.FIELDS.user_allowed.name())).isPresent());
prnfsSettingsBuilder.withAdminsAllowed(tryFind(adminFormValues,
predicate(AdminFormValues.FIELDS.admin_allowed.name())).isPresent());
}
return prnfsSettingsBuilder.build();
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/resources/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
}).done(function(configs) {
$(".prnfs-TRIGGER_CONFIG_FORM").html("");
$(".prnfs-BUTTON_CONFIG_FORM").html("");
$(".prnfs-GLOBAL_SETTINGS").html("");
$.each(configs, function(index, config) {
var formType = 'TRIGGER_CONFIG_FORM';
$.each(config, function(fieldIndex,field_map) {
Expand Down Expand Up @@ -146,6 +147,9 @@
});
addNewForm('TRIGGER_CONFIG_FORM');
addNewForm('BUTTON_CONFIG_FORM');
if ($('[name="FORM_TYPE"][value="GLOBAL_SETTINGS"]').length < 2) {
addNewForm('GLOBAL_SETTINGS');
}
setEvents();
});
}
Expand Down
25 changes: 25 additions & 0 deletions src/main/resources/admin.vm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,31 @@
$webResourceManager.requireResource("se.bjurr.prnfs.pull-request-notifier-for-stash:resources")
</head>
<body>
<div class="prnfs-template prnfs-template-GLOBAL_SETTINGS">
<form class="trigger config-area">
<input type="hidden" name="FORM_IDENTIFIER" value="GLOBAL_SETTINGS">
<input type="hidden" name="FORM_TYPE" value="GLOBAL_SETTINGS">
<div>
<fieldset>
<legend>Admin restrictions</legend>
<input type="checkbox" id="systemadmin_allowed" checked disabled>
<label for="systemadmin_allowed">System administrators</label><br>
<input type="checkbox" name="admin_allowed" value="ADMINS" id="admin_allowed">
<label for="admin_allowed">Administrators</label><br>
<input type="checkbox" name="user_allowed" value="USERS" id="user_allowed">
<label for="user_allowed">Users</label><br>
</fieldset>
</div>
<div>
<fieldset>
<input type="button" name="save" value="Save"/>
<span class="post"></span>
</fieldset>
</div>
</form>
</div>
<div class="prnfs-GLOBAL_SETTINGS">
</div>

<div class="prnfs-BUTTON_CONFIG_FORM">
</div>
Expand Down
Loading

0 comments on commit 325719d

Please sign in to comment.