]> source.dussan.org Git - gitblit.git/commitdiff
Added RedmineUserService
authormallowlabs <mallowlabs@gmail.com>
Sat, 8 Sep 2012 12:40:53 +0000 (21:40 +0900)
committermallowlabs <mallowlabs@gmail.com>
Sat, 8 Sep 2012 12:40:53 +0000 (21:40 +0900)
distrib/gitblit.properties
src/com/gitblit/RedmineUserService.java [new file with mode: 0644]
tests/com/gitblit/tests/RedmineUserServiceTest.java [new file with mode: 0644]

index c7f0ae35db8c73d1fcb53e889d873b75fb09aaa3..fe7692be3140b2df122af0a89d418b35bbdcaf5e 100644 (file)
@@ -301,6 +301,7 @@ web.projectsFile = projects.conf
 #\r
 # Alternative user services:\r
 #    com.gitblit.LdapUserService\r
+#    com.gitblit.RedmineUserService\r
 #\r
 # Any custom user service implementation must have a public default constructor.\r
 #\r
@@ -941,6 +942,16 @@ realm.ldap.displayName = displayName
 # SINCE 1.0.0\r
 realm.ldap.email = email\r
 \r
+# The RedmineUserService must be backed by another user service for standard user\r
+# and team management.\r
+# default: users.conf\r
+#\r
+# RESTART REQUIRED\r
+realm.redmine.backingUserService = users.conf\r
+\r
+# URL of the Redmine.\r
+realm.redmine.url = http://example.com/redmine\r
+\r
 #\r
 # Server Settings\r
 #\r
diff --git a/src/com/gitblit/RedmineUserService.java b/src/com/gitblit/RedmineUserService.java
new file mode 100644 (file)
index 0000000..93d1af8
--- /dev/null
@@ -0,0 +1,128 @@
+package com.gitblit;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.io.InputStreamReader;\r
+import java.net.HttpURLConnection;\r
+import java.net.URL;\r
+\r
+import org.apache.wicket.util.io.IOUtils;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.gitblit.models.UserModel;\r
+import com.google.gson.Gson;\r
+\r
+/**\r
+ * Implementation of an Redmine user service.<br>\r
+ * you can login to gitblit with Redmine user id and api key.\r
+ */\r
+public class RedmineUserService extends GitblitUserService {\r
+\r
+    private final Logger logger = LoggerFactory.getLogger(RedmineUserService.class);\r
+\r
+    private IStoredSettings settings;\r
+\r
+    private String testingJson;\r
+\r
+    private class RedmineCurrent {\r
+        private class RedmineUser {\r
+            public String login;\r
+            public String firstname;\r
+            public String lastname;\r
+            public String mail;\r
+        }\r
+\r
+        public RedmineUser user;\r
+    }\r
+\r
+    public RedmineUserService() {\r
+        super();\r
+    }\r
+\r
+    @Override\r
+    public void setup(IStoredSettings settings) {\r
+        this.settings = settings;\r
+\r
+        String file = settings.getString(Keys.realm.redmine.backingUserService, "users.conf");\r
+        File realmFile = GitBlit.getFileOrFolder(file);\r
+\r
+        serviceImpl = createUserService(realmFile);\r
+        logger.info("Redmine User Service backed by " + serviceImpl.toString());\r
+    }\r
+\r
+    @Override\r
+    public boolean supportsCredentialChanges() {\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public boolean supportsDisplayNameChanges() {\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public boolean supportsEmailAddressChanges() {\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public boolean supportsTeamMembershipChanges() {\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public boolean supportsCookies() {\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public UserModel authenticate(String username, char[] password) {\r
+        String urlText = this.settings.getString(Keys.realm.redmine.url, "");\r
+        if (!urlText.endsWith("/")) {\r
+            urlText.concat("/");\r
+        }\r
+        String apiKey = String.valueOf(password);\r
+\r
+        try {\r
+            String jsonString = getCurrentUserAsJson(urlText, apiKey);\r
+\r
+            RedmineCurrent current = new Gson().fromJson(jsonString, RedmineCurrent.class);\r
+            String login = current.user.login;\r
+\r
+            if (username.equalsIgnoreCase(login)) {\r
+                UserModel userModel = new UserModel(login);\r
+                userModel.displayName = current.user.firstname + " " + current.user.lastname;\r
+                userModel.emailAddress = current.user.mail;\r
+                userModel.canAdmin = true;\r
+                return userModel;\r
+            }\r
+\r
+        } catch (IOException e) {\r
+            logger.error("authenticate", e);\r
+        }\r
+        return null;\r
+    }\r
+\r
+    private String getCurrentUserAsJson(String url, String apiKey) throws IOException {\r
+        if (testingJson != null) { // for testing\r
+            return testingJson;\r
+        }\r
+\r
+        URL apiUrl = new URL(url + "users/current.json?key=" + apiKey);\r
+        HttpURLConnection http = (HttpURLConnection) apiUrl.openConnection();\r
+        http.setRequestMethod("GET");\r
+        http.connect();\r
+        InputStreamReader reader = new InputStreamReader(http.getInputStream());\r
+        return IOUtils.toString(reader);\r
+    }\r
+\r
+    /**\r
+     * set json response. do NOT invoke from production code.\r
+     * @param json json\r
+     */\r
+    public void setTestingCurrentUserAsJson(String json) {\r
+        this.testingJson = json;\r
+    }\r
+\r
+}\r
diff --git a/tests/com/gitblit/tests/RedmineUserServiceTest.java b/tests/com/gitblit/tests/RedmineUserServiceTest.java
new file mode 100644 (file)
index 0000000..a6a8a5e
--- /dev/null
@@ -0,0 +1,41 @@
+package com.gitblit.tests;\r
+\r
+import static org.hamcrest.CoreMatchers.is;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.assertThat;\r
+\r
+import java.util.HashMap;\r
+\r
+import org.junit.Test;\r
+\r
+import com.gitblit.RedmineUserService;\r
+import com.gitblit.models.UserModel;\r
+import com.gitblit.tests.mock.MemorySettings;\r
+\r
+public class RedmineUserServiceTest {\r
+\r
+    private static final String JSON = "{\"user\":{\"created_on\":\"2011-03-28T00:41:29Z\",\"lastname\":\"foo\","\r
+        + "\"last_login_on\":\"2012-09-06T23:59:26Z\",\"firstname\":\"baz\","\r
+        + "\"id\":4,\"login\":\"RedmineUserId\",\"mail\":\"baz@example.com\"}}";\r
+\r
+    @Test\r
+    public void testAuthenticate() throws Exception {\r
+        RedmineUserService redmineUserService = new RedmineUserService();\r
+        redmineUserService.setup(new MemorySettings(new HashMap<String, Object>()));\r
+        redmineUserService.setTestingCurrentUserAsJson(JSON);\r
+        UserModel userModel = redmineUserService.authenticate("RedmineUserId", "RedmineAPIKey".toCharArray());\r
+        assertThat(userModel.getName(), is("RedmineUserId"));\r
+        assertThat(userModel.getDisplayName(), is("baz foo"));\r
+        assertThat(userModel.emailAddress, is("baz@example.com"));\r
+    }\r
+\r
+    @Test\r
+    public void testAuthenticateWithWronId() throws Exception {\r
+        RedmineUserService redmineUserService = new RedmineUserService();\r
+        redmineUserService.setup(new MemorySettings(new HashMap<String, Object>()));\r
+        redmineUserService.setTestingCurrentUserAsJson(JSON);\r
+        UserModel userModel = redmineUserService.authenticate("WrongRedmineUserId", "RedmineAPIKey".toCharArray());\r
+        assertNull(userModel);\r
+    }\r
+\r
+}\r