From 5eb5bb02610868eeef2c33788b1c6e8ee1485a78 Mon Sep 17 00:00:00 2001 From: Marc Farra Date: Mon, 29 Nov 2021 14:13:39 +0200 Subject: [PATCH] Fix permissions for member and profile API calls --- app/manage/index.js | 2 +- app/manage/permissions/index.js | 1 + app/manage/permissions/view-team-members.js | 24 ++++++ app/manage/permissions/view-team.js | 20 ++--- components/edit-team-form.js | 8 ++ lib/profiles-api.js | 10 +-- lib/teams-api.js | 8 +- pages/team.js | 95 +++++++++++---------- 8 files changed, 101 insertions(+), 67 deletions(-) create mode 100644 app/manage/permissions/view-team-members.js diff --git a/app/manage/index.js b/app/manage/index.js index b31b7a88..2c9919b4 100644 --- a/app/manage/index.js +++ b/app/manage/index.js @@ -96,7 +96,7 @@ function manageRouter (nextApp) { router.get('/api/my/teams', can('public:authenticated'), listMyTeams) router.post('/api/teams', can('public:authenticated'), createTeam) router.get('/api/teams/:id', can('team:view'), getTeam) - router.get('/api/teams/:id/members', can('team:view'), getTeamMembers) + router.get('/api/teams/:id/members', can('team:view-members'), getTeamMembers) router.put('/api/teams/:id', can('team:edit'), updateTeam) router.delete('/api/teams/:id', can('team:edit'), destroyTeam) router.put('/api/teams/add/:id/:osmId', can('team:edit'), addMember) diff --git a/app/manage/permissions/index.js b/app/manage/permissions/index.js index 8d9c1f2b..0838830a 100644 --- a/app/manage/permissions/index.js +++ b/app/manage/permissions/index.js @@ -17,6 +17,7 @@ const keyPermissions = { const teamPermissions = { 'team:edit': require('./edit-team'), 'team:view': require('./view-team'), + 'team:view-members': require('./view-team-members'), 'team:join': require('./join-team'), 'team:member': require('./member-team') } diff --git a/app/manage/permissions/view-team-members.js b/app/manage/permissions/view-team-members.js new file mode 100644 index 00000000..28dedc8b --- /dev/null +++ b/app/manage/permissions/view-team-members.js @@ -0,0 +1,24 @@ +const { isPublic, isMember } = require('../../lib/team') + +/** + * team:view-members + * + * To view a team's members, the team needs to be either public + * or the user should be a member of the team + * + * @param {string} uid user id + * @param {Object} params request parameters + * @returns {boolean} can the request go through? + */ +async function viewTeamMembers (uid, { id }) { + const publicTeam = await isPublic(id) + if (publicTeam) return publicTeam + + try { + return await isMember(id, uid) + } catch (e) { + return false + } +} + +module.exports = viewTeamMembers diff --git a/app/manage/permissions/view-team.js b/app/manage/permissions/view-team.js index fbe3cbdf..d94a7fe0 100644 --- a/app/manage/permissions/view-team.js +++ b/app/manage/permissions/view-team.js @@ -1,24 +1,14 @@ -const { isPublic, isMember } = require('../../lib/team') - /** * team:view * - * To view a team, the team needs to be either public - * or the user should be a member of the team + * This covers team metadata, this should always be available + * to any users. Permission for individual pieces of metadata are controlled within + * the route code. * - * @param {string} uid user id - * @param {Object} params request parameters * @returns {boolean} can the request go through? */ -async function viewTeam (uid, { id }) { - const publicTeam = await isPublic(id) - if (publicTeam) return publicTeam - - try { - return await isMember(id, uid) - } catch (e) { - return false - } +async function viewTeam () { + return true } module.exports = viewTeam diff --git a/components/edit-team-form.js b/components/edit-team-form.js index b31f46e4..27de0f54 100644 --- a/components/edit-team-form.js +++ b/components/edit-team-form.js @@ -89,6 +89,14 @@ export default function EditTeamForm ({ initialValues, onSubmit, staff, isCreate URL to your team's editing policy if you have one (include http/https) {errors.editing_policy && renderError(errors.editing_policy)} +
+ + + + + + A private team does not show its member list or team details to non-members. +
{ staff && isCreateForm ? (
diff --git a/lib/profiles-api.js b/lib/profiles-api.js index 3e7950a9..7a420624 100644 --- a/lib/profiles-api.js +++ b/lib/profiles-api.js @@ -102,8 +102,8 @@ export async function deleteAttribute (id) { } /** - * getUserOrgrofile - * get the profile of a user in a team + * getUserOrgProfile + * get the profile of a user in a org */ export async function getUserOrgProfile (orgId, userId) { const res = await fetch(join(URL, 'organizations', `${orgId}`, `${userId}`), { @@ -114,7 +114,7 @@ export async function getUserOrgProfile (orgId, userId) { }) if (res.status === 200) { return res.json() - } if (res.status === 404) { + } if (res.status === 404 || res.status === 401) { return [] } else { const err = new Error('could not retrieve profile') @@ -136,7 +136,7 @@ export async function getUserTeamProfile (teamId, userId) { }) if (res.status === 200) { return res.json() - } if (res.status === 404) { + } if (res.status === 404 || res.status === 401) { return [] } else { const err = new Error('could not retrieve profile') @@ -242,7 +242,7 @@ export async function getTeamProfile (id) { }) if (res.status === 200) { return res.json() - } if (res.status === 404) { + } if (res.status === 404 || res.status === 401) { return [] } else { const err = new Error('could not retrieve profile') diff --git a/lib/teams-api.js b/lib/teams-api.js index 5cb7d72a..9336228b 100644 --- a/lib/teams-api.js +++ b/lib/teams-api.js @@ -72,7 +72,7 @@ export async function createOrgTeam (orgId, data) { * Get team details from the API * * @param id - id of team - * @returns {Object} - team details + moderators + members + * @returns {Object} - team details */ export async function getTeam (id) { let res = await fetch(join(URL, `${id}`)) @@ -124,7 +124,11 @@ export async function getTeamMembers (id) { let res = await fetch(join(URL, `${id}`, 'members')) if (res.status === 200) { return res.json() - } else { + } + if (res.status === 401) { // If unauthorized, don't display team members + return { members: [], moderators: []} + } + else { const err = new Error('could not retrieve team members') err.status = res.status throw err diff --git a/pages/team.js b/pages/team.js index 43a751a7..659c2ec6 100644 --- a/pages/team.js +++ b/pages/team.js @@ -46,8 +46,10 @@ export default class Team extends Component { const { id } = this.props try { let team = await getTeam(id) - let teamMembers = await getTeamMembers(id) - let teamProfile = await getTeamProfile(id) + let teamMembers = { moderators: [], members: [] } + let teamProfile = [] + teamMembers = await getTeamMembers(id) + teamProfile = await getTeamProfile(id) this.setState({ team, teamProfile, @@ -193,7 +195,7 @@ export default class Team extends Component { } } - if (!team || !teamMembers) return null + if (!team) return null const userId = this.props.user.uid const members = map(prop('id'), teamMembers.members) @@ -291,48 +293,53 @@ export default class Team extends Component {
-
-
- Team Members -
- { isUserModerator && ( - { - await addMember(team.id, osmId) - return this.getTeam() - }} + { + (team.privacy === 'public' || isMember) ? ( +
+
+ Team Members +
+ {isUserModerator && ( + { + await addMember(team.id, osmId) + return this.getTeam() + }} + /> + )} +
+
+ { + this.openProfileModal(row) + } + } + /> + + - )} - - -
{ - this.openProfileModal(row) - } - } - /> - - - - + + + ) + :
+ }