]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-21247 Add button to trigger the sync
authorguillaume-peoch-sonarsource <guillaume.peoch@sonarsource.com>
Mon, 18 Dec 2023 10:26:10 +0000 (11:26 +0100)
committersonartech <sonartech@sonarsource.com>
Fri, 22 Dec 2023 20:03:03 +0000 (20:03 +0000)
server/sonar-auth-bitbucket/src/main/java/org/sonar/auth/bitbucket/BitbucketSettings.java
server/sonar-auth-github/src/main/java/org/sonar/auth/github/GitHubSettings.java
server/sonar-auth-gitlab/src/main/java/org/sonar/auth/gitlab/GitLabSettings.java
server/sonar-web/src/main/js/api/gitlab-provisioning.ts
server/sonar-web/src/main/js/apps/settings/components/authentication/GitLabAuthenticationTab.tsx
server/sonar-web/src/main/js/helpers/mocks/definitions-list.ts
server/sonar-web/src/main/js/queries/group-memberships.ts
server/sonar-web/src/main/js/queries/identity-provider/gitlab.ts
server/sonar-web/src/main/js/queries/users.ts
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index 7c7ed7675b3e7759d65afe0f0ef786012495cb7b..3568e070be698b1a7b452a36d25f5bfa4c560e87 100755 (executable)
@@ -105,7 +105,7 @@ public class BitbucketSettings {
         .build(),
       PropertyDefinition.builder(ALLOW_USERS_TO_SIGN_UP)
         .name("Allow users to sign up")
-        .description("Allow new users to authenticate. When set to 'false', only existing users will be able to authenticate.")
+        .description("Allow new users to authenticate. When set to disabled, only existing users will be able to authenticate.")
         .category(CATEGORY)
         .subCategory(SUBCATEGORY)
         .type(PropertyType.BOOLEAN)
index cd7790371f6bb2e23af66149e4e8ae54afd64936..5a50ee8980d953377acbe3ce90a3a6bc9378cb03 100644 (file)
@@ -227,7 +227,7 @@ public class GitHubSettings implements DevOpsPlatformSettings {
         .build(),
       PropertyDefinition.builder(ALLOW_USERS_TO_SIGN_UP)
         .name("Allow users to sign up")
-        .description("Allow new users to authenticate. When set to 'false', only existing users will be able to authenticate to the server.")
+        .description("Allow new users to authenticate. When set to disabled, only existing users will be able to authenticate to the server.")
         .category(CATEGORY)
         .subCategory(SUBCATEGORY)
         .type(BOOLEAN)
index ff9ea68ee67b60f6c110face605b55b6a47a1032..4d92bab2290b3952af35bf541e12ee6809d3a191 100644 (file)
@@ -147,7 +147,7 @@ public class GitLabSettings implements DevOpsPlatformSettings {
         .build(),
       PropertyDefinition.builder(GITLAB_AUTH_ALLOW_USERS_TO_SIGNUP)
         .name("Allow users to sign up")
-        .description("Allow new users to authenticate. When set to 'false', only existing users will be able to authenticate to the server.")
+        .description("Allow new users to authenticate. When set to disabled, only existing users will be able to authenticate to the server.")
         .category(CATEGORY)
         .subCategory(SUBCATEGORY)
         .type(BOOLEAN)
@@ -158,7 +158,7 @@ public class GitLabSettings implements DevOpsPlatformSettings {
         .deprecatedKey("sonar.auth.gitlab.sync_user_groups")
         .name("Synchronize user groups")
         .description("For each GitLab group they belong to, the user will be associated to a group with the same name (if it exists) in SonarQube." +
-          " If enabled, the GitLab Oauth2 application will need to provide the api scope.")
+          " If enabled, the GitLab OAuth 2 application will need to provide the api scope.")
         .category(CATEGORY)
         .subCategory(SUBCATEGORY)
         .type(PropertyType.BOOLEAN)
@@ -167,7 +167,8 @@ public class GitLabSettings implements DevOpsPlatformSettings {
         .build(),
       PropertyDefinition.builder(GITLAB_AUTH_PROVISIONING_TOKEN)
         .name("Provisioning token")
-        .description("Token used for provisioning users. Both a group or a personal access token can be used as soon as it has visibility on desired groups.")
+        .description("Token used for user provisioning." +
+          " You can either use a group or a personal access token, as long as it has visibility on the groups that need to be imported.")
         .category(CATEGORY)
         .subCategory(SUBCATEGORY)
         .type(PASSWORD)
@@ -175,7 +176,8 @@ public class GitLabSettings implements DevOpsPlatformSettings {
         .build(),
       PropertyDefinition.builder(GITLAB_AUTH_PROVISIONING_GROUPS)
         .name("Groups")
-        .description("Only members of these groups (and sub-groups) will be provisioned. Please enter the group slug as it appears in GitLab URL, for instance `my-gitlab-group`.")
+        .description("Only members of these groups (and sub-groups) will be provisioned." +
+          " Please enter the group slug as it appears in the GitLab URL, for instance `my-gitlab-group`.")
         .multiValues(true)
         .category(CATEGORY)
         .subCategory(SUBCATEGORY)
index d4f3d856928ce3f4a7d694efd43819a621433132..81b3549076e66604da446e658f4e73234700d869 100644 (file)
@@ -59,3 +59,7 @@ export function updateGitLabConfiguration(
 export function deleteGitLabConfiguration(id: string): Promise<void> {
   return axios.delete(`${GITLAB_CONFIGURATIONS}/${id}`);
 }
+
+export function syncNowGitLabProvisioning(): Promise<void> {
+  return axios.post('/api/v2/dop-translation/gitlab-synchronization-runs');
+}
index 832702ddd33abeaad73677b16542826fe6ef98dd..95852b9f3258006837fe49b29db4a00b022b2ea3 100644 (file)
@@ -36,6 +36,7 @@ import { useIdentityProviderQuery } from '../../../../queries/identity-provider/
 import {
   useDeleteGitLabConfigurationMutation,
   useGitLabConfigurationsQuery,
+  useSyncWithGitLabNow,
   useUpdateGitLabConfigurationMutation,
 } from '../../../../queries/identity-provider/gitlab';
 import { AlmKeys } from '../../../../types/alm-settings';
@@ -91,6 +92,8 @@ export default function GitLabAuthenticationTab() {
   const { data: list, isLoading: isLoadingList } = useGitLabConfigurationsQuery();
   const configuration = list?.gitlabConfigurations[0];
 
+  const { canSyncNow, synchronizeNow } = useSyncWithGitLabNow();
+
   const { mutate: updateConfig, isLoading: isUpdating } = useUpdateGitLabConfigurationMutation();
   const { mutate: deleteConfig, isLoading: isDeleting } = useDeleteGitLabConfigurationMutation();
 
@@ -282,20 +285,15 @@ export default function GitLabAuthenticationTab() {
                       <FormattedMessage id="settings.authentication.gitlab.provisioning_at_login.description" />
                     </p>
                     <p className="spacer-bottom">
-                      <FormattedMessage
-                        id="settings.authentication.gitlab.description.doc"
-                        values={{
-                          documentation: (
-                            <DocLink
-                              to={`/instance-administration/authentication/${
-                                DOCUMENTATION_LINK_SUFFIXES[AlmKeys.GitLab]
-                              }/`}
-                            >
-                              {translate('documentation')}
-                            </DocLink>
-                          ),
-                        }}
-                      />
+                      <DocLink
+                        to={`/instance-administration/authentication/${
+                          DOCUMENTATION_LINK_SUFFIXES[AlmKeys.GitLab]
+                        }/#choosing-the-provisioning-method`}
+                      >
+                        {translate(
+                          `settings.authentication.gitlab.description.${ProvisioningType.jit}.learn_more`,
+                        )}
+                      </DocLink>
                     </p>
                     {provisioningType === ProvisioningType.jit &&
                       allowUsersToSignUpDefinition !== undefined && (
@@ -338,31 +336,33 @@ export default function GitLabAuthenticationTab() {
                           )}
                         </p>
                         <p className="spacer-bottom">
-                          <FormattedMessage
-                            id="settings.authentication.gitlab.description.doc"
-                            values={{
-                              documentation: (
-                                <DocLink
-                                  to={`/instance-administration/authentication/${
-                                    DOCUMENTATION_LINK_SUFFIXES[AlmKeys.GitLab]
-                                  }/`}
-                                >
-                                  {translate('documentation')}
-                                </DocLink>
-                              ),
-                            }}
-                          />
+                          <DocLink
+                            to={`/instance-administration/authentication/${
+                              DOCUMENTATION_LINK_SUFFIXES[AlmKeys.GitLab]
+                            }/#choosing-the-provisioning-method`}
+                          >
+                            {translate(
+                              `settings.authentication.gitlab.description.${ProvisioningType.auto}.learn_more`,
+                            )}
+                          </DocLink>
                         </p>
 
                         {configuration?.synchronizationType === ProvisioningType.auto && (
-                          <>
-                            <GitLabSynchronisationWarning />
-                            <hr className="spacer-top" />
-                          </>
+                          <GitLabSynchronisationWarning />
                         )}
 
                         {provisioningType === ProvisioningType.auto && (
                           <>
+                            <div className="sw-flex sw-flex-1 spacer-bottom">
+                              <Button
+                                className="spacer-top width-30"
+                                onClick={synchronizeNow}
+                                disabled={!canSyncNow}
+                              >
+                                {translate('settings.authentication.github.synchronize_now')}
+                              </Button>
+                            </div>
+                            <hr />
                             <AuthenticationFormField
                               settingValue={provisioningToken}
                               key={tokenKey}
index 05a75dff539d3377122ecefa62e1bfa1a7c64f91..9ccb10840a04209128be751bc9a50c2c28e34bb8 100644 (file)
@@ -202,7 +202,7 @@ export const definitions: ExtendedSettingDefinition[] = [
     key: 'sonar.auth.bitbucket.allowUsersToSignUp',
     name: 'Allow users to sign up',
     description:
-      "Allow new users to authenticate. When set to 'false', only existing users will be able to authenticate.",
+      'Allow new users to authenticate. When set to disabled, only existing users will be able to authenticate.',
     type: SettingType.BOOLEAN,
     category: 'authentication',
     subCategory: 'bitbucket',
@@ -214,7 +214,7 @@ export const definitions: ExtendedSettingDefinition[] = [
     key: 'sonar.auth.github.allowUsersToSignUp',
     name: 'Allow users to sign up',
     description:
-      "Allow new users to authenticate. When set to 'false', only existing users will be able to authenticate to the server.",
+      'Allow new users to authenticate. When set to disabled, only existing users will be able to authenticate to the server.',
     type: SettingType.BOOLEAN,
     category: 'authentication',
     subCategory: 'github',
@@ -246,7 +246,7 @@ export const definitions: ExtendedSettingDefinition[] = [
     key: 'sonar.auth.gitlab.allowUsersToSignUp',
     name: 'Allow users to sign up',
     description:
-      "Allow new users to authenticate. When set to 'false', only existing users will be able to authenticate to the server.",
+      'Allow new users to authenticate. When set to disabled, only existing users will be able to authenticate to the server.',
     type: SettingType.BOOLEAN,
     category: 'authentication',
     subCategory: 'gitlab',
@@ -258,7 +258,7 @@ export const definitions: ExtendedSettingDefinition[] = [
     key: 'provisioning.gitlab.token.secured',
     name: 'Provisioning token',
     description:
-      'Token used for provisioning users. Both a group or a personal access token can be used as soon as it has visibility on desired groups.',
+      'Token used for user provisioning. You can either use a group or a personal access token, as long as it has visibility on the groups that need to be imported.',
     type: SettingType.PASSWORD,
     category: 'authentication',
     subCategory: 'gitlab',
@@ -323,7 +323,7 @@ export const definitions: ExtendedSettingDefinition[] = [
     key: 'sonar.auth.gitlab.groupsSync',
     name: 'Synchronize user groups',
     description:
-      'For each GitLab group they belong to, the user will be associated to a group with the same name (if it exists) in SonarQube. If enabled, the GitLab Oauth2 application will need to provide the api scope.',
+      'For each GitLab group they belong to, the user will be associated to a group with the same name (if it exists) in SonarQube. If enabled, the GitLab OAuth 2 application will need to provide the api scope.',
     type: SettingType.BOOLEAN,
     category: 'authentication',
     subCategory: 'gitlab',
index 664a949841bcf6c09ebb13da0664e2dbea68f77c..5cdf3efcb40f575211d1d055349b65889f996ff2 100644 (file)
@@ -30,7 +30,6 @@ import { translateWithParameters } from '../helpers/l10n';
 import { getNextPageParam, getPreviousPageParam } from '../helpers/react-query';
 import { RestUserDetailed } from '../types/users';
 
-const STALE_TIME = 4 * 60 * 1000;
 const DOMAIN = 'group-memberships';
 const GROUP_SUB_DOMAIN = 'users-of-group';
 
@@ -84,7 +83,6 @@ export function useGroupMembersCountQuery(groupId: string) {
   return useQuery({
     queryKey: [DOMAIN, GROUP_SUB_DOMAIN, 'count', groupId],
     queryFn: () => getGroupMemberships({ groupId, pageSize: 0 }).then((r) => r.page.total),
-    staleTime: STALE_TIME,
   });
 }
 
index 8368d986e5ac890d01fa87184a15e6e0a9988e7b..353581ab6aa4aac9e173a878ca9269901a38036f 100644 (file)
@@ -24,9 +24,10 @@ import {
   createGitLabConfiguration,
   deleteGitLabConfiguration,
   fetchGitLabConfigurations,
+  syncNowGitLabProvisioning,
   updateGitLabConfiguration,
 } from '../../api/gitlab-provisioning';
-import { AlmSyncStatus } from '../../types/provisioning';
+import { AlmSyncStatus, ProvisioningType } from '../../types/provisioning';
 import { TaskStatuses, TaskTypes } from '../../types/tasks';
 
 export function useGitLabConfigurationsQuery() {
@@ -152,3 +153,23 @@ export function useGitLabSyncStatusQuery() {
     },
   );
 }
+
+export function useSyncWithGitLabNow() {
+  const queryClient = useQueryClient();
+  const { data: syncStatus } = useGitLabSyncStatusQuery();
+  const { data: gitlabConfigurations } = useGitLabConfigurationsQuery();
+  const autoProvisioningEnabled = gitlabConfigurations?.gitlabConfigurations.some(
+    (configuration) =>
+      configuration.enabled && configuration.synchronizationType === ProvisioningType.auto,
+  );
+  const mutation = useMutation(syncNowGitLabProvisioning, {
+    onSuccess: () => {
+      queryClient.invalidateQueries(['identity_provider', 'gitlab_sync']);
+    },
+  });
+
+  return {
+    synchronizeNow: mutation.mutate,
+    canSyncNow: autoProvisioningEnabled && !syncStatus?.nextSync && !mutation.isLoading,
+  };
+}
index 6c693e83d02e7b38674287791e73c766d066fbec..f1fe0a05ef441c10bf5606c833e8948276436124 100644 (file)
@@ -59,7 +59,6 @@ export function useUserGroupsCountQuery(login: string) {
   return useQuery({
     queryKey: ['user', login, 'groups', 'total'],
     queryFn: () => getUserGroups({ login, ps: 1 }).then((r) => r.paging.total),
-    staleTime: STALE_TIME,
   });
 }
 
index a99a9a94c1df303d88ca3b99475ad26517645e06..b5d927e23cd7ec5244078e6f79ede2a56e2f863c 100644 (file)
@@ -1498,7 +1498,7 @@ settings.authentication.title=Authentication
 settings.authentication.custom_message_information=You can define a custom log-in message to appear on the log-in page to help your users authenticate. The relevant settings are available under the {link} section.
 settings.authentication.custom_message_information.link=General
 settings.authentication.description=The following settings allow you to delegate authentication via SAML, or any of the following DevOps Platforms: GitHub, GitLab, and Bitbucket.
-settings.authentication.help=If you need help setting up authentication, read our dedicated {link}.
+settings.authentication.help=For details on how to set up authentication, check out the {link}.
 settings.authentication.legacy_help.github=Compatibility with GitHub OAuth App is deprecated and will be removed in a future release. Please check out the {link} for information on how to update your configuration.
 settings.authentication.help.link=documentation
 settings.authentication.form.create=Create configuration
@@ -1589,16 +1589,17 @@ settings.authentication.gitlab.form.url.description=URL to access GitLab.
 settings.authentication.gitlab.form.secret.name=Secret
 settings.authentication.gitlab.form.secret.description=Secret provided by GitLab when registering the application.
 settings.authentication.gitlab.form.synchronizeGroups.name=Synchronize user groups
-settings.authentication.gitlab.form.synchronizeGroups.description=For each GitLab group they belong to, the user will be associated to a group with the same name (if it exists) in SonarQube. If enabled, the GitLab Oauth2 application will need to provide the api scope.
+settings.authentication.gitlab.form.synchronizeGroups.description=For each GitLab group they belong to, the user will be associated to a group with the same name (if it exists) in SonarQube. If enabled, the GitLab OAuth 2 application will need to provide the api scope.
 settings.authentication.gitlab.form.provisioningGroups.name=Groups
-settings.authentication.gitlab.form.provisioningGroups.description=Only members of these groups (and sub-groups) will be provisioned. Please enter the group slug as it appears in GitLab URL, for instance `my-gitlab-group`.
+settings.authentication.gitlab.form.provisioningGroups.description=Only members of these groups (and sub-groups) will be provisioned. Please enter the group slug as it appears in the GitLab URL, for instance `my-gitlab-group`.
 settings.authentication.gitlab.form.allowUsersToSignUp.name=Allow users to sign up
-settings.authentication.gitlab.form.allowUsersToSignUp.description=Allow new users to authenticate. When set to 'false', only existing users will be able to authenticate to the server.
+settings.authentication.gitlab.form.allowUsersToSignUp.description=Allow new users to authenticate. When set to disabled, only existing users will be able to authenticate to the server.
 settings.authentication.gitlab.form.provisioningToken.name=Provisioning token
-settings.authentication.gitlab.form.provisioningToken.description=Token used for provisioning users. Both a group or a personal access token can be used as soon as it has visibility on desired groups.
+settings.authentication.gitlab.form.provisioningToken.description=Token used for user provisioning. You can either use a group or a personal access token, as long as it has visibility on the groups that need to be imported.
 settings.authentication.gitlab.provisioning_at_login=Just-in-Time user provisioning (default)
 settings.authentication.gitlab.provisioning_at_login.description=Users are synchronized only when users log in to SonarQube.
-settings.authentication.gitlab.description.doc=For more details, see {documentation}.
+settings.authentication.gitlab.description.JIT.learn_more=Learn more about Just-in-Time provisioning with GitLab
+settings.authentication.gitlab.description.AUTO_PROVISIONING.learn_more=Learn more about automatic provisioning with GitLab
 settings.authentication.gitlab.confirm.AUTO_PROVISIONING=Switch to automatic provisioning
 settings.authentication.gitlab.confirm.JIT=Switch to Just-in-Time provisioning
 settings.authentication.gitlab.confirm.AUTO_PROVISIONING.description=Once you transition to automatic provisioning users and groups on GitLab projects will be inherited from GitLab. You will no longer have the ability to edit them within SonarQube. Do you want to proceed with this change?