Skip to content

Commit

Permalink
dcoraboeuf#265 Use the current account as run-as identity
Browse files Browse the repository at this point in the history
  • Loading branch information
dcoraboeuf committed Nov 4, 2013
1 parent 9eaa1e1 commit 94bc88e
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,28 @@ public class RunAsAdminAuthentication extends AbstractAuthenticationToken {
"runas",
Locale.ENGLISH
);
private final Account account;

public RunAsAdminAuthentication() {
public RunAsAdminAuthentication(Account account) {
super(AuthorityUtils.createAuthorityList(SecurityRoles.ADMINISTRATOR));
if (account == null) {
this.account = RUNAS_ACCOUNT;
} else {
this.account = new Account(
account.getId(),
account.getName(),
account.getFullName(),
"",
SecurityRoles.ADMINISTRATOR,
"runas",
Locale.ENGLISH
);
}
}

@Override
public Account getDetails() {
return RUNAS_ACCOUNT;
return account;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,31 +67,27 @@ public void checkIsLogged() {

@Override
public <T> T asAdmin(Callable<T> call) {
// Current context
final SecurityContext context = SecurityContextHolder.getContext();
try {
// Creates a temporary admin context
SecurityContextImpl adminContext = new SecurityContextImpl();
adminContext.setAuthentication(new RunAsAdminAuthentication());
SecurityContextHolder.setContext(adminContext);
// Runs the call
try {
return call.call();
} catch (RuntimeException ex) {
throw ex;
} catch (Exception e) {
throw new AsAdminCallException(e);
}
} finally {
// Restores the initial context
SecurityContextHolder.setContext(context);
return asAdminTask(call).call();
} catch (RuntimeException ex) {
throw ex;
} catch (Exception e) {
throw new AsAdminCallException(e);
}
}

@Override
public <T> Callable<T> withCurrentCredentials(final Callable<T> callable) {
// Current context
final SecurityContext context = SecurityContextHolder.getContext();
public <T> Callable<T> asAdminTask(Callable<T> callable) {
// Gets the current account (if any)
Account account = getCurrentAccount();
// Creates a temporary admin context
SecurityContextImpl adminContext = new SecurityContextImpl();
adminContext.setAuthentication(new RunAsAdminAuthentication(account));
// Returns a callable that sets the context before running the target callable
return withSecurityContext(callable, adminContext);
}

protected <T> Callable<T> withSecurityContext(final Callable<T> callable, final SecurityContext context) {
// Returns a callable that sets the context before running the target callable
return new Callable<T>() {
@Override
Expand All @@ -107,6 +103,14 @@ public T call() throws Exception {
};
}

@Override
public <T> Callable<T> withCurrentCredentials(Callable<T> callable) {
// Current context
SecurityContext context = SecurityContextHolder.getContext();
// Uses it
return withSecurityContext(callable, context);
}

@Override
public void checkGrant(GlobalFunction fn) {
if (!isGranted(fn)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.ontrack.core.security.GlobalFunction;
import net.ontrack.core.security.ProjectFunction;
import net.ontrack.core.security.SecurityRoles;
import net.ontrack.service.AccountService;
import net.ontrack.service.ControlService;
import net.ontrack.service.ManagementService;
import net.ontrack.test.AbstractIntegrationTest;
Expand All @@ -22,9 +23,10 @@ public abstract class AbstractBackendTest extends AbstractIntegrationTest {

@Autowired
private ManagementService managementService;

@Autowired
private ControlService controlService;
@Autowired
private AccountService accountService;

protected AnonymousCall asAnonymous() {
return new AnonymousCall();
Expand All @@ -46,6 +48,31 @@ protected String uid(String prefix) {
return Helper.uid(prefix);
}

protected Account doCreateAccount() throws Exception {
return doCreateAccount(uid("ACC"));
}

protected Account doCreateAccount(final String name) throws Exception {
return asAdmin().call(new Callable<Account>() {
@Override
public Account call() throws Exception {
return accountService.getAccount(
accountService.createAccount(
new AccountCreationForm(
name,
name + " Test",
name + "@test.com",
SecurityRoles.USER,
"builtin",
"test",
"test"
)
).getValue()
);
}
});
}

protected ProjectSummary doCreateProject() throws Exception {
final String projectName = uid("PRJ");
return asAdmin().call(new Callable<ProjectSummary>() {
Expand Down Expand Up @@ -96,7 +123,6 @@ public ValidationRunSummary call() throws Exception {
});
}


protected BuildSummary doCreateBuild(final int branchId) throws Exception {
final String buildName = uid("B");
return asAdmin().call(new Callable<BuildSummary>() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
package net.ontrack.backend;

import net.ontrack.core.model.BranchSummary;
import net.ontrack.core.model.BuildCreationForm;
import net.ontrack.core.model.BuildSummary;
import net.ontrack.core.model.PropertiesCreationForm;
import net.ontrack.core.model.*;
import net.ontrack.core.security.SecurityUtils;
import net.ontrack.core.support.MapBuilder;
import net.ontrack.service.ControlService;
import net.ontrack.service.EventService;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Locale;
import java.util.concurrent.Callable;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class ControlServiceIntegrationTest extends AbstractBackendTest {

@Autowired
private EventService eventService;
@Autowired
private ControlService controlService;
@Autowired
Expand All @@ -25,16 +27,34 @@ public class ControlServiceIntegrationTest extends AbstractBackendTest {
public void createBuild() throws Exception {
// Prerequisites
final BranchSummary branch = doCreateBranch();
// Creates a build
BuildSummary build = securityUtils.asAdmin(new Callable<BuildSummary>() {
// New account
Account account = doCreateAccount();
// As account
BuildSummary build = asAccount(account).call(new Callable<BuildSummary>() {
@Override
public BuildSummary call() throws Exception {
return controlService.createBuild(branch.getId(), new BuildCreationForm("1", "Build 1", PropertiesCreationForm.create()));
return securityUtils.asAdmin(new Callable<BuildSummary>() {
@Override
public BuildSummary call() throws Exception {
return controlService.createBuild(branch.getId(), new BuildCreationForm("1", "Build 1", PropertiesCreationForm.create()));
}
});
}
});
// Checks
assertNotNull(build);
assertEquals("1", build.getName());
// Signature must match the initial account name, not the admin
DatedSignature s = eventService.getDatedSignature(
Locale.ENGLISH,
EventType.BUILD_CREATED,
MapBuilder.of(Entity.PROJECT, branch.getProject().getId())
.with(Entity.BRANCH, branch.getId())
.with(Entity.BUILD, build.getId())
.get()
);
assertEquals(account.getId(), s.getSignature().getId().intValue());
assertEquals(account.getFullName(), s.getSignature().getName());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public interface SecurityUtils {

<T> Callable<T> withCurrentCredentials(Callable<T> callable);

<T> Callable<T> asAdminTask(Callable<T> callable);

void checkGrant(GlobalFunction fn);

void checkGrant(ProjectFunction fn, int project);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,8 @@ public boolean apply(String tagName) {
@Override
public void importBuilds(final int branchId, final GitImportBuildsForm form) {
authorizationUtils.checkBranch(branchId, ProjectFunction.BUILD_CREATE);
executorImportBuilds.submit(new Runnable() {
@Override
public void run() {
securityUtils.asAdmin(new Callable<Void>() {
executorImportBuilds.submit(securityUtils.asAdminTask(
new Callable<Void>() {
@Override
public Void call() throws Exception {
try {
Expand All @@ -221,9 +219,8 @@ public Void call() throws Exception {
}
return null;
}
});
}
});
})
);
}

@Override
Expand Down

0 comments on commit 94bc88e

Please sign in to comment.