mirror of
				https://github.com/scm-manager/scm-manager.git
				synced 2025-10-31 10:35:56 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			626 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			626 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // @flow
 | |
| 
 | |
| import { apiClient } from "../../../../../scm-ui-components/packages/ui-components/src/index";
 | |
| import * as types from "../../../modules/types";
 | |
| import type { Action } from "../../../../../scm-ui-components/packages/ui-types/src/index";
 | |
| import type {
 | |
|   PermissionCollection,
 | |
|   Permission,
 | |
|   PermissionEntry
 | |
| } from "../types/Permissions";
 | |
| import { isPending } from "../../../modules/pending";
 | |
| import { getFailure } from "../../../modules/failure";
 | |
| import { Dispatch } from "redux";
 | |
| 
 | |
| export const FETCH_PERMISSIONS = "scm/permissions/FETCH_PERMISSIONS";
 | |
| export const FETCH_PERMISSIONS_PENDING = `${FETCH_PERMISSIONS}_${
 | |
|   types.PENDING_SUFFIX
 | |
| }`;
 | |
| export const FETCH_PERMISSIONS_SUCCESS = `${FETCH_PERMISSIONS}_${
 | |
|   types.SUCCESS_SUFFIX
 | |
| }`;
 | |
| export const FETCH_PERMISSIONS_FAILURE = `${FETCH_PERMISSIONS}_${
 | |
|   types.FAILURE_SUFFIX
 | |
| }`;
 | |
| export const MODIFY_PERMISSION = "scm/permissions/MODFIY_PERMISSION";
 | |
| export const MODIFY_PERMISSION_PENDING = `${MODIFY_PERMISSION}_${
 | |
|   types.PENDING_SUFFIX
 | |
| }`;
 | |
| export const MODIFY_PERMISSION_SUCCESS = `${MODIFY_PERMISSION}_${
 | |
|   types.SUCCESS_SUFFIX
 | |
| }`;
 | |
| export const MODIFY_PERMISSION_FAILURE = `${MODIFY_PERMISSION}_${
 | |
|   types.FAILURE_SUFFIX
 | |
| }`;
 | |
| export const MODIFY_PERMISSION_RESET = `${MODIFY_PERMISSION}_${
 | |
|   types.RESET_SUFFIX
 | |
| }`;
 | |
| export const CREATE_PERMISSION = "scm/permissions/CREATE_PERMISSION";
 | |
| export const CREATE_PERMISSION_PENDING = `${CREATE_PERMISSION}_${
 | |
|   types.PENDING_SUFFIX
 | |
| }`;
 | |
| export const CREATE_PERMISSION_SUCCESS = `${CREATE_PERMISSION}_${
 | |
|   types.SUCCESS_SUFFIX
 | |
| }`;
 | |
| export const CREATE_PERMISSION_FAILURE = `${CREATE_PERMISSION}_${
 | |
|   types.FAILURE_SUFFIX
 | |
| }`;
 | |
| export const CREATE_PERMISSION_RESET = `${CREATE_PERMISSION}_${
 | |
|   types.RESET_SUFFIX
 | |
| }`;
 | |
| export const DELETE_PERMISSION = "scm/permissions/DELETE_PERMISSION";
 | |
| export const DELETE_PERMISSION_PENDING = `${DELETE_PERMISSION}_${
 | |
|   types.PENDING_SUFFIX
 | |
| }`;
 | |
| export const DELETE_PERMISSION_SUCCESS = `${DELETE_PERMISSION}_${
 | |
|   types.SUCCESS_SUFFIX
 | |
| }`;
 | |
| export const DELETE_PERMISSION_FAILURE = `${DELETE_PERMISSION}_${
 | |
|   types.FAILURE_SUFFIX
 | |
| }`;
 | |
| export const DELETE_PERMISSION_RESET = `${DELETE_PERMISSION}_${
 | |
|   types.RESET_SUFFIX
 | |
| }`;
 | |
| 
 | |
| const REPOS_URL = "repositories";
 | |
| const PERMISSIONS_URL = "permissions";
 | |
| const CONTENT_TYPE = "application/vnd.scmm-permission+json";
 | |
| 
 | |
| // fetch permissions
 | |
| 
 | |
| export function fetchPermissions(namespace: string, repoName: string) {
 | |
|   return function(dispatch: any) {
 | |
|     dispatch(fetchPermissionsPending(namespace, repoName));
 | |
|     return apiClient
 | |
|       .get(`${REPOS_URL}/${namespace}/${repoName}/${PERMISSIONS_URL}`)
 | |
|       .then(response => response.json())
 | |
|       .then(permissions => {
 | |
|         dispatch(fetchPermissionsSuccess(permissions, namespace, repoName));
 | |
|       })
 | |
|       .catch(err => {
 | |
|         dispatch(fetchPermissionsFailure(namespace, repoName, err));
 | |
|       });
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function fetchPermissionsPending(
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ): Action {
 | |
|   return {
 | |
|     type: FETCH_PERMISSIONS_PENDING,
 | |
|     payload: {
 | |
|       namespace,
 | |
|       repoName
 | |
|     },
 | |
|     itemId: namespace + "/" + repoName
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function fetchPermissionsSuccess(
 | |
|   permissions: any,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ): Action {
 | |
|   return {
 | |
|     type: FETCH_PERMISSIONS_SUCCESS,
 | |
|     payload: permissions,
 | |
|     itemId: namespace + "/" + repoName
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function fetchPermissionsFailure(
 | |
|   namespace: string,
 | |
|   repoName: string,
 | |
|   error: Error
 | |
| ): Action {
 | |
|   return {
 | |
|     type: FETCH_PERMISSIONS_FAILURE,
 | |
|     payload: {
 | |
|       namespace,
 | |
|       repoName,
 | |
|       error
 | |
|     },
 | |
|     itemId: namespace + "/" + repoName
 | |
|   };
 | |
| }
 | |
| 
 | |
| // modify permission
 | |
| 
 | |
| export function modifyPermission(
 | |
|   permission: Permission,
 | |
|   namespace: string,
 | |
|   repoName: string,
 | |
|   callback?: () => void
 | |
| ) {
 | |
|   return function(dispatch: any) {
 | |
|     dispatch(modifyPermissionPending(permission, namespace, repoName));
 | |
|     return apiClient
 | |
|       .put(permission._links.update.href, permission, CONTENT_TYPE)
 | |
|       .then(() => {
 | |
|         dispatch(modifyPermissionSuccess(permission, namespace, repoName));
 | |
|         if (callback) {
 | |
|           callback();
 | |
|         }
 | |
|       })
 | |
|       .catch(cause => {
 | |
|         const error = new Error(
 | |
|           `failed to modify permission: ${cause.message}`
 | |
|         );
 | |
|         dispatch(
 | |
|           modifyPermissionFailure(permission, error, namespace, repoName)
 | |
|         );
 | |
|       });
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function modifyPermissionPending(
 | |
|   permission: Permission,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ): Action {
 | |
|   return {
 | |
|     type: MODIFY_PERMISSION_PENDING,
 | |
|     payload: permission,
 | |
|     itemId: namespace + "/" + repoName + "/" + permission.name
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function modifyPermissionSuccess(
 | |
|   permission: Permission,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ): Action {
 | |
|   return {
 | |
|     type: MODIFY_PERMISSION_SUCCESS,
 | |
|     payload: {
 | |
|       permission,
 | |
|       position: namespace + "/" + repoName
 | |
|     },
 | |
|     itemId: namespace + "/" + repoName + "/" + permission.name
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function modifyPermissionFailure(
 | |
|   permission: Permission,
 | |
|   error: Error,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ): Action {
 | |
|   return {
 | |
|     type: MODIFY_PERMISSION_FAILURE,
 | |
|     payload: { error, permission },
 | |
|     itemId: namespace + "/" + repoName + "/" + permission.name
 | |
|   };
 | |
| }
 | |
| 
 | |
| function newPermissions(
 | |
|   oldPermissions: PermissionCollection,
 | |
|   newPermission: Permission
 | |
| ) {
 | |
|   for (let i = 0; i < oldPermissions.length; i++) {
 | |
|     if (oldPermissions[i].name === newPermission.name) {
 | |
|       oldPermissions.splice(i, 1, newPermission);
 | |
|       return oldPermissions;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| export function modifyPermissionReset(namespace: string, repoName: string) {
 | |
|   return {
 | |
|     type: MODIFY_PERMISSION_RESET,
 | |
|     payload: {
 | |
|       namespace,
 | |
|       repoName
 | |
|     },
 | |
|     itemId: namespace + "/" + repoName
 | |
|   };
 | |
| }
 | |
| 
 | |
| // create permission
 | |
| export function createPermission(
 | |
|   permission: PermissionEntry,
 | |
|   namespace: string,
 | |
|   repoName: string,
 | |
|   callback?: () => void
 | |
| ) {
 | |
|   return function(dispatch: Dispatch) {
 | |
|     dispatch(createPermissionPending(permission, namespace, repoName));
 | |
|     return apiClient
 | |
|       .post(
 | |
|         `${REPOS_URL}/${namespace}/${repoName}/${PERMISSIONS_URL}`,
 | |
|         permission,
 | |
|         CONTENT_TYPE
 | |
|       )
 | |
|       .then(response => {
 | |
|         const location = response.headers.get("Location");
 | |
|         return apiClient.get(location);
 | |
|       })
 | |
|       .then(response => response.json())
 | |
|       .then(createdPermission => {
 | |
|         dispatch(
 | |
|           createPermissionSuccess(createdPermission, namespace, repoName)
 | |
|         );
 | |
|         if (callback) {
 | |
|           callback();
 | |
|         }
 | |
|       })
 | |
|       .catch(err =>
 | |
|         dispatch(
 | |
|           createPermissionFailure(
 | |
|             new Error(
 | |
|               `failed to add permission ${permission.name}: ${err.message}`
 | |
|             ),
 | |
|             namespace,
 | |
|             repoName
 | |
|           )
 | |
|         )
 | |
|       );
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function createPermissionPending(
 | |
|   permission: PermissionEntry,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ): Action {
 | |
|   return {
 | |
|     type: CREATE_PERMISSION_PENDING,
 | |
|     payload: permission,
 | |
|     itemId: namespace + "/" + repoName
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function createPermissionSuccess(
 | |
|   permission: PermissionEntry,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ): Action {
 | |
|   return {
 | |
|     type: CREATE_PERMISSION_SUCCESS,
 | |
|     payload: {
 | |
|       permission,
 | |
|       position: namespace + "/" + repoName
 | |
|     },
 | |
|     itemId: namespace + "/" + repoName
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function createPermissionFailure(
 | |
|   error: Error,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ): Action {
 | |
|   return {
 | |
|     type: CREATE_PERMISSION_FAILURE,
 | |
|     payload: error,
 | |
|     itemId: namespace + "/" + repoName
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function createPermissionReset(namespace: string, repoName: string) {
 | |
|   return {
 | |
|     type: CREATE_PERMISSION_RESET,
 | |
|     itemId: namespace + "/" + repoName
 | |
|   };
 | |
| }
 | |
| 
 | |
| // delete permission
 | |
| 
 | |
| export function deletePermission(
 | |
|   permission: Permission,
 | |
|   namespace: string,
 | |
|   repoName: string,
 | |
|   callback?: () => void
 | |
| ) {
 | |
|   return function(dispatch: any) {
 | |
|     dispatch(deletePermissionPending(permission, namespace, repoName));
 | |
|     return apiClient
 | |
|       .delete(permission._links.delete.href)
 | |
|       .then(() => {
 | |
|         dispatch(deletePermissionSuccess(permission, namespace, repoName));
 | |
|         if (callback) {
 | |
|           callback();
 | |
|         }
 | |
|       })
 | |
|       .catch(cause => {
 | |
|         const error = new Error(
 | |
|           `could not delete permission ${permission.name}: ${cause.message}`
 | |
|         );
 | |
|         dispatch(
 | |
|           deletePermissionFailure(permission, namespace, repoName, error)
 | |
|         );
 | |
|       });
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function deletePermissionPending(
 | |
|   permission: Permission,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ): Action {
 | |
|   return {
 | |
|     type: DELETE_PERMISSION_PENDING,
 | |
|     payload: permission,
 | |
|     itemId: namespace + "/" + repoName + "/" + permission.name
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function deletePermissionSuccess(
 | |
|   permission: Permission,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ): Action {
 | |
|   return {
 | |
|     type: DELETE_PERMISSION_SUCCESS,
 | |
|     payload: {
 | |
|       permission,
 | |
|       position: namespace + "/" + repoName
 | |
|     },
 | |
|     itemId: namespace + "/" + repoName + "/" + permission.name
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function deletePermissionFailure(
 | |
|   permission: Permission,
 | |
|   namespace: string,
 | |
|   repoName: string,
 | |
|   error: Error
 | |
| ): Action {
 | |
|   return {
 | |
|     type: DELETE_PERMISSION_FAILURE,
 | |
|     payload: {
 | |
|       error,
 | |
|       permission
 | |
|     },
 | |
|     itemId: namespace + "/" + repoName + "/" + permission.name
 | |
|   };
 | |
| }
 | |
| 
 | |
| export function deletePermissionReset(namespace: string, repoName: string) {
 | |
|   return {
 | |
|     type: DELETE_PERMISSION_RESET,
 | |
|     payload: {
 | |
|       namespace,
 | |
|       repoName
 | |
|     },
 | |
|     itemId: namespace + "/" + repoName
 | |
|   };
 | |
| }
 | |
| function deletePermissionFromState(
 | |
|   oldPermissions: PermissionCollection,
 | |
|   permission: Permission
 | |
| ) {
 | |
|   let newPermission = [];
 | |
|   for (let i = 0; i < oldPermissions.length; i++) {
 | |
|     if (oldPermissions[i] !== permission) {
 | |
|       newPermission.push(oldPermissions[i]);
 | |
|     }
 | |
|   }
 | |
|   return newPermission;
 | |
| }
 | |
| 
 | |
| // reducer
 | |
| export default function reducer(
 | |
|   state: Object = {},
 | |
|   action: Action = { type: "UNKNOWN" }
 | |
| ): Object {
 | |
|   if (!action.payload) {
 | |
|     return state;
 | |
|   }
 | |
|   switch (action.type) {
 | |
|     case FETCH_PERMISSIONS_SUCCESS:
 | |
|       return {
 | |
|         ...state,
 | |
|         [action.itemId]: {
 | |
|           entries: action.payload._embedded.permissions,
 | |
|           createPermission: action.payload._links.create ? true : false
 | |
|         }
 | |
|       };
 | |
|     case MODIFY_PERMISSION_SUCCESS:
 | |
|       const positionOfPermission = action.payload.position;
 | |
|       const newPermission = newPermissions(
 | |
|         state[action.payload.position].entries,
 | |
|         action.payload.permission
 | |
|       );
 | |
|       return {
 | |
|         ...state,
 | |
|         [positionOfPermission]: {
 | |
|           ...state[positionOfPermission],
 | |
|           entries: newPermission
 | |
|         }
 | |
|       };
 | |
|     case CREATE_PERMISSION_SUCCESS:
 | |
|       // return state;
 | |
|       const position = action.payload.position;
 | |
|       const permissions = state[action.payload.position].entries;
 | |
|       permissions.push(action.payload.permission);
 | |
|       return {
 | |
|         ...state,
 | |
|         [position]: {
 | |
|           ...state[position],
 | |
|           entries: permissions
 | |
|         }
 | |
|       };
 | |
|     case DELETE_PERMISSION_SUCCESS:
 | |
|       const permissionPosition = action.payload.position;
 | |
|       const new_Permissions = deletePermissionFromState(
 | |
|         state[action.payload.position].entries,
 | |
|         action.payload.permission
 | |
|       );
 | |
|       return {
 | |
|         ...state,
 | |
|         [permissionPosition]: {
 | |
|           ...state[permissionPosition],
 | |
|           entries: new_Permissions
 | |
|         }
 | |
|       };
 | |
|     default:
 | |
|       return state;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // selectors
 | |
| 
 | |
| export function getPermissionsOfRepo(
 | |
|   state: Object,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ) {
 | |
|   if (state.permissions && state.permissions[namespace + "/" + repoName]) {
 | |
|     const permissions = state.permissions[namespace + "/" + repoName].entries;
 | |
|     return permissions;
 | |
|   }
 | |
| }
 | |
| 
 | |
| export function isFetchPermissionsPending(
 | |
|   state: Object,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ) {
 | |
|   return isPending(state, FETCH_PERMISSIONS, namespace + "/" + repoName);
 | |
| }
 | |
| 
 | |
| export function getFetchPermissionsFailure(
 | |
|   state: Object,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ) {
 | |
|   return getFailure(state, FETCH_PERMISSIONS, namespace + "/" + repoName);
 | |
| }
 | |
| 
 | |
| export function isModifyPermissionPending(
 | |
|   state: Object,
 | |
|   namespace: string,
 | |
|   repoName: string,
 | |
|   permissionname: string
 | |
| ) {
 | |
|   return isPending(
 | |
|     state,
 | |
|     MODIFY_PERMISSION,
 | |
|     namespace + "/" + repoName + "/" + permissionname
 | |
|   );
 | |
| }
 | |
| 
 | |
| export function getModifyPermissionFailure(
 | |
|   state: Object,
 | |
|   namespace: string,
 | |
|   repoName: string,
 | |
|   permissionname: string
 | |
| ) {
 | |
|   return getFailure(
 | |
|     state,
 | |
|     MODIFY_PERMISSION,
 | |
|     namespace + "/" + repoName + "/" + permissionname
 | |
|   );
 | |
| }
 | |
| 
 | |
| export function hasCreatePermission(
 | |
|   state: Object,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ) {
 | |
|   if (state.permissions && state.permissions[namespace + "/" + repoName])
 | |
|     return state.permissions[namespace + "/" + repoName].createPermission;
 | |
|   else return null;
 | |
| }
 | |
| 
 | |
| export function isCreatePermissionPending(
 | |
|   state: Object,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ) {
 | |
|   return isPending(state, CREATE_PERMISSION, namespace + "/" + repoName);
 | |
| }
 | |
| export function getCreatePermissionFailure(
 | |
|   state: Object,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ) {
 | |
|   return getFailure(state, CREATE_PERMISSION, namespace + "/" + repoName);
 | |
| }
 | |
| 
 | |
| export function isDeletePermissionPending(
 | |
|   state: Object,
 | |
|   namespace: string,
 | |
|   repoName: string,
 | |
|   permissionname: string
 | |
| ) {
 | |
|   return isPending(
 | |
|     state,
 | |
|     DELETE_PERMISSION,
 | |
|     namespace + "/" + repoName + "/" + permissionname
 | |
|   );
 | |
| }
 | |
| 
 | |
| export function getDeletePermissionFailure(
 | |
|   state: Object,
 | |
|   namespace: string,
 | |
|   repoName: string,
 | |
|   permissionname: string
 | |
| ) {
 | |
|   return getFailure(
 | |
|     state,
 | |
|     DELETE_PERMISSION,
 | |
|     namespace + "/" + repoName + "/" + permissionname
 | |
|   );
 | |
| }
 | |
| 
 | |
| export function getDeletePermissionsFailure(
 | |
|   state: Object,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ) {
 | |
|   const permissions =
 | |
|     state.permissions && state.permissions[namespace + "/" + repoName]
 | |
|       ? state.permissions[namespace + "/" + repoName].entries
 | |
|       : null;
 | |
|   if (permissions == null) return undefined;
 | |
|   for (let i = 0; i < permissions.length; i++) {
 | |
|     if (
 | |
|       getDeletePermissionFailure(
 | |
|         state,
 | |
|         namespace,
 | |
|         repoName,
 | |
|         permissions[i].name
 | |
|       )
 | |
|     ) {
 | |
|       return getFailure(
 | |
|         state,
 | |
|         DELETE_PERMISSION,
 | |
|         namespace + "/" + repoName + "/" + permissions[i].name
 | |
|       );
 | |
|     }
 | |
|   }
 | |
|   return null;
 | |
| }
 | |
| 
 | |
| export function getModifyPermissionsFailure(
 | |
|   state: Object,
 | |
|   namespace: string,
 | |
|   repoName: string
 | |
| ) {
 | |
|   const permissions =
 | |
|     state.permissions && state.permissions[namespace + "/" + repoName]
 | |
|       ? state.permissions[namespace + "/" + repoName].entries
 | |
|       : null;
 | |
|   if (permissions == null) return undefined;
 | |
|   for (let i = 0; i < permissions.length; i++) {
 | |
|     if (
 | |
|       getModifyPermissionFailure(
 | |
|         state,
 | |
|         namespace,
 | |
|         repoName,
 | |
|         permissions[i].name
 | |
|       )
 | |
|     ) {
 | |
|       return getFailure(
 | |
|         state,
 | |
|         MODIFY_PERMISSION,
 | |
|         namespace + "/" + repoName + "/" + permissions[i].name
 | |
|       );
 | |
|     }
 | |
|   }
 | |
|   return null;
 | |
| }
 |