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