You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

LdapGroupMapping.java 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2019 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.auth.ldap;
  21. import java.util.Arrays;
  22. import javax.naming.NamingException;
  23. import javax.naming.directory.Attribute;
  24. import javax.naming.directory.SearchResult;
  25. import org.apache.commons.lang.StringUtils;
  26. import org.sonar.api.config.Settings;
  27. import org.sonar.api.utils.log.Logger;
  28. import org.sonar.api.utils.log.Loggers;
  29. /**
  30. * @author Evgeny Mandrikov
  31. */
  32. public class LdapGroupMapping {
  33. private static final Logger LOG = Loggers.get(LdapGroupMapping.class);
  34. private static final String DEFAULT_OBJECT_CLASS = "groupOfUniqueNames";
  35. private static final String DEFAULT_ID_ATTRIBUTE = "cn";
  36. private static final String DEFAULT_MEMBER_ATTRIBUTE = "uniqueMember";
  37. private static final String DEFAULT_REQUEST = "(&(objectClass=groupOfUniqueNames)(uniqueMember={dn}))";
  38. private final String baseDn;
  39. private final String idAttribute;
  40. private final String request;
  41. private final String[] requiredUserAttributes;
  42. /**
  43. * Constructs mapping from Sonar settings.
  44. */
  45. public LdapGroupMapping(Settings settings, String settingsPrefix) {
  46. this.baseDn = settings.getString(settingsPrefix + ".group.baseDn");
  47. this.idAttribute = StringUtils.defaultString(settings.getString(settingsPrefix + ".group.idAttribute"), DEFAULT_ID_ATTRIBUTE);
  48. String objectClass = settings.getString(settingsPrefix + ".group.objectClass");
  49. String memberAttribute = settings.getString(settingsPrefix + ".group.memberAttribute");
  50. String req;
  51. if (StringUtils.isNotBlank(objectClass) || StringUtils.isNotBlank(memberAttribute)) {
  52. // For backward compatibility with plugin versions 1.1 and 1.1.1
  53. objectClass = StringUtils.defaultString(objectClass, DEFAULT_OBJECT_CLASS);
  54. memberAttribute = StringUtils.defaultString(memberAttribute, DEFAULT_MEMBER_ATTRIBUTE);
  55. req = "(&(objectClass=" + objectClass + ")(" + memberAttribute + "=" + "{dn}))";
  56. LOG.warn("Properties '" + settingsPrefix + ".group.objectClass' and '" + settingsPrefix + ".group.memberAttribute' are deprecated" +
  57. " and should be replaced by single property '" + settingsPrefix + ".group.request' with value: " + req);
  58. } else {
  59. req = StringUtils.defaultString(settings.getString(settingsPrefix + ".group.request"), DEFAULT_REQUEST);
  60. }
  61. this.requiredUserAttributes = StringUtils.substringsBetween(req, "{", "}");
  62. for (int i = 0; i < requiredUserAttributes.length; i++) {
  63. req = StringUtils.replace(req, "{" + requiredUserAttributes[i] + "}", "{" + i + "}");
  64. }
  65. this.request = req;
  66. }
  67. /**
  68. * Search for this mapping.
  69. */
  70. public LdapSearch createSearch(LdapContextFactory contextFactory, SearchResult user) {
  71. String[] attrs = getRequiredUserAttributes();
  72. String[] parameters = new String[attrs.length];
  73. for (int i = 0; i < parameters.length; i++) {
  74. String attr = attrs[i];
  75. if ("dn".equals(attr)) {
  76. parameters[i] = user.getNameInNamespace();
  77. } else {
  78. parameters[i] = getAttributeValue(user, attr);
  79. }
  80. }
  81. return new LdapSearch(contextFactory)
  82. .setBaseDn(getBaseDn())
  83. .setRequest(getRequest())
  84. .setParameters(parameters)
  85. .returns(getIdAttribute());
  86. }
  87. private static String getAttributeValue(SearchResult user, String attributeId) {
  88. Attribute attribute = user.getAttributes().get(attributeId);
  89. if (attribute == null) {
  90. return null;
  91. }
  92. try {
  93. return (String) attribute.get();
  94. } catch (NamingException e) {
  95. throw new IllegalArgumentException(e);
  96. }
  97. }
  98. /**
  99. * Base DN. For example "ou=groups,o=mycompany".
  100. */
  101. public String getBaseDn() {
  102. return baseDn;
  103. }
  104. /**
  105. * Group ID Attribute. For example "cn".
  106. */
  107. public String getIdAttribute() {
  108. return idAttribute;
  109. }
  110. /**
  111. * Request. For example:
  112. * <pre>
  113. * (&(objectClass=groupOfUniqueNames)(uniqueMember={0}))
  114. * (&(objectClass=posixGroup)(memberUid={0}))
  115. * (&(|(objectClass=groupOfUniqueNames)(objectClass=posixGroup))(|(uniqueMember={0})(memberUid={1})))
  116. * </pre>
  117. */
  118. public String getRequest() {
  119. return request;
  120. }
  121. /**
  122. * Attributes of user required for search of groups.
  123. */
  124. public String[] getRequiredUserAttributes() {
  125. return requiredUserAttributes;
  126. }
  127. @Override
  128. public String toString() {
  129. return getClass().getSimpleName() + "{" +
  130. "baseDn=" + getBaseDn() +
  131. ", idAttribute=" + getIdAttribute() +
  132. ", requiredUserAttributes=" + Arrays.toString(getRequiredUserAttributes()) +
  133. ", request=" + getRequest() +
  134. "}";
  135. }
  136. }