Skip to content

Commit

Permalink
ui - use member comment as justification when approving self review r…
Browse files Browse the repository at this point in the history
…oles and grops

Signed-off-by: aporss <[email protected]>
  • Loading branch information
ArtjomsPorss committed Jan 16, 2025
1 parent 7285193 commit d7624d3
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 9 deletions.
2 changes: 2 additions & 0 deletions ui/src/components/pending-approval/PendingApprovalTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,8 @@ class PendingApprovalTable extends React.Component {
pendingState={this.state.pendingMap[key].pendingState}
view={view}
timeZone={this.props.timeZone}
selfServe={pending.selfServe}
auditRef={pending.auditRef}
/>
);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,9 @@ export default class PendingApprovalTableRow extends React.Component {
onChange={(event) => {
this.props.auditRefChange(key, event);
}}
/>
{...(this.props.selfServe && {defaultValue:this.props.auditRef})}
>
</StyledTextArea>
{this.props.auditRefMissing ? (
<ErrorDiv>Justification is Required</ErrorDiv>
) : null}
Expand Down
29 changes: 29 additions & 0 deletions ui/src/redux/actions/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,32 @@ export const addUsersToStore = (userList) => ({
userList: userList,
},
});

export const STORE_PENDING_ROLE = 'STORE_PENDING_ROLE';
export const storePendingRole = (role, domainName, roleName) => {
console.log("ROLE: ", {
type: STORE_PENDING_ROLE,
payload: {
role,
domainName,
roleName
}
});

return {
type: STORE_PENDING_ROLE,
payload: {
role,
domainName,
roleName,
},
};
};

export const STORE_PENDING_GROUP = 'STORE_PENDING_GROUP';
export const storePendingGroup = (group, domainName, groupName) => ({
type: STORE_PENDING_GROUP,
payload: { group,
domainName, groupName},
});

19 changes: 18 additions & 1 deletion ui/src/redux/reducers/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import {
ADD_ALL_USERS,
LOAD_PENDING_MEMBERS,
LOAD_RESOURCE_ACCESS_LIST,
LOAD_RESOURCE_ACCESS_LIST, STORE_PENDING_GROUP, STORE_PENDING_ROLE,
} from '../actions/user';
import {
PROCESS_GROUP_PENDING_MEMBERS_TO_STORE,
Expand Down Expand Up @@ -72,6 +72,23 @@ export const user = (state = {}, action) => {
draft.userList = userList;
});
}
case STORE_PENDING_ROLE: {
return produce(state, (draft) => {
if (!draft.pendingMemberRoles) {
draft.pendingMemberRoles = {};
}
draft.pendingMemberRoles[`${payload.domainName}:${payload.roleName}`] = payload.role;

});
}
case STORE_PENDING_GROUP: {
return produce(state, (draft) => {
if (!draft.pendingMemberGroups) {
draft.pendingMemberGroups = {};
}
draft.pendingMemberGroups[`${payload.domainName}:${payload.groupName}`] = payload.group;
});
}
default:
return state;
}
Expand Down
4 changes: 2 additions & 2 deletions ui/src/redux/selectors/groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const selectGroups = (state) => {
};

export const selectGroup = (state, domainName, groupName) => {
return state.groups.groups &&
return state.groups && state.groups.groups &&
state.groups.groups[getFullName(domainName, groupDelimiter, groupName)]
? state.groups.groups[
getFullName(domainName, groupDelimiter, groupName)
Expand All @@ -43,7 +43,7 @@ export const thunkSelectGroupMembers = (state, domainName, groupName) => {
};

export const selectGroupMembers = (state, domainName, groupName) => {
return state.groups.groups &&
return state.groups && state.groups.groups &&
state.groups.groups[getFullName(domainName, groupDelimiter, groupName)]
? membersMapsToList(
state.groups.groups[
Expand Down
4 changes: 2 additions & 2 deletions ui/src/redux/selectors/roles.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ export const selectRoleUsers = (state) => {
};

export const selectRole = (state, domainName, roleName) => {
return state.roles.roles &&
return state.roles && state.roles.roles &&
state.roles.roles[getFullName(domainName, roleDelimiter, roleName)]
? state.roles.roles[getFullName(domainName, roleDelimiter, roleName)]
: {};
};

export const selectRoleMembers = (state, domainName, roleName) => {
return state.roles.roles &&
return state.roles && state.roles.roles &&
state.roles.roles[getFullName(domainName, roleDelimiter, roleName)] &&
state.roles.roles[getFullName(domainName, roleDelimiter, roleName)]
.roleMembers
Expand Down
5 changes: 5 additions & 0 deletions ui/src/redux/selectors/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,8 @@ export const selectUserResourceAccessList = (state) =>
export const selectAllUsers = (state) => {
return state.user.userList;
};

export const selectPendingMemberRole = (state, domainName, roleName) =>
state?.user?.pendingMemberRoles?.[`${domainName}:${roleName}`] ?? null ;
export const selectPendingMemberGroup = (state, domainName, groupName) =>
state?.user?.pendingMemberGroups?.[`${domainName}:${groupName}`] ?? null;
100 changes: 97 additions & 3 deletions ui/src/redux/thunks/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
* limitations under the License.
*/

import { getExpiryTime, isExpired } from '../utils';
import { getExpiryTime, isExpired, membersListToMaps } from '../utils';
import {
selectAllUsers,
selectAllUsers, selectPendingMemberGroup, selectPendingMemberRole,
selectUserPendingMembers,
selectUserResourceAccessList,
} from '../selectors/user';
Expand All @@ -25,7 +25,7 @@ import {
addUsersToStore,
loadUserPendingMembers,
loadUserResourceAccessList,
returnUserResourceAccessList,
returnUserResourceAccessList, storePendingGroup, storePendingRole,
} from '../actions/user';

import {
Expand All @@ -34,6 +34,93 @@ import {
loadingSuccess,
} from '../actions/loading';

const ROLE = "role";
const GROUP = "group";

const getPendingMemberRole = async (dispatch, state,domainName, roleName) => {
let role = selectPendingMemberRole(state, domainName, roleName);
if (!role || isExpired(role.expiry)) {
role = await API().getRole(domainName, roleName, false, false, true);
role.expiry = getExpiryTime();
dispatch(storePendingRole(role, domainName, roleName));
}
return role;
}
const getPendingMemberGroup = async (dispatch, state, domainName, groupName) => {
let group = selectPendingMemberGroup(state, domainName, groupName);
if (!group || isExpired(group.expiry)) {
group = await API().getGroup(domainName, groupName, false, true);
group.expiry = getExpiryTime();
dispatch(storePendingGroup(group, domainName, groupName));
}
return group;
}


const prepareSelfServePendingMembers = async (pendingMembers, category, dispatch, state) => {
// SET MEMBER COMMENT AS AUDITREF FOR SELF-SERVE ROLES/GROUPS
// set of domains to search for roles/groups
/*
console.log('T prepareSelfServePendingMembers');
// TODO remove all entries except one for testing
Object.keys(pendingMembers).forEach((member) => {
if (member == "home.aporssuser.palakasself-service-test") {
return;
}
delete pendingMembers[member];
});
// TODO =====
*/

// create a set of domain.role
let roleOrGroupSet = new Set();
Object.keys(pendingMembers).forEach((member) => {
const memberData = pendingMembers[member];
if (category === memberData.category) {
roleOrGroupSet.add(`${memberData.domainName}:${memberData.roleName}`);
}
});

let promises = [];
roleOrGroupSet.forEach((entity)=>{
let [domain, role] = entity.split(":");
if (category === ROLE) {
promises.push(getPendingMemberRole(dispatch, state, domain, role));
} else if (category === GROUP) {
promises.push(getPendingMemberGroup(dispatch, state, domain, role));
}
})

let data = await Promise.all(promises);

Object.keys(pendingMembers).forEach((memberName) => {
const member = pendingMembers[memberName];
if (member.category !== category) {
return; // category is different (can be role or group)
}
// category matches
for(let i = 0; i < data.length; i++) {
const roleGroup = data[i];
if (!roleGroup.selfServe) {
continue; // we only look for self-serve roles/groups
}
const [domain, rest] = roleGroup.name.split(":");
if (domain !== member.domainName) {
break; // go to next "i" list containing roles/groups for diff domain
}
// domain matches
const [princType, roleGroupName] = rest.split(".");
if (roleGroupName === member.roleName) {
// role/group name matches member's role/group and is self serve
// set audetRef as provided comment
member.auditRef = member.userComment;
member.selfServe = true;
}
}
});
}

export const getUserPendingMembers = () => async (dispatch, getState) => {
const expiry = getExpiryTime();
try {
Expand All @@ -44,10 +131,17 @@ export const getUserPendingMembers = () => async (dispatch, getState) => {
) {
let userPendingMembersList =
await API().getPendingDomainMembersList();

let promises = [];
promises.push(prepareSelfServePendingMembers(userPendingMembersList, ROLE, dispatch, getState()));
promises.push(prepareSelfServePendingMembers(userPendingMembersList, GROUP, dispatch, getState()));
await Promise.all(promises);

dispatch(loadUserPendingMembers(userPendingMembersList, expiry));
}
} catch (error) {
// if error, set userPendingMembers to empty array
console.error(error);
dispatch(loadUserPendingMembers([], expiry));
}
};
Expand Down

0 comments on commit d7624d3

Please sign in to comment.