aboutsummaryrefslogtreecommitdiffstats
path: root/it/it-plugins
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2015-12-16 12:18:46 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2016-02-11 12:20:48 +0100
commit1d06608dbe0e02ce8ab12bf2116d7e6ae36d4657 (patch)
treeeb500577cc95f1bb86ff5e293ecc159ea908bbd0 /it/it-plugins
parent393a139c493e8a58d3e52cbc0a5d27faf8b9c3bb (diff)
downloadsonarqube-1d06608dbe0e02ce8ab12bf2116d7e6ae36d4657.tar.gz
sonarqube-1d06608dbe0e02ce8ab12bf2116d7e6ae36d4657.zip
Move ExternalAuthenticationTest ITs
Diffstat (limited to 'it/it-plugins')
-rw-r--r--it/it-plugins/pom.xml1
-rw-r--r--it/it-plugins/security-plugin/pom.xml59
-rw-r--r--it/it-plugins/security-plugin/src/main/java/FakeAuthenticator.java157
-rw-r--r--it/it-plugins/security-plugin/src/main/java/FakeGroupsProvider.java36
-rw-r--r--it/it-plugins/security-plugin/src/main/java/FakeRealm.java49
-rw-r--r--it/it-plugins/security-plugin/src/main/java/FakeUsersProvider.java36
-rw-r--r--it/it-plugins/security-plugin/src/main/java/SecurityPlugin.java30
-rw-r--r--it/it-plugins/security-plugin/src/test/java/FakeAuthenticatorTest.java126
8 files changed, 494 insertions, 0 deletions
diff --git a/it/it-plugins/pom.xml b/it/it-plugins/pom.xml
index 9dd4d8459da..fa1df6e5231 100644
--- a/it/it-plugins/pom.xml
+++ b/it/it-plugins/pom.xml
@@ -42,6 +42,7 @@
<module>project-builder-plugin</module>
<module>property-relocation-plugin</module>
<module>property-sets-plugin</module>
+ <module>security-plugin</module>
<module>server-plugin</module>
<module>settings-encryption-plugin</module>
<module>settings-plugin</module>
diff --git a/it/it-plugins/security-plugin/pom.xml b/it/it-plugins/security-plugin/pom.xml
new file mode 100644
index 00000000000..2243869854b
--- /dev/null
+++ b/it/it-plugins/security-plugin/pom.xml
@@ -0,0 +1,59 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.sonarsource.sonarqube</groupId>
+ <artifactId>it-plugins</artifactId>
+ <version>5.5-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>security-plugin</artifactId>
+ <packaging>sonar-plugin</packaging>
+ <version>1.0-SNAPSHOT</version>
+ <description>Plugins :: Security</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.sonarsource.sonarqube</groupId>
+ <artifactId>sonar-plugin-api</artifactId>
+ <version>${apiVersion}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.6</version>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <version>2.0.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-guava</artifactId>
+ <version>1.3.1</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.sonarsource.sonar-packaging-maven-plugin</groupId>
+ <artifactId>sonar-packaging-maven-plugin</artifactId>
+ <version>1.15</version>
+ <extensions>true</extensions>
+ <configuration>
+ <pluginClass>SecurityPlugin</pluginClass>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
diff --git a/it/it-plugins/security-plugin/src/main/java/FakeAuthenticator.java b/it/it-plugins/security-plugin/src/main/java/FakeAuthenticator.java
new file mode 100644
index 00000000000..6455d260b89
--- /dev/null
+++ b/it/it-plugins/security-plugin/src/main/java/FakeAuthenticator.java
@@ -0,0 +1,157 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.Properties;
+import org.sonar.api.Property;
+import org.sonar.api.PropertyType;
+import org.sonar.api.config.Settings;
+import org.sonar.api.security.LoginPasswordAuthenticator;
+import org.sonar.api.security.UserDetails;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+
+@Properties({
+ @Property(
+ key = FakeAuthenticator.DATA_PROPERTY,
+ name = "Fake Users", type = PropertyType.TEXT
+ )
+})
+public class FakeAuthenticator implements LoginPasswordAuthenticator {
+
+ private static final Logger LOG = Loggers.get(FakeAuthenticator.class);
+
+ /**
+ * Example:
+ * <pre>
+ * evgeny.password=foo
+ * evgeny.name=Evgeny Mandrikov
+ * evgeny.email=evgeny@example.org
+ * evgeny.groups=sonar-users
+ *
+ * simon.password=bar
+ * simon.groups=sonar-users,sonar-developers
+ * </pre>
+ */
+ public static final String DATA_PROPERTY = "sonar.fakeauthenticator.users";
+
+ private final Settings settings;
+
+ private Map<String, String> data;
+
+ public FakeAuthenticator(Settings settings) {
+ this.settings = settings;
+ }
+
+ public boolean authenticate(String username, String password) {
+ // Never touch admin
+ if (isAdmin(username)) {
+ return true;
+ }
+
+ reloadData();
+ checkExistence(username);
+
+ String expectedPassword = data.get(username + ".password");
+ if (StringUtils.equals(password, expectedPassword)) {
+ LOG.info("user {} with password {}", username, password);
+ return true;
+ } else {
+ LOG.info("user " + username + " expected password " + expectedPassword + " , but was " + password);
+ return false;
+ }
+ }
+
+ private void checkExistence(String username) {
+ if (!data.containsKey(username + ".password")) {
+ throw new RuntimeException("No such user");
+ }
+ }
+
+ public UserDetails doGetUserDetails(String username) {
+ // Never touch admin
+ if (isAdmin(username)) {
+ return null;
+ }
+
+ reloadData();
+ checkExistence(username);
+
+ UserDetails result = new UserDetails();
+ result.setName(Strings.nullToEmpty(data.get(username + ".name")));
+ result.setEmail(Strings.nullToEmpty(data.get(username + ".email")));
+ LOG.info("details for user {} : {}", username, result);
+ return result;
+ }
+
+ public Collection<String> doGetGroups(String username) {
+ // Never touch admin
+ if (isAdmin(username)) {
+ return null;
+ }
+
+ reloadData();
+ checkExistence(username);
+
+ Collection<String> result = parseList(data.get(username + ".groups"));
+ LOG.info("groups for user {} : {}", username, result);
+ return result;
+ }
+
+ private static boolean isAdmin(String username) {
+ return StringUtils.equals(username, "admin");
+ }
+
+ private void reloadData() {
+ data = parse(settings.getString(DATA_PROPERTY));
+ }
+
+ private static final Splitter LIST_SPLITTER = Splitter.on(',').omitEmptyStrings().trimResults();
+ private static final Splitter LINE_SPLITTER = Splitter.on(Pattern.compile("\r?\n")).omitEmptyStrings().trimResults();
+
+ @VisibleForTesting
+ static List<String> parseList(String data) {
+ return ImmutableList.copyOf(LIST_SPLITTER.split(Strings.nullToEmpty(data)));
+ }
+
+ @VisibleForTesting
+ static Map<String, String> parse(String data) {
+ Map<String, String> result = Maps.newHashMap();
+ for (String entry : LINE_SPLITTER.split(Strings.nullToEmpty(data))) {
+ Iterator<String> keyValue = Splitter.on('=').split(entry).iterator();
+ result.put(keyValue.next(), keyValue.next());
+ }
+ return result;
+ }
+
+ public void init() {
+ // nothing to do
+ }
+
+}
diff --git a/it/it-plugins/security-plugin/src/main/java/FakeGroupsProvider.java b/it/it-plugins/security-plugin/src/main/java/FakeGroupsProvider.java
new file mode 100644
index 00000000000..9c1666c5423
--- /dev/null
+++ b/it/it-plugins/security-plugin/src/main/java/FakeGroupsProvider.java
@@ -0,0 +1,36 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import java.util.Collection;
+import org.sonar.api.security.ExternalGroupsProvider;
+
+public class FakeGroupsProvider extends ExternalGroupsProvider {
+
+ private final FakeAuthenticator instance;
+
+ public FakeGroupsProvider(FakeAuthenticator instance) {
+ this.instance = instance;
+ }
+
+ @Override
+ public Collection<String> doGetGroups(String username) {
+ return instance.doGetGroups(username);
+ }
+
+}
diff --git a/it/it-plugins/security-plugin/src/main/java/FakeRealm.java b/it/it-plugins/security-plugin/src/main/java/FakeRealm.java
new file mode 100644
index 00000000000..4b4dd479836
--- /dev/null
+++ b/it/it-plugins/security-plugin/src/main/java/FakeRealm.java
@@ -0,0 +1,49 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import org.sonar.api.config.Settings;
+import org.sonar.api.security.ExternalGroupsProvider;
+import org.sonar.api.security.ExternalUsersProvider;
+import org.sonar.api.security.LoginPasswordAuthenticator;
+import org.sonar.api.security.SecurityRealm;
+
+public class FakeRealm extends SecurityRealm {
+
+ private FakeAuthenticator instance;
+
+ public FakeRealm(Settings settings) {
+ this.instance = new FakeAuthenticator(settings);
+ }
+
+ @Override
+ public LoginPasswordAuthenticator getLoginPasswordAuthenticator() {
+ return instance;
+ }
+
+ @Override
+ public ExternalGroupsProvider getGroupsProvider() {
+ return new FakeGroupsProvider(instance);
+ }
+
+ @Override
+ public ExternalUsersProvider getUsersProvider() {
+ return new FakeUsersProvider(instance);
+ }
+
+}
diff --git a/it/it-plugins/security-plugin/src/main/java/FakeUsersProvider.java b/it/it-plugins/security-plugin/src/main/java/FakeUsersProvider.java
new file mode 100644
index 00000000000..4ebae9deae1
--- /dev/null
+++ b/it/it-plugins/security-plugin/src/main/java/FakeUsersProvider.java
@@ -0,0 +1,36 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import org.sonar.api.security.ExternalUsersProvider;
+import org.sonar.api.security.UserDetails;
+
+public class FakeUsersProvider extends ExternalUsersProvider {
+
+ private final FakeAuthenticator instance;
+
+ public FakeUsersProvider(FakeAuthenticator instance) {
+ this.instance = instance;
+ }
+
+ @Override
+ public UserDetails doGetUserDetails(String username) {
+ return instance.doGetUserDetails(username);
+ }
+
+}
diff --git a/it/it-plugins/security-plugin/src/main/java/SecurityPlugin.java b/it/it-plugins/security-plugin/src/main/java/SecurityPlugin.java
new file mode 100644
index 00000000000..c2582893c70
--- /dev/null
+++ b/it/it-plugins/security-plugin/src/main/java/SecurityPlugin.java
@@ -0,0 +1,30 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import java.util.Arrays;
+import java.util.List;
+import org.sonar.api.SonarPlugin;
+
+public class SecurityPlugin extends SonarPlugin {
+
+ public List getExtensions() {
+ return Arrays.asList(FakeRealm.class, FakeAuthenticator.class);
+ }
+
+}
diff --git a/it/it-plugins/security-plugin/src/test/java/FakeAuthenticatorTest.java b/it/it-plugins/security-plugin/src/test/java/FakeAuthenticatorTest.java
new file mode 100644
index 00000000000..6a0b1884a05
--- /dev/null
+++ b/it/it-plugins/security-plugin/src/test/java/FakeAuthenticatorTest.java
@@ -0,0 +1,126 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+import java.util.Map;
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.config.Settings;
+import org.sonar.api.security.UserDetails;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+
+public class FakeAuthenticatorTest {
+
+ private Settings settings;
+ private FakeAuthenticator authenticator;
+
+ @Before
+ public void setUp() {
+ settings = new Settings();
+ authenticator = new FakeAuthenticator(settings);
+ authenticator.init();
+ }
+
+ @Test
+ public void shouldNeverTouchAdmin() {
+ assertThat(authenticator.authenticate("admin", "admin")).isTrue();
+ assertThat(authenticator.doGetGroups("admin")).isNull();
+ assertThat(authenticator.doGetUserDetails("admin")).isNull();
+ }
+
+ @Test
+ public void shouldAuthenticateFakeUsers() {
+ settings.setProperty(FakeAuthenticator.DATA_PROPERTY, "evgeny.password=foo");
+
+ assertThat(authenticator.authenticate("evgeny", "foo")).isTrue();
+ assertThat(authenticator.authenticate("evgeny", "bar")).isFalse();
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void shouldNotAuthenticateNotExistingUsers() {
+ authenticator.authenticate("evgeny", "foo");
+ }
+
+ @Test
+ public void shouldGetUserDetails() {
+ settings.setProperty(FakeAuthenticator.DATA_PROPERTY, "evgeny.password=foo\n" +
+ "evgeny.name=Tester Testerovich\n" +
+ "evgeny.email=evgeny@example.org");
+
+ UserDetails details = authenticator.doGetUserDetails("evgeny");
+ assertThat(details.getName()).isEqualTo("Tester Testerovich");
+ assertThat(details.getEmail()).isEqualTo("evgeny@example.org");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void shouldNotReturnDetailsForNotExistingUsers() {
+ authenticator.doGetUserDetails("evgeny");
+ }
+
+ @Test
+ public void shouldGetGroups() {
+ settings.setProperty(FakeAuthenticator.DATA_PROPERTY, "evgeny.password=foo\n" +
+ "evgeny.groups=sonar-users,sonar-developers");
+
+ assertThat(authenticator.doGetGroups("evgeny")).containsOnly("sonar-users", "sonar-developers");
+ }
+
+ @Test(expected = RuntimeException.class)
+ public void shouldNotReturnGroupsForNotExistingUsers() {
+ authenticator.doGetGroups("evgeny");
+ }
+
+ @Test
+ public void shouldParseList() {
+ assertThat(FakeAuthenticator.parseList(null)).isEmpty();
+ assertThat(FakeAuthenticator.parseList("")).isEmpty();
+ assertThat(FakeAuthenticator.parseList(",,,")).isEmpty();
+ assertThat(FakeAuthenticator.parseList("a,b")).containsOnly("a", "b");
+ }
+
+ @Test
+ public void shouldParseMap() {
+ Map<String, String> map = FakeAuthenticator.parse(null);
+ assertThat(map).isEmpty();
+
+ map = FakeAuthenticator.parse("");
+ assertThat(map).isEmpty();
+
+ map = FakeAuthenticator.parse("foo=bar");
+ assertThat(map).hasSize(1);
+ assertThat(map.get("foo")).isEqualTo("bar");
+
+ map = FakeAuthenticator.parse("foo=bar\r\nbaz=qux");
+ assertThat(map).hasSize(2);
+ assertThat(map.get("foo")).isEqualTo("bar");
+ assertThat(map.get("baz")).isEqualTo("qux");
+
+ map = FakeAuthenticator.parse("foo=bar\nbaz=qux");
+ assertThat(map).hasSize(2);
+ assertThat(map.get("foo")).isEqualTo("bar");
+ assertThat(map.get("baz")).isEqualTo("qux");
+
+ map = FakeAuthenticator.parse("foo=bar\n\n\nbaz=qux");
+ assertThat(map).hasSize(2);
+ assertThat(map.get("foo")).isEqualTo("bar");
+ assertThat(map.get("baz")).isEqualTo("qux");
+ }
+
+}