Skip to content

Commit

Permalink
feat(iam): add permissions groups support in iam policy (#10447)
Browse files Browse the repository at this point in the history
ref: MANAGER-12308

Signed-off-by: Bruno MARQUES <[email protected]>
  • Loading branch information
BrunoMarquesOVH authored Dec 1, 2023
1 parent 649bd0b commit 3e2fb10
Show file tree
Hide file tree
Showing 18 changed files with 136 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default {
tagPrefix: '<',
trackClick: '<',
trackPage: '<',
permissionsGroups: '<',
},
require: {
requiredNgModel: '^ngModel',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
CUSTOM_ACTION_SAMPLE,
CUSTOM_ACTION_WILDCARD_PATTERN,
CUSTOM_RESOURCE_TYPE,
OVH_MANAGED_PERMISSIONS_GROUP,
TAG,
WILDCARD,
} from '../../iam.constants';
Expand Down Expand Up @@ -55,6 +56,12 @@ export default class ActionSelectController {
*/
this.form = null;

/**
* The NgFormController created by the template by using name="$ctrl.formManaged"
* @type {NgFormController}
*/
this.formManaged = null;

/**
* Whether the controller is loading
* @type {boolean}
Expand Down Expand Up @@ -134,6 +141,17 @@ export default class ActionSelectController {

$onInit() {
this.isLoading = true;
this.permissionsGroupsList = this.permissionsGroups
.filter(({ urn }) => urn.indexOf(OVH_MANAGED_PERMISSIONS_GROUP) > -1)
.map((permission) => {
return {
...permission,
selected:
this.ngModel?.permissionsGroups?.findIndex(
(subPermission) => subPermission.urn === permission.urn,
) > -1,
};
});
return this.IAMService.getActions()
.then((actions) => {
this.actions = cloneDeep(actions);
Expand Down Expand Up @@ -192,7 +210,7 @@ export default class ActionSelectController {
return;
}

const selectedActions = this.ngModel?.selection || [];
const selectedActions = this.ngModel?.actions?.selection || [];

this.actionTrees = ActionTrees.create({
$scope: this.$scope,
Expand All @@ -215,7 +233,8 @@ export default class ActionSelectController {
// Custom required validator for the whole component
name.$validators.required = () =>
this.required
? this.ngModel?.selection.length > 0 || this.ngModel?.isWildcardActive
? this.ngModel?.actions?.selection.length > 0 ||
this.ngModel?.actions?.isWildcardActive
: true;

// Custom "requirements" validator to know if a custom action meets all the requirements
Expand Down Expand Up @@ -285,10 +304,10 @@ export default class ActionSelectController {
embedded,
}),
);
this.requiredNgModel.$setViewValue({
this.ngModel.actions = {
isWildcardActive: this.isWildcardActive,
selection: mappedSelection,
});
};
// if a custom action with wilcard exits(ie. resource:urn/*)
// all embedded actions have to be updated
if (
Expand All @@ -307,6 +326,20 @@ export default class ActionSelectController {
});
}

onPermissionsGroupsChanged(permissionGroupId) {
if (!this.ngModel.permissionsGroups) {
this.ngModel.permissionsGroups = [];
}
const permissionsGroupsIndex = this.ngModel?.permissionsGroups?.findIndex(
(permission) => permission.urn === permissionGroupId,
);
if (permissionsGroupsIndex === -1) {
this.ngModel.permissionsGroups.push({ urn: permissionGroupId });
} else {
this.ngModel.permissionsGroups.splice(permissionsGroupsIndex, 1);
}
}

/**
* Toggle a limited set of actions
* @param {Action[]} actions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,36 @@
<span data-ng-bind-html="$ctrl.customActionSuccessMessage"></span>
</oui-message>

<!-- <MANAGED PERMISSIONS> -->
<oui-collapsible
data-heading="{{ :: 'iam_managed_permissions_heading' | translate }}"
data-expanded="true"
>
<div
class="oui-checkbox ml-4"
data-ng-repeat="group in $ctrl.permissionsGroupsList track by group.id"
>
<input
class="oui-checkbox__input"
id="{{ ::group.id }}"
type="checkbox"
name="{{ ::group.id }}"
data-ng-model="group.selected"
data-ng-change="$ctrl.onPermissionsGroupsChanged(group.urn)"
/>
<label class="oui-checkbox__label-container" for="{{ ::group.id }}">
<span class="oui-checkbox__label">
<span class="oui-checkbox__icon"></span>
<span class="oui-checkbox__text">
<span data-ng-bind="group.name"></span>
</span>
</span>
<div class="ml-4" data-ng-bind-html="::group.description"></div>
</label>
</div>
</oui-collapsible>
<!-- </MANAGED PERMISSIONS> -->

<!-- <Actions> -->
<oui-collapsible
data-ng-repeat="actionTree in $ctrl.actionTrees track by actionTree.value"
Expand All @@ -42,7 +72,7 @@
<input
type="hidden"
name="{{ $ctrl.name }}"
data-ng-model="$ctrl.ngModel"
data-ng-model="$ctrl.ngModel.actions"
data-disabled="$ctrl.readOnly"
/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@
"iam_action_select_custom_action_success_selected": "Die Aktion {{ action }} wurde in {{ resourceType }} ausgewählt",
"iam_action_select_custom_action_success_wildcard": "„Alle Aktionen zulassen“ wurde aktiviert",
"iam_action_select_error_required": "Sie müssen mindestens eine Aktion auswählen, alle Aktionen zulassen oder eine Aktion manuell hinzufügen",
"iam_action_select_custom_action_placeholder": "Beispiel: {{ sample }}"
"iam_action_select_custom_action_placeholder": "Beispiel: {{ sample }}",
"iam_managed_permissions_heading": "Gruppen verwalteter Berechtigungen",
"iam_managed_permissions_description": "Eine von OVHcloud verwaltete Richtlinie hinzufügen",
"iam_managed_permissions_description_sub": "(vollständige Beschreibung in der Dokumentation)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@
"iam_action_select_custom_action_success_selected": "The action {{ action }} has been selected in {{ resourceType }}",
"iam_action_select_custom_action_success_wildcard": "“Authorise all actions” has been enabled",
"iam_action_select_error_required": "You must select at least one action, authorise all actions, or add an action manually",
"iam_action_select_custom_action_placeholder": "Example: {{ sample }}"
"iam_action_select_custom_action_placeholder": "Example: {{ sample }}",
"iam_managed_permissions_heading": "Managed permission groups",
"iam_managed_permissions_description": "Add an OVHcloud-managed policy",
"iam_managed_permissions_description_sub": "(full description in documentation)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@
"iam_action_select_custom_action_success_selected": "Se ha seleccionado la acción {{ action }} en {{ resourceType }}",
"iam_action_select_custom_action_success_wildcard": "Se ha habilitado «Permitir todas las acciones»",
"iam_action_select_error_required": "Debe seleccionar al menos una acción, permitir todas las acciones o agregar una acción manualmente",
"iam_action_select_custom_action_placeholder": "Ejemplo: {{ sample }}"
"iam_action_select_custom_action_placeholder": "Ejemplo: {{ sample }}",
"iam_managed_permissions_heading": "Grupos de permisos gestionados",
"iam_managed_permissions_description": "Añadir una política gestionada por OVHcloud",
"iam_managed_permissions_description_sub": "(descripción completa en la documentación)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@
"iam_action_select_custom_action_success_created": "L'action {{ action }} a été ajoutée à {{ resourceType }}",
"iam_action_select_custom_action_success_selected": "L'action {{ action }} a été sélectionnée dans {{ resourceType }}",
"iam_action_select_custom_action_success_wildcard": "« Autoriser toutes les actions » a été activé",
"iam_action_select_error_required": "Vous devez sélectionner au moins une action, autoriser toutes les actions, ou ajouter une action manuellement"
"iam_action_select_error_required": "Vous devez sélectionner au moins une action, autoriser toutes les actions, ou ajouter une action manuellement",
"iam_managed_permissions_heading": "Groupes de permissions managées",
"iam_managed_permissions_description": "Ajouter une politique managée par OVHCloud",
"iam_managed_permissions_description_sub": "(description complète dans la documentation)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@
"iam_action_select_custom_action_success_created": "L'action {{ action }} a été ajoutée à {{ resourceType }}",
"iam_action_select_custom_action_success_selected": "L'action {{ action }} a été sélectionnée dans {{ resourceType }}",
"iam_action_select_custom_action_success_wildcard": "« Autoriser toutes les actions » a été activé",
"iam_action_select_error_required": "Vous devez sélectionner au moins une action, autoriser toutes les actions, ou ajouter une action manuellement"
"iam_action_select_error_required": "Vous devez sélectionner au moins une action, autoriser toutes les actions, ou ajouter une action manuellement",
"iam_managed_permissions_heading": "Groupes de permissions managées",
"iam_managed_permissions_description": "Ajouter une politique managée par OVHCloud",
"iam_managed_permissions_description_sub": "(description complète dans la documentation)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@
"iam_action_select_custom_action_success_selected": "L'azione {{ action }} è stata selezionata in {{ resourceType }}",
"iam_action_select_custom_action_success_wildcard": "\"Autorizza tutte le azioni\" è stato attivato",
"iam_action_select_error_required": "È necessario selezionare almeno un'azione, autorizzare tutte le azioni o aggiungere un'azione manualmente",
"iam_action_select_custom_action_placeholder": "Esempio: {{ sample }}"
"iam_action_select_custom_action_placeholder": "Esempio: {{ sample }}",
"iam_managed_permissions_heading": "Gruppi di permessi gestiti",
"iam_managed_permissions_description": "Aggiungere una politica gestita da OVHcloud",
"iam_managed_permissions_description_sub": "(descrizione completa nella documentazione)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@
"iam_action_select_custom_action_success_selected": "Operacja {{ action }} została wybrana dla {{ resourceType }}",
"iam_action_select_custom_action_success_wildcard": "\"Zezwalaj na wszystkie operacje\" zostało włączone.",
"iam_action_select_error_required": "Wybierz przynajmniej jedną operację, zatwierdź wszystkie operacje, lub dodaj operację ręcznie.",
"iam_action_select_custom_action_placeholder": "Przykład: {{sample}}"
"iam_action_select_custom_action_placeholder": "Przykład: {{sample}}",
"iam_managed_permissions_heading": "Zarządzane grupy uprawnień",
"iam_managed_permissions_description": "Dodaj politykę zarządzaną przez OVHcloud",
"iam_managed_permissions_description_sub": "(pełny opis w dokumentacji)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,8 @@
"iam_action_select_custom_action_success_selected": "A ação {{ action }} foi selecionada em {{ resourceType }}",
"iam_action_select_custom_action_success_wildcard": "A opção « Autorizar todas as ações » foi ativada",
"iam_action_select_error_required": "Deve selecionar pelo menos uma ação, autorizar todas as ações ou adicionar uma ação manualmente",
"iam_action_select_custom_action_placeholder": "Exemplo: {{ sample }}"
"iam_action_select_custom_action_placeholder": "Exemplo: {{ sample }}",
"iam_managed_permissions_heading": "Grupos de permissões administradas",
"iam_managed_permissions_description": "Adicionar uma política gerida pela OVHcloud",
"iam_managed_permissions_description_sub": "(descrição completa na documentação)"
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default {
policy: '<',
trackClick: '<',
trackPage: '<',
permissionsGroups: '<',
},
controller,
template,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ export default class CreatePolicyController {
(resourceType, index, list) =>
Boolean(resourceType) && list.indexOf(resourceType) === index,
);
this.model.permissionsGroups = this.policy.permissionsGroups.map(
({ urn }) => ({ urn }),
);
}
}

Expand Down Expand Up @@ -409,6 +412,7 @@ export default class CreatePolicyController {
list.findIndex(({ action }) => item.action === action) === i,
),
},
permissionsGroups: this.model.permissionsGroups,
resources: [
...new Map(
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,13 @@ <h4 data-translate="iam_create_policy_form_actions_heading"></h4>
<iam-action-select
data-error="$ctrl.onError(error)"
data-name="actions"
data-ng-model="$ctrl.model.actions"
data-ng-model="$ctrl.model"
data-resource-types="$ctrl.model.resources.types"
data-read-only="$ctrl.policy.readOnly"
data-tag-prefix=":: $ctrl.tag.prefix"
data-track-click=":: $ctrl.trackClick"
data-track-page=":: $ctrl.trackPage"
data-permissions-groups="$ctrl.permissionsGroups"
></iam-action-select>
<!-- </Actions> -->

Expand Down
3 changes: 3 additions & 0 deletions packages/manager/modules/iam/src/iam.constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ const UNAVAILABLE_STATE_NAME = 'app.account.user';

const URN_VERSION = 1;

const OVH_MANAGED_PERMISSIONS_GROUP = 'permissionsGroup:ovh';

export {
ALERT_ID,
API_ERROR,
Expand All @@ -294,6 +296,7 @@ export {
ENTITY_NAME_PATTERN,
FEATURE,
GUIDE,
OVH_MANAGED_PERMISSIONS_GROUP,
PAGE_SIZE,
PREFERENCES_KEY,
TAG,
Expand Down
12 changes: 12 additions & 0 deletions packages/manager/modules/iam/src/iam.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const URL = {
RESOURCE: '/engine/api/v2/iam/resource',
RESOURCE_GROUP: '/engine/api/v2/iam/resourceGroup',
RESOURCE_TYPE: '/engine/api/v2/iam/reference/resource/type',
PERMISSIONS_GROUPS: '/engine/api/v2/iam/permissionsGroup',
};

export default class IAMService {
Expand Down Expand Up @@ -404,6 +405,17 @@ export default class IAMService {
);
}

/**
* Get the list of permissionsGroups
* @returns {Promise}
*/
getPermissionsGroups() {
return this.Apiv2Service.httpApiv2({
method: 'get',
url: URL.PERMISSIONS_GROUPS,
}).then(({ data }) => data);
}

/**
* Modify a resource group
* @param {string} id The resource group's id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ export default /* @ngInject */ ($stateProvider) => {
resolve: {
breadcrumb: /* @ngInject */ ($translate) =>
$translate.instant('iam_policy_create'),
/**
* Retrieve the list of permissionsGroups
* @returns {Object|null}
*/
permissionsGroups: /* @ngInject */ (IAMService) =>
IAMService.getPermissionsGroups(),
},
atInternet: {
rename: TAG.ADD_POLICY,
Expand Down
7 changes: 7 additions & 0 deletions packages/manager/modules/iam/src/policy/edit/edit.routing.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ export default /* @ngInject */ ($stateProvider) => {
const { policy: uuid } = $transition$.params();
return uuid ? IAMService.getDetailedPolicy(uuid) : null;
},

/**
* Retrieve the list of permissionsGroups
* @returns {Object|null}
*/
permissionsGroups: /* @ngInject */ (IAMService) =>
IAMService.getPermissionsGroups(),
},
atInternet: {
rename: TAG.EDIT_POLICY,
Expand Down

0 comments on commit 3e2fb10

Please sign in to comment.