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

Commit

Permalink
Checking for admin permission on the repo/project #123
Browse files Browse the repository at this point in the history
 * If a user is only admin in one repo, the user should not be able to administrate the plugin in another repo.
 * Hiding admin restriction levels, in buttons config, that the user does not have access to. So that the user cannot create buttons that the user cannot see.
 * Sorting notifications and buttons by name in REST API.
  • Loading branch information
tomasbjerre committed Jun 20, 2016
1 parent 043117b commit 15d2bd2
Show file tree
Hide file tree
Showing 17 changed files with 203 additions and 69 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

Changelog of Pull Request Notifier for Bitbucket.

## Unreleased
### GitHub [#123](https://github.com/tomasbjerre/pull-request-notifier-for-bitbucket/issues/123) Question on the configuration permissions.
Checking for admin permission on the repo/project

* If a user is only admin in one repo, the user should not be able to administrate the plugin in another repo.
* Hiding admin restriction levels, in buttons config, that the user does not have access to. So that the user cannot create buttons that the user cannot see.
* Sorting notifications and buttons by name in REST API.

[8eb180033a79346](https://github.com/tomasbjerre/pull-request-notifier-for-bitbucket/commit/8eb180033a79346) Tomas Bjerre *2016-06-20 17:32:05*

## 2.23
### GitHub [#122](https://github.com/tomasbjerre/pull-request-notifier-for-bitbucket/issues/122) Preserving configs when upgrading from stash 3.x to bitbucket 4.x
Loading legacy settings correctly

* Did not save loaded legacy settings in new format when found. Got new UUID:s on every load.

[56827de4eb8310d](https://github.com/tomasbjerre/pull-request-notifier-for-bitbucket/commit/56827de4eb8310d) Tomas Bjerre *2016-06-04 21:25:42*

## 2.22
### GitHub [#119](https://github.com/tomasbjerre/pull-request-notifier-for-bitbucket/issues/119) You are not permitted to access this resource
Getting clone URL:s with admin permission
Expand Down
22 changes: 16 additions & 6 deletions src/main/java/se/bjurr/prnfb/presentation/ButtonServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import static se.bjurr.prnfb.transformer.ButtonTransformer.toButtonDtoList;
import static se.bjurr.prnfb.transformer.ButtonTransformer.toPrnfbButton;

import java.util.Collections;
import java.util.List;
import java.util.UUID;

Expand Down Expand Up @@ -46,8 +47,11 @@ public ButtonServlet(ButtonsService buttonsService, SettingsService settingsServ
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public Response create(ButtonDTO buttonDto) {
if (!this.userCheckService.isAdminAllowed()) {
return status(UNAUTHORIZED).build();
if (!this.userCheckService.isAdminAllowed(//
buttonDto.getProjectKey().orNull()//
, buttonDto.getRepositorySlug().orNull())) {
return status(UNAUTHORIZED)//
.build();
}
PrnfbButton prnfbButton = toPrnfbButton(buttonDto);
PrnfbButton created = this.settingsService.addOrUpdateButton(prnfbButton);
Expand All @@ -62,11 +66,15 @@ public Response create(ButtonDTO buttonDto) {
@Path("{uuid}")
@XsrfProtectionExcluded
@Produces(APPLICATION_JSON)
public Response delete(@PathParam("uuid") UUID prnfbButton) {
if (!this.userCheckService.isAdminAllowed()) {
return status(UNAUTHORIZED).build();
public Response delete(@PathParam("uuid") UUID prnfbButtonUuid) {
PrnfbButton prnfbButton = this.settingsService.getButton(prnfbButtonUuid);
if (!this.userCheckService.isAdminAllowed(//
prnfbButton.getProjectKey().orNull()//
, prnfbButton.getRepositorySlug().orNull())) {
return status(UNAUTHORIZED)//
.build();
}
this.settingsService.deleteButton(prnfbButton);
this.settingsService.deleteButton(prnfbButtonUuid);
return status(OK).build();
}

Expand All @@ -89,6 +97,7 @@ public Response get(@PathParam("repositoryId") Integer repositoryId, @PathParam(
List<PrnfbButton> buttons = this.buttonsService.getButtons(repositoryId, pullRequestId);
Iterable<PrnfbButton> allowedButtons = this.userCheckService.filterAllowed(buttons);
List<ButtonDTO> dtos = toButtonDtoList(allowedButtons);
Collections.sort(dtos);
return ok(dtos, APPLICATION_JSON).build();
}

Expand All @@ -113,6 +122,7 @@ public Response get(@PathParam("projectKey") String projectKey, @PathParam("repo
}
List<PrnfbButton> buttons = this.settingsService.getButtons(projectKey, repositorySlug);
List<ButtonDTO> dtos = toButtonDtoList(buttons);
Collections.sort(dtos);
return ok(dtos, APPLICATION_JSON).build();
}

Expand Down
20 changes: 17 additions & 3 deletions src/main/java/se/bjurr/prnfb/presentation/GlobalAdminServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import se.bjurr.prnfb.service.UserCheckService;

import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.repository.RepositoryService;
import com.atlassian.sal.api.auth.LoginUriProvider;
Expand All @@ -27,14 +29,16 @@ public class GlobalAdminServlet extends HttpServlet {
private final LoginUriProvider loginUriProvider;
private final TemplateRenderer renderer;
private final RepositoryService repositoryService;
private final UserCheckService userCheckService;
private final UserManager userManager;

public GlobalAdminServlet(UserManager userManager, LoginUriProvider loginUriProvider, TemplateRenderer renderer,
RepositoryService repositoryService) {
RepositoryService repositoryService, UserCheckService userCheckService) {
this.userManager = userManager;
this.loginUriProvider = loginUriProvider;
this.renderer = renderer;
this.repositoryService = repositoryService;
this.userCheckService = userCheckService;
}

@Override
Expand All @@ -47,11 +51,21 @@ public void doGet(HttpServletRequest request, HttpServletResponse response) {
}

final Optional<Repository> repository = getRepository(request.getPathInfo());
boolean isSystemAdmin = this.userCheckService.isSystemAdmin(user.getUserKey());
String projectKey = null;
String repositorySlug = null;
if (repository.isPresent()) {
projectKey = repository.get().getProject().getKey();
repositorySlug = repository.get().getSlug();
}
boolean isAdmin = this.userCheckService.isAdmin(user.getUserKey(), projectKey, repositorySlug);

Map<String, Object> context = newHashMap();
if (repository.isPresent()) {
context = of( //
"repository", repository.orNull() //
);
"repository", repository.orNull(), //
"isAdmin", isAdmin, //
"isSystemAdmin", isSystemAdmin);
}

response.setContentType("text/html;charset=UTF-8");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import static se.bjurr.prnfb.transformer.NotificationTransformer.toNotificationDtoList;
import static se.bjurr.prnfb.transformer.NotificationTransformer.toPrnfbNotification;

import java.util.Collections;
import java.util.List;
import java.util.UUID;

Expand Down Expand Up @@ -44,7 +45,7 @@ public NotificationServlet(SettingsService settingsService, UserCheckService use
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public Response create(NotificationDTO notificationDto) {
if (!this.userCheckService.isAdminAllowed()) {
if (!this.userCheckService.isAdminAllowed(notificationDto.getProjectKey(), notificationDto.getRepositorySlug())) {
return status(UNAUTHORIZED).build();
}
try {
Expand All @@ -64,7 +65,10 @@ public Response create(NotificationDTO notificationDto) {
@XsrfProtectionExcluded
@Produces(APPLICATION_JSON)
public Response delete(@PathParam("uuid") UUID notification) {
if (!this.userCheckService.isAdminAllowed()) {
PrnfbNotification notificationDto = this.settingsService.getNotification(notification);
if (!this.userCheckService.isAdminAllowed(//
notificationDto.getProjectKey().orNull(), //
notificationDto.getRepositorySlug().orNull())) {
return status(UNAUTHORIZED).build();
}
this.settingsService.deleteNotification(notification);
Expand All @@ -79,6 +83,7 @@ public Response get() {
}
List<PrnfbNotification> notifications = this.settingsService.getNotifications();
List<NotificationDTO> dtos = toNotificationDtoList(notifications);
Collections.sort(dtos);
return ok(dtos).build();
}

Expand All @@ -91,6 +96,7 @@ public Response get(@PathParam("projectKey") String projectKey) {
}
List<PrnfbNotification> notifications = this.settingsService.getNotifications(projectKey);
List<NotificationDTO> dtos = toNotificationDtoList(notifications);
Collections.sort(dtos);
return ok(dtos).build();
}

Expand All @@ -103,6 +109,7 @@ public Response get(@PathParam("projectKey") String projectKey, @PathParam("repo
}
List<PrnfbNotification> notifications = this.settingsService.getNotifications(projectKey, repositorySlug);
List<NotificationDTO> dtos = toNotificationDtoList(notifications);
Collections.sort(dtos);
return ok(dtos).build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public Response get() {
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
public Response post(SettingsDataDTO settingsDataDto) {
if (!this.userCheckService.isAdminAllowed()) {
if (!this.userCheckService.isAdminAllowed(null, null)) {
return status(UNAUTHORIZED).build();
}

Expand Down
17 changes: 12 additions & 5 deletions src/main/java/se/bjurr/prnfb/presentation/dto/ButtonDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,23 @@

import se.bjurr.prnfb.settings.USER_LEVEL;

import com.google.common.base.Optional;

@XmlRootElement
@XmlAccessorType(FIELD)
public class ButtonDTO {
public class ButtonDTO implements Comparable<ButtonDTO> {

private String name;
private String projectKey;
private String repositorySlug;
private USER_LEVEL userLevel;
private UUID uuid;

@Override
public int compareTo(ButtonDTO o) {
return this.name.compareTo(o.name);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
Expand Down Expand Up @@ -69,12 +76,12 @@ public String getName() {
return this.name;
}

public String getProjectKey() {
return this.projectKey;
public Optional<String> getProjectKey() {
return Optional.fromNullable(this.projectKey);
}

public String getRepositorySlug() {
return this.repositorySlug;
public Optional<String> getRepositorySlug() {
return Optional.fromNullable(this.repositorySlug);
}

public USER_LEVEL getUserLevel() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

@XmlRootElement
@XmlAccessorType(FIELD)
public class NotificationDTO {
public class NotificationDTO implements Comparable<NotificationDTO> {
private String filterRegexp;
private String filterString;
private List<HeaderDTO> headers;
Expand All @@ -36,6 +36,11 @@ public class NotificationDTO {
private String user;
private UUID uuid;

@Override
public int compareTo(NotificationDTO o) {
return this.name.compareTo(o.name);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
Expand Down
37 changes: 20 additions & 17 deletions src/main/java/se/bjurr/prnfb/service/ButtonsService.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,45 +75,48 @@ private boolean isTriggeredByAction(ClientKeyStore clientKeyStore, List<PrnfbNot
return FALSE;
}

/**
* Checks if the given button is visible on the pull request by either the from
* or to repository.
*/
private boolean isVisibleOnPullRequest(PrnfbButton button, PullRequest pullRequest) {
return (pullRequest.getFromRef() != null && isVisibleOnRepository(button, pullRequest.getFromRef().getRepository()))
|| (pullRequest.getToRef() != null && isVisibleOnRepository(button, pullRequest.getToRef().getRepository()));
}

/**
* Checks if the given button is visible in the given repository.
*
* @param button Button under test
* @param repository Repository to check for
* @return True if the button is either globally visible or matches with the given repository
*
* @param button
* Button under test
* @param repository
* Repository to check for
* @return True if the button is either globally visible or matches with the
* given repository
*/
private boolean isVisibleOnRepository(PrnfbButton button, Repository repository) {
if(button.getRepositorySlug().isPresent()) {
if (button.getRepositorySlug().isPresent()) {
boolean visible = false;
do {
visible |= button.getProjectKey().get().equals(repository.getProject().getKey())
&& button.getRepositorySlug().get().equals(repository.getSlug());
} while(!visible && (repository = repository.getOrigin()) != null);
} while (!visible && (repository = repository.getOrigin()) != null);
return visible;
} else {
return TRUE;
}
}

/**
* Checks if the given button is visible on the pull request by either the from or to repository.
*/
private boolean isVisibleOnPullRequest(PrnfbButton button, PullRequest pullRequest) {
return
(pullRequest.getFromRef() != null && isVisibleOnRepository(button, pullRequest.getFromRef().getRepository()))
|| (pullRequest.getToRef() != null && isVisibleOnRepository(button, pullRequest.getToRef().getRepository()));
}

@VisibleForTesting
List<PrnfbButton> doGetButtons(List<PrnfbNotification> notifications, ClientKeyStore clientKeyStore,
final PullRequest pullRequest, boolean shouldAcceptAnyCertificate) {
List<PrnfbButton> allFoundButtons = newArrayList();
for (PrnfbButton candidate : this.settingsService.getButtons()) {
Map<PrnfbVariable, Supplier<String>> variables = getVariables(candidate.getUuid());
PrnfbPullRequestAction pullRequestAction = BUTTON_TRIGGER;
if (this.userCheckService.isAllowedUseButton(candidate)
if (this.userCheckService.isAllowedUseButton(candidate)//
&& isTriggeredByAction(clientKeyStore, notifications, shouldAcceptAnyCertificate, pullRequestAction, pullRequest,
variables)
variables) //
&& (isVisibleOnPullRequest(candidate, pullRequest))) {
allFoundButtons.add(candidate);
}
Expand Down
Loading

0 comments on commit 15d2bd2

Please sign in to comment.