Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-02-09 00:11:09 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-02-09 00:11:09 +0300
commit3d42e098d9658853984534c9dfc2bf76284a8ac0 (patch)
tree269e9d9e017124f5f6d841311661832ea7e4eff8 /app/assets/javascripts/token_access
parenta3487798aeff89daff78749e6d6f392d3ca23687 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/token_access')
-rw-r--r--app/assets/javascripts/token_access/components/inbound_token_access.vue258
-rw-r--r--app/assets/javascripts/token_access/components/outbound_token_access.vue (renamed from app/assets/javascripts/token_access/components/token_access.vue)30
-rw-r--r--app/assets/javascripts/token_access/components/token_access_app.vue27
-rw-r--r--app/assets/javascripts/token_access/components/token_projects_table.vue29
-rw-r--r--app/assets/javascripts/token_access/graphql/mutations/inbound_add_project_ci_job_token_scope.mutation.graphql7
-rw-r--r--app/assets/javascripts/token_access/graphql/mutations/inbound_remove_project_ci_job_token_scope.mutation.graphql7
-rw-r--r--app/assets/javascripts/token_access/graphql/mutations/inbound_update_ci_job_token_scope.mutation.graphql8
-rw-r--r--app/assets/javascripts/token_access/graphql/queries/inbound_get_ci_job_token_scope.query.graphql8
-rw-r--r--app/assets/javascripts/token_access/graphql/queries/inbound_get_projects_with_ci_job_token_scope.query.graphql18
-rw-r--r--app/assets/javascripts/token_access/index.js4
10 files changed, 367 insertions, 29 deletions
diff --git a/app/assets/javascripts/token_access/components/inbound_token_access.vue b/app/assets/javascripts/token_access/components/inbound_token_access.vue
new file mode 100644
index 00000000000..1a225550c95
--- /dev/null
+++ b/app/assets/javascripts/token_access/components/inbound_token_access.vue
@@ -0,0 +1,258 @@
+<script>
+import {
+ GlAlert,
+ GlButton,
+ GlCard,
+ GlFormInput,
+ GlLink,
+ GlLoadingIcon,
+ GlSprintf,
+ GlToggle,
+} from '@gitlab/ui';
+import { createAlert } from '~/flash';
+import { __, s__ } from '~/locale';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import inboundAddProjectCIJobTokenScopeMutation from '../graphql/mutations/inbound_add_project_ci_job_token_scope.mutation.graphql';
+import inboundRemoveProjectCIJobTokenScopeMutation from '../graphql/mutations/inbound_remove_project_ci_job_token_scope.mutation.graphql';
+import inboundUpdateCIJobTokenScopeMutation from '../graphql/mutations/inbound_update_ci_job_token_scope.mutation.graphql';
+import inboundGetCIJobTokenScopeQuery from '../graphql/queries/inbound_get_ci_job_token_scope.query.graphql';
+import inboundGetProjectsWithCIJobTokenScopeQuery from '../graphql/queries/inbound_get_projects_with_ci_job_token_scope.query.graphql';
+import TokenProjectsTable from './token_projects_table.vue';
+
+export default {
+ i18n: {
+ toggleLabelTitle: s__('CICD|Allow access to this project with a CI_JOB_TOKEN'),
+ toggleHelpText: s__(
+ `CICD|Manage which projects can use their CI_JOB_TOKEN to access this project. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API. %{linkStart}Learn more.%{linkEnd}`,
+ ),
+ cardHeaderTitle: s__(
+ 'CICD|Allow CI job tokens from the following projects to access this project',
+ ),
+ settingDisabledMessage: s__(
+ 'CICD|Enable feature to allow job token access by the following projects.',
+ ),
+ addProject: __('Add project'),
+ cancel: __('Cancel'),
+ addProjectPlaceholder: __('Paste project path (i.e. gitlab-org/gitlab)'),
+ projectsFetchError: __('There was a problem fetching the projects'),
+ scopeFetchError: __('There was a problem fetching the job token scope value'),
+ },
+ fields: [
+ {
+ key: 'project',
+ label: __('Project with access'),
+ thClass: 'gl-border-t-none!',
+ columnClass: 'gl-w-40p',
+ },
+ {
+ key: 'namespace',
+ label: __('Namespace'),
+ thClass: 'gl-border-t-none!',
+ columnClass: 'gl-w-40p',
+ },
+ {
+ key: 'actions',
+ label: '',
+ tdClass: 'gl-text-right',
+ thClass: 'gl-border-t-none!',
+ columnClass: 'gl-w-10p',
+ },
+ ],
+ components: {
+ GlAlert,
+ GlButton,
+ GlCard,
+ GlFormInput,
+ GlLink,
+ GlLoadingIcon,
+ GlSprintf,
+ GlToggle,
+ TokenProjectsTable,
+ },
+ inject: {
+ fullPath: {
+ default: '',
+ },
+ },
+ apollo: {
+ inboundJobTokenScopeEnabled: {
+ query: inboundGetCIJobTokenScopeQuery,
+ variables() {
+ return {
+ fullPath: this.fullPath,
+ };
+ },
+ update({ project }) {
+ return project.ciCdSettings.inboundJobTokenScopeEnabled;
+ },
+ error() {
+ createAlert({ message: this.$options.i18n.scopeFetchError });
+ },
+ },
+ projects: {
+ query: inboundGetProjectsWithCIJobTokenScopeQuery,
+ variables() {
+ return {
+ fullPath: this.fullPath,
+ };
+ },
+ update({ project }) {
+ return project?.ciJobTokenScope?.inboundAllowlist?.nodes ?? [];
+ },
+ error() {
+ createAlert({ message: this.$options.i18n.projectsFetchError });
+ },
+ },
+ },
+ data() {
+ return {
+ inboundJobTokenScopeEnabled: null,
+ targetProjectPath: '',
+ projects: [],
+ };
+ },
+ computed: {
+ isProjectPathEmpty() {
+ return this.targetProjectPath === '';
+ },
+ ciJobTokenHelpPage() {
+ return helpPagePath('ci/jobs/ci_job_token');
+ },
+ },
+ methods: {
+ async updateCIJobTokenScope() {
+ try {
+ const {
+ data: {
+ ciCdSettingsUpdate: { errors },
+ },
+ } = await this.$apollo.mutate({
+ mutation: inboundUpdateCIJobTokenScopeMutation,
+ variables: {
+ input: {
+ fullPath: this.fullPath,
+ inboundJobTokenScopeEnabled: this.inboundJobTokenScopeEnabled,
+ },
+ },
+ });
+
+ if (errors.length) {
+ throw new Error(errors[0]);
+ }
+ } catch (error) {
+ this.inboundJobTokenScopeEnabled = !this.inboundJobTokenScopeEnabled;
+ createAlert({ message: error.message });
+ }
+ },
+ async addProject() {
+ try {
+ const {
+ data: {
+ ciJobTokenScopeAddProject: { errors },
+ },
+ } = await this.$apollo.mutate({
+ mutation: inboundAddProjectCIJobTokenScopeMutation,
+ variables: {
+ projectPath: this.fullPath,
+ targetProjectPath: this.targetProjectPath,
+ },
+ });
+
+ if (errors.length) {
+ throw new Error(errors[0]);
+ }
+ } catch (error) {
+ createAlert({ message: error.message });
+ } finally {
+ this.clearTargetProjectPath();
+ this.getProjects();
+ }
+ },
+ async removeProject(removeTargetPath) {
+ try {
+ const {
+ data: {
+ ciJobTokenScopeRemoveProject: { errors },
+ },
+ } = await this.$apollo.mutate({
+ mutation: inboundRemoveProjectCIJobTokenScopeMutation,
+ variables: {
+ projectPath: this.fullPath,
+ targetProjectPath: removeTargetPath,
+ },
+ });
+
+ if (errors.length) {
+ throw new Error(errors[0]);
+ }
+ } catch (error) {
+ createAlert({ message: error.message });
+ } finally {
+ this.getProjects();
+ }
+ },
+ clearTargetProjectPath() {
+ this.targetProjectPath = '';
+ },
+ getProjects() {
+ this.$apollo.queries.projects.refetch();
+ },
+ },
+};
+</script>
+<template>
+ <div>
+ <gl-loading-icon v-if="$apollo.loading" size="lg" class="gl-mt-5" />
+ <template v-else>
+ <gl-toggle
+ v-model="inboundJobTokenScopeEnabled"
+ :label="$options.i18n.toggleLabelTitle"
+ @change="updateCIJobTokenScope"
+ >
+ <template #help>
+ <gl-sprintf :message="$options.i18n.toggleHelpText">
+ <template #link="{ content }">
+ <gl-link :href="ciJobTokenHelpPage" class="inline-link" target="_blank">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </template>
+ </gl-toggle>
+
+ <div>
+ <gl-card class="gl-mt-5 gl-mb-3">
+ <template #header>
+ <h5 class="gl-my-0">{{ $options.i18n.cardHeaderTitle }}</h5>
+ </template>
+ <template #default>
+ <gl-form-input
+ v-model="targetProjectPath"
+ :placeholder="$options.i18n.addProjectPlaceholder"
+ />
+ </template>
+ <template #footer>
+ <gl-button variant="confirm" :disabled="isProjectPathEmpty" @click="addProject">
+ {{ $options.i18n.addProject }}
+ </gl-button>
+ <gl-button @click="clearTargetProjectPath">{{ $options.i18n.cancel }}</gl-button>
+ </template>
+ </gl-card>
+ <gl-alert
+ v-if="!inboundJobTokenScopeEnabled"
+ class="gl-mb-3"
+ variant="warning"
+ :dismissible="false"
+ :show-icon="false"
+ >
+ {{ $options.i18n.settingDisabledMessage }}
+ </gl-alert>
+ <token-projects-table
+ :projects="projects"
+ :table-fields="$options.fields"
+ @removeProject="removeProject"
+ />
+ </div>
+ </template>
+ </div>
+</template>
diff --git a/app/assets/javascripts/token_access/components/token_access.vue b/app/assets/javascripts/token_access/components/outbound_token_access.vue
index 527f01f0a6f..47ec0910a7b 100644
--- a/app/assets/javascripts/token_access/components/token_access.vue
+++ b/app/assets/javascripts/token_access/components/outbound_token_access.vue
@@ -17,7 +17,6 @@ import removeProjectCIJobTokenScopeMutation from '../graphql/mutations/remove_pr
import updateCIJobTokenScopeMutation from '../graphql/mutations/update_ci_job_token_scope.mutation.graphql';
import getCIJobTokenScopeQuery from '../graphql/queries/get_ci_job_token_scope.query.graphql';
import getProjectsWithCIJobTokenScopeQuery from '../graphql/queries/get_projects_with_ci_job_token_scope.query.graphql';
-import OptInJwt from './opt_in_jwt.vue';
import TokenProjectsTable from './token_projects_table.vue';
export default {
@@ -36,6 +35,27 @@ export default {
projectsFetchError: __('There was a problem fetching the projects'),
scopeFetchError: __('There was a problem fetching the job token scope value'),
},
+ fields: [
+ {
+ key: 'project',
+ label: __('Project that can be accessed'),
+ thClass: 'gl-border-t-none!',
+ columnClass: 'gl-w-40p',
+ },
+ {
+ key: 'namespace',
+ label: __('Namespace'),
+ thClass: 'gl-border-t-none!',
+ columnClass: 'gl-w-40p',
+ },
+ {
+ key: 'actions',
+ label: '',
+ tdClass: 'gl-text-right',
+ thClass: 'gl-border-t-none!',
+ columnClass: 'gl-w-10p',
+ },
+ ],
components: {
GlAlert,
GlButton,
@@ -45,7 +65,6 @@ export default {
GlLoadingIcon,
GlSprintf,
GlToggle,
- OptInJwt,
TokenProjectsTable,
},
inject: {
@@ -230,9 +249,12 @@ export default {
>
{{ $options.i18n.settingDisabledMessage }}
</gl-alert>
- <token-projects-table :projects="projects" @removeProject="removeProject" />
+ <token-projects-table
+ :projects="projects"
+ :table-fields="$options.fields"
+ @removeProject="removeProject"
+ />
</div>
- <opt-in-jwt />
</template>
</div>
</template>
diff --git a/app/assets/javascripts/token_access/components/token_access_app.vue b/app/assets/javascripts/token_access/components/token_access_app.vue
new file mode 100644
index 00000000000..410a6267dc8
--- /dev/null
+++ b/app/assets/javascripts/token_access/components/token_access_app.vue
@@ -0,0 +1,27 @@
+<script>
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import OutboundTokenAccess from './outbound_token_access.vue';
+import InboundTokenAccess from './inbound_token_access.vue';
+import OptInJwt from './opt_in_jwt.vue';
+
+export default {
+ components: {
+ OutboundTokenAccess,
+ InboundTokenAccess,
+ OptInJwt,
+ },
+ mixins: [glFeatureFlagMixin()],
+ computed: {
+ inboundTokenAccessEnabled() {
+ return this.glFeatures.ciInboundJobTokenScope;
+ },
+ },
+};
+</script>
+<template>
+ <div>
+ <outbound-token-access />
+ <inbound-token-access v-if="inboundTokenAccessEnabled" class="gl-pt-5" />
+ <opt-in-jwt />
+ </div>
+</template>
diff --git a/app/assets/javascripts/token_access/components/token_projects_table.vue b/app/assets/javascripts/token_access/components/token_projects_table.vue
index ce33478cbee..c00dd882895 100644
--- a/app/assets/javascripts/token_access/components/token_projects_table.vue
+++ b/app/assets/javascripts/token_access/components/token_projects_table.vue
@@ -1,32 +1,11 @@
<script>
import { GlButton, GlTable } from '@gitlab/ui';
-import { __, s__ } from '~/locale';
+import { s__ } from '~/locale';
export default {
i18n: {
emptyText: s__('CI/CD|No projects have been added to the scope'),
},
- fields: [
- {
- key: 'project',
- label: __('Projects that can be accessed'),
- thClass: 'gl-border-t-none!',
- columnClass: 'gl-w-40p',
- },
- {
- key: 'namespace',
- label: __('Namespace'),
- thClass: 'gl-border-t-none!',
- columnClass: 'gl-w-40p',
- },
- {
- key: 'actions',
- label: '',
- tdClass: 'gl-text-right',
- thClass: 'gl-border-t-none!',
- columnClass: 'gl-w-10p',
- },
- ],
components: {
GlButton,
GlTable,
@@ -41,6 +20,10 @@ export default {
type: Array,
required: true,
},
+ tableFields: {
+ type: Array,
+ required: true,
+ },
},
methods: {
removeProject(project) {
@@ -52,7 +35,7 @@ export default {
<template>
<gl-table
:items="projects"
- :fields="$options.fields"
+ :fields="tableFields"
:tbody-tr-attr="{ 'data-testid': 'projects-token-table-row' }"
:empty-text="$options.i18n.emptyText"
show-empty
diff --git a/app/assets/javascripts/token_access/graphql/mutations/inbound_add_project_ci_job_token_scope.mutation.graphql b/app/assets/javascripts/token_access/graphql/mutations/inbound_add_project_ci_job_token_scope.mutation.graphql
new file mode 100644
index 00000000000..f030a892af2
--- /dev/null
+++ b/app/assets/javascripts/token_access/graphql/mutations/inbound_add_project_ci_job_token_scope.mutation.graphql
@@ -0,0 +1,7 @@
+mutation inboundAddProjectCIJobTokenScope($projectPath: ID!, $targetProjectPath: ID!) {
+ ciJobTokenScopeAddProject(
+ input: { projectPath: $projectPath, targetProjectPath: $targetProjectPath, direction: INBOUND }
+ ) {
+ errors
+ }
+}
diff --git a/app/assets/javascripts/token_access/graphql/mutations/inbound_remove_project_ci_job_token_scope.mutation.graphql b/app/assets/javascripts/token_access/graphql/mutations/inbound_remove_project_ci_job_token_scope.mutation.graphql
new file mode 100644
index 00000000000..cc6736bb80d
--- /dev/null
+++ b/app/assets/javascripts/token_access/graphql/mutations/inbound_remove_project_ci_job_token_scope.mutation.graphql
@@ -0,0 +1,7 @@
+mutation inboundRemoveProjectCIJobTokenScope($projectPath: ID!, $targetProjectPath: ID!) {
+ ciJobTokenScopeRemoveProject(
+ input: { projectPath: $projectPath, targetProjectPath: $targetProjectPath, direction: INBOUND }
+ ) {
+ errors
+ }
+}
diff --git a/app/assets/javascripts/token_access/graphql/mutations/inbound_update_ci_job_token_scope.mutation.graphql b/app/assets/javascripts/token_access/graphql/mutations/inbound_update_ci_job_token_scope.mutation.graphql
new file mode 100644
index 00000000000..aac9feab237
--- /dev/null
+++ b/app/assets/javascripts/token_access/graphql/mutations/inbound_update_ci_job_token_scope.mutation.graphql
@@ -0,0 +1,8 @@
+mutation inboundUpdateCIJobTokenScope($input: CiCdSettingsUpdateInput!) {
+ ciCdSettingsUpdate(input: $input) {
+ ciCdSettings {
+ inboundJobTokenScopeEnabled
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/token_access/graphql/queries/inbound_get_ci_job_token_scope.query.graphql b/app/assets/javascripts/token_access/graphql/queries/inbound_get_ci_job_token_scope.query.graphql
new file mode 100644
index 00000000000..68d506a6c41
--- /dev/null
+++ b/app/assets/javascripts/token_access/graphql/queries/inbound_get_ci_job_token_scope.query.graphql
@@ -0,0 +1,8 @@
+query inboundGetCIJobTokenScope($fullPath: ID!) {
+ project(fullPath: $fullPath) {
+ id
+ ciCdSettings {
+ inboundJobTokenScopeEnabled
+ }
+ }
+}
diff --git a/app/assets/javascripts/token_access/graphql/queries/inbound_get_projects_with_ci_job_token_scope.query.graphql b/app/assets/javascripts/token_access/graphql/queries/inbound_get_projects_with_ci_job_token_scope.query.graphql
new file mode 100644
index 00000000000..c51bdcbf7d2
--- /dev/null
+++ b/app/assets/javascripts/token_access/graphql/queries/inbound_get_projects_with_ci_job_token_scope.query.graphql
@@ -0,0 +1,18 @@
+query inboundGetProjectsWithCIJobTokenScope($fullPath: ID!) {
+ project(fullPath: $fullPath) {
+ id
+ ciJobTokenScope {
+ inboundAllowlist {
+ nodes {
+ id
+ name
+ namespace {
+ id
+ fullPath
+ }
+ fullPath
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/token_access/index.js b/app/assets/javascripts/token_access/index.js
index 6a29883290a..0253abe393e 100644
--- a/app/assets/javascripts/token_access/index.js
+++ b/app/assets/javascripts/token_access/index.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
-import TokenAccess from './components/token_access.vue';
+import TokenAccessApp from './components/token_access_app.vue';
Vue.use(VueApollo);
@@ -25,7 +25,7 @@ export const initTokenAccess = (containerId = 'js-ci-token-access-app') => {
fullPath,
},
render(createElement) {
- return createElement(TokenAccess);
+ return createElement(TokenAccessApp);
},
});
};