From 377b2087815b3b6da05d9f4a7718b9fae7abd71e Mon Sep 17 00:00:00 2001 From: Sébastien Lesaint <sebastien.lesaint@sonarsource.com> Date: Tue, 4 Oct 2016 11:10:31 +0200 Subject: SONAR-8155 add UserSession#isRoot and checkIsRoot --- .../main/java/org/sonar/ce/user/CeUserSession.java | 10 ++++ .../org/sonar/server/user/AbstractUserSession.java | 12 ++++- .../java/org/sonar/server/user/DoPrivileged.java | 5 ++ .../org/sonar/server/user/ServerUserSession.java | 5 ++ .../sonar/server/user/ThreadLocalUserSession.java | 11 +++++ .../java/org/sonar/server/user/UserSession.java | 7 +++ .../server/tester/AnonymousMockUserSession.java | 5 ++ .../org/sonar/server/tester/MockUserSession.java | 10 ++++ .../org/sonar/server/tester/UserSessionRule.java | 23 ++++++++- .../sonar/server/user/ServerUserSessionTest.java | 54 ++++++++++++++++------ .../src/main/java/org/sonar/db/user/UserDto.java | 5 +- 11 files changed, 128 insertions(+), 19 deletions(-) diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/user/CeUserSession.java b/server/sonar-ce/src/main/java/org/sonar/ce/user/CeUserSession.java index f1bb8212bb1..b805e1749be 100644 --- a/server/sonar-ce/src/main/java/org/sonar/ce/user/CeUserSession.java +++ b/server/sonar-ce/src/main/java/org/sonar/ce/user/CeUserSession.java @@ -65,6 +65,16 @@ public class CeUserSession implements UserSession { return notImplemented(); } + @Override + public boolean isRoot() { + return notImplementedBooleanMethod(); + } + + @Override + public UserSession checkIsRoot() { + return notImplemented(); + } + @Override public UserSession checkLoggedIn() { return notImplemented(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/AbstractUserSession.java b/server/sonar-server/src/main/java/org/sonar/server/user/AbstractUserSession.java index e5441c5faf8..d43a1db5350 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/AbstractUserSession.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/AbstractUserSession.java @@ -27,11 +27,21 @@ import org.sonar.server.exceptions.UnauthorizedException; public abstract class AbstractUserSession implements UserSession { private static final String INSUFFICIENT_PRIVILEGES_MESSAGE = "Insufficient privileges"; private static final ForbiddenException INSUFFICIENT_PRIVILEGES_EXCEPTION = new ForbiddenException(INSUFFICIENT_PRIVILEGES_MESSAGE); + private static final String AUTHENTICATION_IS_REQUIRED_MESSAGE = "Authentication is required"; @Override public UserSession checkLoggedIn() { if (!isLoggedIn()) { - throw new UnauthorizedException("Authentication is required"); + throw new UnauthorizedException(AUTHENTICATION_IS_REQUIRED_MESSAGE); + } + return this; + } + + + @Override + public UserSession checkIsRoot() { + if (!isRoot()) { + throw new UnauthorizedException(AUTHENTICATION_IS_REQUIRED_MESSAGE); } return this; } diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/DoPrivileged.java b/server/sonar-server/src/main/java/org/sonar/server/user/DoPrivileged.java index 120911e9f61..cd00aaddf34 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/DoPrivileged.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/DoPrivileged.java @@ -92,6 +92,11 @@ public final class DoPrivileged { return false; } + @Override + public boolean isRoot() { + return false; + } + @Override public Locale locale() { return Locale.getDefault(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ServerUserSession.java b/server/sonar-server/src/main/java/org/sonar/server/user/ServerUserSession.java index 9aafd5f4e1d..3ccf912885e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ServerUserSession.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ServerUserSession.java @@ -125,6 +125,11 @@ public class ServerUserSession extends AbstractUserSession { return Locale.ENGLISH; } + @Override + public boolean isRoot() { + return userDto != null && userDto.isRoot(); + } + @Override public List<String> globalPermissions() { if (globalPermissions == null) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java b/server/sonar-server/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java index 7e46f810a98..12594ace597 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ThreadLocalUserSession.java @@ -86,6 +86,17 @@ public class ThreadLocalUserSession implements UserSession { return get().locale(); } + @Override + public boolean isRoot() { + return get().isRoot(); + } + + @Override + public UserSession checkIsRoot() { + get().checkIsRoot(); + return this; + } + @Override public UserSession checkLoggedIn() { get().checkLoggedIn(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/UserSession.java b/server/sonar-server/src/main/java/org/sonar/server/user/UserSession.java index 1e5e1c57557..2373cf0c9fe 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/UserSession.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/UserSession.java @@ -45,6 +45,13 @@ public interface UserSession { @Deprecated Locale locale(); + boolean isRoot(); + + /** + * Ensures that user is root in otherwise throws {@link org.sonar.server.exceptions.UnauthorizedException}. + */ + UserSession checkIsRoot(); + /** * Ensures that user is logged in otherwise throws {@link org.sonar.server.exceptions.UnauthorizedException}. */ diff --git a/server/sonar-server/src/test/java/org/sonar/server/tester/AnonymousMockUserSession.java b/server/sonar-server/src/test/java/org/sonar/server/tester/AnonymousMockUserSession.java index f1502fd75dd..6da49c33c0e 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/tester/AnonymousMockUserSession.java +++ b/server/sonar-server/src/test/java/org/sonar/server/tester/AnonymousMockUserSession.java @@ -25,6 +25,11 @@ public class AnonymousMockUserSession extends AbstractMockUserSession<AnonymousM super(AnonymousMockUserSession.class); } + @Override + public boolean isRoot() { + return false; + } + @Override public String getLogin() { return null; diff --git a/server/sonar-server/src/test/java/org/sonar/server/tester/MockUserSession.java b/server/sonar-server/src/test/java/org/sonar/server/tester/MockUserSession.java index 8df3ab8fa78..df409a00c58 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/tester/MockUserSession.java +++ b/server/sonar-server/src/test/java/org/sonar/server/tester/MockUserSession.java @@ -25,6 +25,7 @@ import static com.google.common.base.Preconditions.checkArgument; public class MockUserSession extends AbstractMockUserSession<MockUserSession> { private final String login; + private boolean root = false; private Integer userId; private String name; @@ -41,6 +42,15 @@ public class MockUserSession extends AbstractMockUserSession<MockUserSession> { return true; } + @Override + public boolean isRoot() { + return root; + } + + public void setRoot(boolean root) { + this.root = root; + } + @Override public String getLogin() { return this.login; diff --git a/server/sonar-server/src/test/java/org/sonar/server/tester/UserSessionRule.java b/server/sonar-server/src/test/java/org/sonar/server/tester/UserSessionRule.java index 243ba5daa8b..2da0a3a0794 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/tester/UserSessionRule.java +++ b/server/sonar-server/src/test/java/org/sonar/server/tester/UserSessionRule.java @@ -78,7 +78,7 @@ import static com.google.common.base.Preconditions.checkState; * </p> */ public class UserSessionRule implements TestRule, UserSession { - public static final String DEFAULT_LOGIN = "default_login"; + private static final String DEFAULT_LOGIN = "default_login"; @CheckForNull private final ServerTester serverTester; @@ -120,6 +120,16 @@ public class UserSessionRule implements TestRule, UserSession { return this; } + public UserSessionRule setRoot() { + ensureMockUserSession().setRoot(true); + return this; + } + + public UserSessionRule setNonRoot() { + ensureMockUserSession().setRoot(false); + return this; + } + @Override public Statement apply(Statement statement, Description description) { return this.statement(statement); @@ -269,6 +279,17 @@ public class UserSessionRule implements TestRule, UserSession { return currentUserSession.locale(); } + @Override + public boolean isRoot() { + return currentUserSession.isRoot(); + } + + @Override + public UserSession checkIsRoot() { + currentUserSession.checkIsRoot(); + return this; + } + @Override public UserSession checkLoggedIn() { currentUserSession.checkLoggedIn(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java index 3c43cb13048..07d3956ab6c 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java @@ -37,6 +37,7 @@ import org.sonar.db.permission.GroupPermissionDto; import org.sonar.db.permission.UserPermissionDto; import org.sonar.db.user.UserDto; import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.UnauthorizedException; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN; @@ -47,35 +48,58 @@ import static org.sonar.server.user.ServerUserSession.createForAnonymous; import static org.sonar.server.user.ServerUserSession.createForUser; public class ServerUserSessionTest { - static final String LOGIN = "marius"; - - static final String PROJECT_UUID = "ABCD"; - static final String FILE_KEY = "com.foo:Bar:BarFile.xoo"; - static final String FILE_UUID = "BCDE"; + private static final String LOGIN = "marius"; + + private static final String PROJECT_UUID = "ABCD"; + private static final String FILE_KEY = "com.foo:Bar:BarFile.xoo"; + private static final String FILE_UUID = "BCDE"; + private static final UserDto ROOT_USER_DTO = new UserDto() {{ + setRoot(true); + }}.setLogin("root_user"); + private static final UserDto NON_ROOT_USER_DTO = new UserDto() {{ + setRoot(false); + }}.setLogin("regular_user"); @Rule public DbTester dbTester = DbTester.create(System2.INSTANCE); - @Rule public ExpectedException expectedException = ExpectedException.none(); - ComponentDbTester componentDbTester = new ComponentDbTester(dbTester); - - DbClient dbClient = dbTester.getDbClient(); - - DbSession dbSession = dbTester.getSession(); - - UserDto userDto = newUserDto().setLogin(LOGIN); - ComponentDto project, file; + private ComponentDbTester componentDbTester = new ComponentDbTester(dbTester); + private DbClient dbClient = dbTester.getDbClient(); + private DbSession dbSession = dbTester.getSession(); + private UserDto userDto = newUserDto().setLogin(LOGIN); + private ComponentDto project; @Before public void setUp() throws Exception { project = componentDbTester.insertComponent(ComponentTesting.newProjectDto(PROJECT_UUID)); - file = componentDbTester.insertComponent(ComponentTesting.newFileDto(project, null, FILE_UUID).setKey(FILE_KEY)); + componentDbTester.insertComponent(ComponentTesting.newFileDto(project, null, FILE_UUID).setKey(FILE_KEY)); dbClient.userDao().insert(dbSession, userDto); dbSession.commit(); } + @Test + public void isRoot_is_false_is_flag_root_is_false_on_UserDto() { + assertThat(newUserSession(ROOT_USER_DTO).isRoot()).isTrue(); + assertThat(newUserSession(NON_ROOT_USER_DTO).isRoot()).isFalse(); + } + + @Test + public void checkIsRoot_fails_with_UnauthorizedException_when_flag_is_false_on_UserDto() { + expectedException.expect(UnauthorizedException.class); + expectedException.expectMessage("Authentication is required"); + + newUserSession(NON_ROOT_USER_DTO).checkIsRoot(); + } + + @Test + public void checkIsRoot_does_not_fails_when_flag_is_true_on_UserDto() { + ServerUserSession underTest = newUserSession(ROOT_USER_DTO); + + assertThat(underTest.checkIsRoot()).isSameAs(underTest); + } + @Test public void has_global_permission() { addGlobalPermissions("admin", "profileadmin"); diff --git a/sonar-db/src/main/java/org/sonar/db/user/UserDto.java b/sonar-db/src/main/java/org/sonar/db/user/UserDto.java index df3d9e02726..385968943fd 100644 --- a/sonar-db/src/main/java/org/sonar/db/user/UserDto.java +++ b/sonar-db/src/main/java/org/sonar/db/user/UserDto.java @@ -207,13 +207,14 @@ public class UserDto { } /** - * Setters is not accessible as dedicated requests must be used to update the root flag of a user: + * Setters is not accessible as MyBatis doesn't need setter to set the field and dedicated SQL requests must be used + * to update the root flag of a user: * <ul> * <li>a user can not be created root</li> * <li>the generic update method of a user can not change its root flag</li> * </ul> */ - private void setRoot(boolean root) { + protected void setRoot(boolean root) { this.root = root; } -- cgit v1.2.3