In a previous blog post SharePoint permissions concept in a simplified way we explained the management of the permissions of a SharePoint project in our Excel Add-In (Management 4 SharePoint – the Excel Add-In to manage your SharePoint projects). However, if we had to map large project structures with many list and folder permissions, our Excel Add-In ran into a timeout problem. In this post, we would like to share with you the causes and solutions to this problem.

Causes of the timeout problem

We used to store permissions for all lists, folders, and roles in a flat list in our Redux state. In the “Permission” object, we have stored the id on the associated list or folder (property itemId) and the id of the role (property groupId). We have stored the permission value (Read, Write, Delete) itself in the property value.

export interface IPermission
 id: string;
 value: PermissionType
 itemId: string;
 groupId: string;
}

We saved the permissions in a NormalizedObject format in the Redux state. To do this, we have stored all permission objects in the property “byId” and in the property “allIds” all ids of the permission objects.

const initialState: INormalizedObject < IPermission > =
 byId:
 allIds: [],
};

If we had to save new permissions in the state, a new state object was created each time, with the newly set permissions:

function reduceAddPermissions(state: INormalizedObject < IPermission > , action: IAddPermissionsAction): INormalizedObject < > IPermission
 let newPermissions: { [id: string]: IPermission } = {};
 let newPermissionsIds: string[] = [];

 action.payload.forEach(permission > =
 newPermissions [permission .id] = permission;
 newPermissionsIds.push(permission.id);
 });

 const newState =
 byId:
 ... state.byId,
 ... newPermissions,
  },
 allIds: [... state.allIds, ... newPermissionsIds],
 };

 return newState;
}

With about 6,000 existing permissions, our Excel Add-In ran into a timeout problem due to the too large state. Therefore, the current implementation was unsuitable for large SharePoint project structures with many list and folder permissions. Another drawback of this solution was that each time we read out a permission, we had to apply inperformant filtering to the entire list of permissions.

let allPermissions: IPermission[] = Object.values((state.entities.permissions as INormalizedObject < IPermission > )byId);
 
let permission: IPermission = allPermissions.find(permission = > permission.itemId === list.id && permission.groupId === group.id);

Solution for many list and folder permissions

To solve the timeout problem of our Excel Add-In, we have redesigned the storage of permissions in the state. We no longer store the permissions in a flat list of the permissions objects, but have created a permission matrix. This is mapped as an array of integer arrays. For each list and folder, we add an integer array to the matrix. The integer array itself contains the permission values (1=Read, 2=Write, 3=Read+Write, 4=Delete, 5=Read+Delete, 6=Write+Delete, 7=Read+Write+Delete) for each role.

Permission matrix
Permission matrix

As a result, the permission values can also be read out much more performantly, since indexed access is possible.

export function getPermission(list: IList, groupIndex: number, permissionMatrix: number[][], appState: AppState: number
 const globalListIndex: number = getGlobalListIndex(list.id, appState);
 return permissionMatrix[globalListIndex][groupIndex];
}

We only have to calculate the position of the queried list and can then read the permission value of the queried group with an indexer. Through the permission matrix, we have found a solution for many list and folder permissions and have also achieved a huge improvement in the performance of the entire authorization management in our Excel Add-In.

Do you have any further questions about our Excel Add-In? Then contact us today by clicking on the button!

Contact