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.

UserRegistrarImplOrgMembershipSyncTest.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2020 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.server.authentication;
  21. import com.google.common.collect.ImmutableSet;
  22. import org.junit.Rule;
  23. import org.junit.Test;
  24. import org.junit.rules.ExpectedException;
  25. import org.sonar.api.config.internal.MapSettings;
  26. import org.sonar.api.impl.utils.AlwaysIncreasingSystem2;
  27. import org.sonar.api.resources.Qualifiers;
  28. import org.sonar.api.resources.ResourceTypes;
  29. import org.sonar.api.server.authentication.UserIdentity;
  30. import org.sonar.api.utils.System2;
  31. import org.sonar.db.DbTester;
  32. import org.sonar.db.alm.AlmAppInstallDto;
  33. import org.sonar.db.component.ResourceTypesRule;
  34. import org.sonar.db.organization.OrganizationDto;
  35. import org.sonar.db.user.UserDto;
  36. import org.sonar.server.authentication.UserRegistration.ExistingEmailStrategy;
  37. import org.sonar.server.authentication.event.AuthenticationEvent.Source;
  38. import org.sonar.server.es.EsTester;
  39. import org.sonar.server.organization.DefaultOrganizationProvider;
  40. import org.sonar.server.organization.MemberUpdater;
  41. import org.sonar.server.organization.OrganizationUpdater;
  42. import org.sonar.server.organization.TestDefaultOrganizationProvider;
  43. import org.sonar.server.organization.TestOrganizationFlags;
  44. import org.sonar.server.permission.PermissionService;
  45. import org.sonar.server.permission.PermissionServiceImpl;
  46. import org.sonar.server.user.NewUserNotifier;
  47. import org.sonar.server.user.UserUpdater;
  48. import org.sonar.server.user.index.UserIndexer;
  49. import org.sonar.server.usergroups.DefaultGroupFinder;
  50. import static org.mockito.Mockito.mock;
  51. import static org.sonar.db.alm.ALM.BITBUCKETCLOUD;
  52. import static org.sonar.db.alm.ALM.GITHUB;
  53. import static org.sonar.server.authentication.event.AuthenticationEvent.Method.BASIC;
  54. public class UserRegistrarImplOrgMembershipSyncTest {
  55. private System2 system2 = new AlwaysIncreasingSystem2();
  56. private static String USER_LOGIN = "github-johndoo";
  57. private static UserIdentity USER_IDENTITY = UserIdentity.builder()
  58. .setProviderId("ABCD")
  59. .setProviderLogin("johndoo")
  60. .setName("John")
  61. .setEmail("john@email.com")
  62. .build();
  63. private static TestIdentityProvider GITHUB_PROVIDER = new TestIdentityProvider()
  64. .setKey("github")
  65. .setName("Github")
  66. .setEnabled(true)
  67. .setAllowsUsersToSignUp(true);
  68. private static TestIdentityProvider BITBUCKET_PROVIDER = new TestIdentityProvider()
  69. .setKey("bitbucket")
  70. .setName("Bitbucket")
  71. .setEnabled(true)
  72. .setAllowsUsersToSignUp(true);
  73. private MapSettings settings = new MapSettings();
  74. @Rule
  75. public ExpectedException expectedException = ExpectedException.none();
  76. @Rule
  77. public DbTester db = DbTester.create(new AlwaysIncreasingSystem2());
  78. @Rule
  79. public EsTester es = EsTester.create();
  80. private UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client());
  81. private DefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
  82. private OrganizationUpdater organizationUpdater = mock(OrganizationUpdater.class);
  83. private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone();
  84. private CredentialsLocalAuthentication localAuthentication = new CredentialsLocalAuthentication(db.getDbClient());
  85. private UserUpdater userUpdater = new UserUpdater(
  86. system2,
  87. mock(NewUserNotifier.class),
  88. db.getDbClient(),
  89. userIndexer,
  90. organizationFlags,
  91. defaultOrganizationProvider,
  92. new DefaultGroupFinder(db.getDbClient()),
  93. settings.asConfig(),
  94. localAuthentication);
  95. private ResourceTypes resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT);
  96. private PermissionService permissionService = new PermissionServiceImpl(resourceTypes);
  97. private DefaultGroupFinder defaultGroupFinder = new DefaultGroupFinder(db.getDbClient());
  98. private UserRegistrarImpl underTest = new UserRegistrarImpl(db.getDbClient(), userUpdater, defaultOrganizationProvider, organizationFlags,
  99. defaultGroupFinder, new MemberUpdater(db.getDbClient(), defaultGroupFinder, userIndexer));
  100. @Test
  101. public void authenticate_new_github_user_syncs_organization() {
  102. organizationFlags.setEnabled(true);
  103. OrganizationDto organization = db.organizations().insert();
  104. db.users().insertDefaultGroup(organization, "Members");
  105. AlmAppInstallDto gitHubInstall = db.alm().insertAlmAppInstall(a -> a.setAlm(GITHUB));
  106. db.alm().insertOrganizationAlmBinding(organization, gitHubInstall, true);
  107. underTest.register(UserRegistration.builder()
  108. .setUserIdentity(USER_IDENTITY)
  109. .setProvider(GITHUB_PROVIDER)
  110. .setSource(Source.realm(BASIC, GITHUB_PROVIDER.getName()))
  111. .setExistingEmailStrategy(ExistingEmailStrategy.ALLOW)
  112. .setOrganizationAlmIds(ImmutableSet.of(gitHubInstall.getOrganizationAlmId()))
  113. .build());
  114. UserDto user = db.users().selectUserByExternalLoginAndIdentityProvider(USER_IDENTITY.getProviderLogin(), GITHUB_PROVIDER.getKey()).get();
  115. db.organizations().assertUserIsMemberOfOrganization(organization, user);
  116. }
  117. @Test
  118. public void authenticate_new_github_user_does_not_sync_organization_when_no_org_alm_ids_provided() {
  119. organizationFlags.setEnabled(true);
  120. OrganizationDto organization = db.organizations().insert();
  121. db.users().insertDefaultGroup(organization, "Members");
  122. AlmAppInstallDto gitHubInstall = db.alm().insertAlmAppInstall(a -> a.setAlm(GITHUB));
  123. db.alm().insertOrganizationAlmBinding(organization, gitHubInstall, true);
  124. underTest.register(UserRegistration.builder()
  125. .setUserIdentity(USER_IDENTITY)
  126. .setProvider(GITHUB_PROVIDER)
  127. .setSource(Source.realm(BASIC, GITHUB_PROVIDER.getName()))
  128. .setExistingEmailStrategy(ExistingEmailStrategy.ALLOW)
  129. .setOrganizationAlmIds(null)
  130. .build());
  131. UserDto user = db.users().selectUserByExternalLoginAndIdentityProvider(USER_IDENTITY.getProviderLogin(), GITHUB_PROVIDER.getKey()).get();
  132. db.organizations().assertUserIsNotMemberOfOrganization(organization, user);
  133. }
  134. @Test
  135. public void authenticate_new_bitbucket_user_does_not_sync_organization() {
  136. organizationFlags.setEnabled(true);
  137. OrganizationDto organization = db.organizations().insert();
  138. db.users().insertDefaultGroup(organization, "Members");
  139. AlmAppInstallDto gitHubInstall = db.alm().insertAlmAppInstall(a -> a.setAlm(BITBUCKETCLOUD));
  140. db.alm().insertOrganizationAlmBinding(organization, gitHubInstall, true);
  141. underTest.register(UserRegistration.builder()
  142. .setUserIdentity(USER_IDENTITY)
  143. .setProvider(BITBUCKET_PROVIDER)
  144. .setSource(Source.realm(BASIC, BITBUCKET_PROVIDER.getName()))
  145. .setExistingEmailStrategy(ExistingEmailStrategy.ALLOW)
  146. .setOrganizationAlmIds(ImmutableSet.of(gitHubInstall.getOrganizationAlmId()))
  147. .build());
  148. UserDto user = db.users().selectUserByExternalLoginAndIdentityProvider(USER_IDENTITY.getProviderLogin(), BITBUCKET_PROVIDER.getKey()).get();
  149. db.organizations().assertUserIsNotMemberOfOrganization(organization, user);
  150. }
  151. @Test
  152. public void authenticate_new_user_using_unknown_alm_does_not_sync_organization() {
  153. organizationFlags.setEnabled(true);
  154. OrganizationDto organization = db.organizations().insert();
  155. db.users().insertDefaultGroup(organization, "Members");
  156. AlmAppInstallDto almAppInstall = db.alm().insertAlmAppInstall(a -> a.setAlm(GITHUB));
  157. db.alm().insertOrganizationAlmBinding(organization, almAppInstall, true);
  158. TestIdentityProvider identityProvider = new TestIdentityProvider()
  159. .setKey("unknown")
  160. .setName("unknown")
  161. .setEnabled(true)
  162. .setAllowsUsersToSignUp(true);
  163. underTest.register(UserRegistration.builder()
  164. .setUserIdentity(USER_IDENTITY)
  165. .setProvider(identityProvider)
  166. .setSource(Source.realm(BASIC, identityProvider.getName()))
  167. .setExistingEmailStrategy(ExistingEmailStrategy.ALLOW)
  168. .setOrganizationAlmIds(ImmutableSet.of(almAppInstall.getOrganizationAlmId()))
  169. .build());
  170. UserDto user = db.users().selectUserByExternalLoginAndIdentityProvider(USER_IDENTITY.getProviderLogin(), identityProvider.getKey()).get();
  171. db.organizations().assertUserIsNotMemberOfOrganization(organization, user);
  172. }
  173. @Test
  174. public void authenticate_existing_github_user_does_not_sync_organization() {
  175. organizationFlags.setEnabled(true);
  176. OrganizationDto organization = db.organizations().insert();
  177. db.users().insertDefaultGroup(organization, "Members");
  178. AlmAppInstallDto gitHubInstall = db.alm().insertAlmAppInstall(a -> a.setAlm(GITHUB));
  179. db.alm().insertOrganizationAlmBinding(organization, gitHubInstall, true);
  180. UserDto user = db.users().insertUser(u -> u
  181. .setLogin("Old login")
  182. .setExternalId(USER_IDENTITY.getProviderId())
  183. .setExternalIdentityProvider(GITHUB_PROVIDER.getKey()));
  184. underTest.register(UserRegistration.builder()
  185. .setUserIdentity(USER_IDENTITY)
  186. .setProvider(GITHUB_PROVIDER)
  187. .setSource(Source.local(BASIC))
  188. .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
  189. .setOrganizationAlmIds(ImmutableSet.of(gitHubInstall.getOrganizationAlmId()))
  190. .build());
  191. db.organizations().assertUserIsNotMemberOfOrganization(organization, user);
  192. }
  193. @Test
  194. public void authenticate_disabled_github_user_syncs_organization() {
  195. organizationFlags.setEnabled(true);
  196. OrganizationDto organization = db.organizations().insert();
  197. db.users().insertDefaultGroup(organization, "Members");
  198. AlmAppInstallDto gitHubInstall = db.alm().insertAlmAppInstall(a -> a.setAlm(GITHUB));
  199. db.alm().insertOrganizationAlmBinding(organization, gitHubInstall, true);
  200. UserDto user = db.users().insertDisabledUser(u -> u
  201. .setLogin(USER_LOGIN)
  202. .setExternalId(USER_IDENTITY.getProviderId())
  203. .setExternalIdentityProvider(GITHUB_PROVIDER.getKey())
  204. );
  205. underTest.register(UserRegistration.builder()
  206. .setUserIdentity(USER_IDENTITY)
  207. .setProvider(GITHUB_PROVIDER)
  208. .setSource(Source.local(BASIC))
  209. .setExistingEmailStrategy(ExistingEmailStrategy.FORBID)
  210. .setOrganizationAlmIds(ImmutableSet.of(gitHubInstall.getOrganizationAlmId()))
  211. .build());
  212. db.organizations().assertUserIsMemberOfOrganization(organization, user);
  213. }
  214. }