]> source.dussan.org Git - gitblit.git/commitdiff
Added support for authenticating against a Salesforce org. 93/head
authorWilliam Whittle <william.whittle@gmail.com>
Fri, 7 Jun 2013 15:04:18 +0000 (16:04 +0100)
committerWilliam Whittle <william.whittle@gmail.com>
Fri, 7 Jun 2013 15:09:49 +0000 (16:09 +0100)
.classpath
build.moxie
gitblit.iml
src/main/distrib/data/gitblit.properties
src/main/java/com/gitblit/SalesforceUserService.java [new file with mode: 0644]

index ffb673d867475e86ce62206b30b229917746b23e..e25f68c51bcd7421128a2d1cf0b6070a785883fb 100644 (file)
@@ -37,6 +37,9 @@
        <classpathentry kind="lib" path="ext/jcalendar-1.3.2.jar" />
        <classpathentry kind="lib" path="ext/commons-compress-1.4.1.jar" sourcepath="ext/src/commons-compress-1.4.1.jar" />
        <classpathentry kind="lib" path="ext/xz-1.0.jar" sourcepath="ext/src/xz-1.0.jar" />
+       <classpathentry kind="lib" path="ext/force-partner-api-24.0.0.jar" sourcepath="ext/src/force-partner-api-24.0.0.jar" />
+       <classpathentry kind="lib" path="ext/force-wsc-24.0.0.jar" sourcepath="ext/src/force-wsc-24.0.0.jar" />
+       <classpathentry kind="lib" path="ext/js-1.7R2.jar" sourcepath="ext/src/js-1.7R2.jar" />
        <classpathentry kind="lib" path="ext/junit-4.11.jar" sourcepath="ext/src/junit-4.11.jar" />
        <classpathentry kind="lib" path="ext/hamcrest-core-1.3.jar" sourcepath="ext/src/hamcrest-core-1.3.jar" />
        <classpathentry kind="lib" path="ext/selenium-java-2.28.0.jar" sourcepath="ext/src/selenium-java-2.28.0.jar" />
index d27e08a6d0b7e5cac6351cceaef12d8ba56e1dd3..be9a21cf8205250d4ee65901af67ed19dd03ff5f 100644 (file)
@@ -147,6 +147,7 @@ dependencies:
 - compile 'org.apache.ivy:ivy:2.2.0' :war
 - compile 'com.toedter:jcalendar:1.3.2' :authority
 - compile 'org.apache.commons:commons-compress:1.4.1' :war
+- compile 'com.force.api:force-partner-api:24.0.0' :war
 - test 'junit'
 # Dependencies for Selenium web page testing
 - test 'org.seleniumhq.selenium:selenium-java:${selenium.version}' @jar
index fe245be2ec885ca51e2bd454d9ab6d8021ae9acd..b90adbd02a93a32bdafc2596ffe0e52765a597a3 100644 (file)
         </SOURCES>
       </library>
     </orderEntry>
+    <orderEntry type="module-library">
+      <library name="force-partner-api-24.0.0.jar">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/ext/force-partner-api-24.0.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/ext/src/force-partner-api-24.0.0.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library name="force-wsc-24.0.0.jar">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/ext/force-wsc-24.0.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/ext/src/force-wsc-24.0.0.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library name="js-1.7R2.jar">
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/ext/js-1.7R2.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/ext/src/js-1.7R2.jar!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
     <orderEntry type="module-library" scope="TEST">
       <library name="junit-4.11.jar">
         <CLASSES>
index 36d780351f75f5e9bb4b4bc76b69d3c00040fc6f..82e77f3573e23b7405842e79eaacc3aa67993967 100644 (file)
@@ -499,6 +499,7 @@ web.projectsFile = ${baseFolder}/projects.conf
 # Alternative user services:\r
 #    com.gitblit.LdapUserService\r
 #    com.gitblit.RedmineUserService\r
+#    com.gitblit.SalesforceUserService\r
 #\r
 # Any custom user service implementation must have a public default constructor.\r
 #\r
@@ -1096,6 +1097,20 @@ federation.sets =
 # Advanced Realm Settings\r
 #\r
 \r
+# The SalesforceUserService must be backed by another user service for standard user\r
+# and team management.\r
+# default: users.conf\r
+#\r
+# RESTART REQUIRED\r
+# BASEFOLDER\r
+realm.salesforce.backingUserService = ${baseFolder}/users.conf\r
+\r
+# Restrict the Salesforce user to members of this org.\r
+# default: 0 (i.e. do not check the Org ID)\r
+#\r
+# RESTART REQUIRED\r
+realm.salesforce.orgId = 0\r
+\r
 # URL of the LDAP server.\r
 # To use encrypted transport, use either ldaps:// URL for SSL or ldap+tls:// to\r
 # send StartTLS command.\r
diff --git a/src/main/java/com/gitblit/SalesforceUserService.java b/src/main/java/com/gitblit/SalesforceUserService.java
new file mode 100644 (file)
index 0000000..4a6a1ba
--- /dev/null
@@ -0,0 +1,132 @@
+package com.gitblit;
+
+import java.io.File;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.gitblit.models.UserModel;
+import com.gitblit.utils.ArrayUtils;
+import com.gitblit.utils.StringUtils;
+import com.sforce.soap.partner.Connector;
+import com.sforce.soap.partner.GetUserInfoResult;
+import com.sforce.soap.partner.PartnerConnection;
+import com.sforce.ws.ConnectionException;
+import com.sforce.ws.ConnectorConfig;
+
+public class SalesforceUserService extends GitblitUserService {
+       public static final Logger logger = LoggerFactory
+                       .getLogger(SalesforceUserService.class);
+       private IStoredSettings settings;
+
+       @Override
+       public void setup(IStoredSettings settings) {
+               this.settings = settings;
+               String file = settings.getString(
+                               Keys.realm.salesforce.backingUserService,
+                               "${baseFolder}/users.conf");
+               File realmFile = GitBlit.getFileOrFolder(file);
+
+               serviceImpl = createUserService(realmFile);
+
+               logger.info("Salesforce User Service backed by "
+                               + serviceImpl.toString());
+       }
+
+       @Override
+       public UserModel authenticate(String username, char[] password) {
+               if (isLocalAccount(username)) {
+                       // local account, bypass Salesforce authentication
+                       return super.authenticate(username, password);
+               }
+
+               ConnectorConfig config = new ConnectorConfig();
+               config.setUsername(username);
+               config.setPassword(new String(password));
+
+               try {
+                       PartnerConnection connection = Connector.newConnection(config);
+
+                       GetUserInfoResult info = connection.getUserInfo();
+
+                       String org = settings.getString(Keys.realm.salesforce.orgId, "0")
+                                       .trim();
+
+                       if (!org.equals("0")) {
+                               if (!org.equals(info.getOrganizationId())) {
+                                       logger.warn("Access attempted by user of an invalid org: "
+                                                       + info.getUserName() + ", org: "
+                                                       + info.getOrganizationName() + "("
+                                                       + info.getOrganizationId() + ")");
+
+                                       return null;
+                               }
+                       }
+
+                       logger.info("Authenticated user " + info.getUserName()
+                                       + " using org " + info.getOrganizationName() + "("
+                                       + info.getOrganizationId() + ")");
+
+                       String simpleUsername = getSimpleUsername(info);
+
+                       UserModel user = null;
+                       synchronized (this) {
+                               user = getUserModel(simpleUsername);
+                               if (user == null)
+                                       user = new UserModel(simpleUsername);
+
+                               if (StringUtils.isEmpty(user.cookie)
+                                               && !ArrayUtils.isEmpty(password)) {
+                                       user.cookie = StringUtils.getSHA1(user.username
+                                                       + new String(password));
+                               }
+
+                               setUserAttributes(user, info);
+
+                               super.updateUserModel(user);
+                       }
+
+                       return user;
+               } catch (ConnectionException e) {
+                       logger.error("Failed to authenticate", e);
+               }
+
+               return null;
+       }
+
+       private void setUserAttributes(UserModel user, GetUserInfoResult info) {
+               // Don't want visibility into the real password, make up a dummy
+               user.password = ExternalAccount;
+               user.accountType = getAccountType();
+
+               // Get full name Attribute
+               user.displayName = info.getUserFullName();
+
+               // Get email address Attribute
+               user.emailAddress = info.getUserEmail();
+       }
+
+       /**
+        * Simple user name is the first part of the email address.
+        */
+       private String getSimpleUsername(GetUserInfoResult info) {
+               String email = info.getUserEmail();
+
+               return email.split("@")[0];
+       }
+
+       @Override
+       public boolean supportsCredentialChanges() {
+               return false;
+       }
+
+       @Override
+       public boolean supportsDisplayNameChanges() {
+               return false;
+       }
+
+       @Override
+       public boolean supportsEmailAddressChanges() {
+               return false;
+       }
+}