Skip to content

Commit 07a6c00

Browse files
committed
add new visibility for org_staff
1 parent cfc34f6 commit 07a6c00

File tree

4 files changed

+70
-30
lines changed

4 files changed

+70
-30
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const constraintName = 'profile_keys_visibility_check'
2+
3+
exports.up = async (knex) => {
4+
await knex.raw(`ALTER TABLE profile_keys DROP CONSTRAINT IF EXISTS ${constraintName};`)
5+
await knex.raw(`ALTER TABLE profile_keys ADD CONSTRAINT ${constraintName} CHECK (visibility = ANY (ARRAY['public'::text, 'team'::text, 'org'::text, 'org_staff'::text]))`)
6+
}
7+
8+
exports.down = async (knex) => {
9+
await knex.raw(`ALTER TABLE profile_keys DROP CONSTRAINT IF EXISTS ${constraintName};`)
10+
await knex.raw(`ALTER TABLE profile_keys ADD CONSTRAINT ${constraintName} CHECK (visibility = ANY (ARRAY['public'::text, 'team'::text, 'org'::text]))`)
11+
}

app/lib/profile.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const db = require('../db')
22
const { unpack, ValidationError, checkRequiredProperties, PropertyRequiredError } = require('../lib/utils')
3-
const { map, has, propEq, anyPass, forEach, mergeRight, prop, assoc, pick, keys } = require('ramda')
3+
const { map, has, propEq, anyPass, forEach, prop, assoc, pick, keys } = require('ramda')
44

55
/**
66
* Given the profile type return the db table
@@ -40,7 +40,8 @@ const profileTypeValid = anyPass([
4040
const visibilityValid = anyPass([
4141
propEq('visibility', 'public'),
4242
propEq('visibility', 'team'),
43-
propEq('visibility', 'org')
43+
propEq('visibility', 'org'),
44+
propEq('visibility', 'org_staff')
4445
])
4546

4647
/**
@@ -51,7 +52,7 @@ const visibilityValid = anyPass([
5152
* @param {string} attribute.description Description of the attribute
5253
* @param {string} attribute.profileType enum: 'owner', 'user', 'team'
5354
* @param {boolean} attribute.required whether this attribute is required to be filled
54-
* @param {enum} attribute.visibility enum: 'owner', 'user', 'team'
55+
* @param {enum} attribute.visibility enum: 'org_staff', 'org', 'user', 'team'
5556
*/
5657
function checkProfileKey (attribute) {
5758
checkRequiredProperties(['name', 'profileType'], attribute)
@@ -61,7 +62,7 @@ function checkProfileKey (attribute) {
6162
}
6263

6364
if (has('visibility', attribute) && !visibilityValid(attribute)) {
64-
throw new ValidationError('visibility should be one of "public", "team" or "org"')
65+
throw new ValidationError('visibility should be one of "public", "team", "org" or "org_staff"')
6566
}
6667
}
6768

@@ -73,7 +74,7 @@ function checkProfileKey (attribute) {
7374
* @param {string} attributes[].description Description of the attribute
7475
* @param {string} attributes[].profileType enum: 'owner', 'user', 'team'
7576
* @param {boolean} attributes[].required whether this attribute is required to be filled
76-
* @param {enum} attributes[].visibility enum: 'owner', 'user', 'team'
77+
* @param {enum} attributes[].visibility enum: 'org_staff', 'org', 'user', 'team'
7778
* @param {string} ownerType enum: 'owner', 'user', 'team'
7879
* @param {integer} ownerId iD in owner, user or team tables
7980
*/
@@ -114,11 +115,11 @@ async function addProfileKeys (attributes, ownerType, ownerId) {
114115
* @param {integer} id id of key to modify
115116
* @param {string} attribute.description Description of the attribute
116117
* @param {boolean} attribute.required whether this attribute is required to be filled
117-
* @param {enum} attribute.visibility enum: 'owner', 'user', 'team'
118+
* @param {enum} attribute.visibility enum: 'org_staff', 'org', 'user', 'team'
118119
*/
119120
async function modifyProfileKey (id, attribute) {
120121
if (has('visibility', attribute) && !visibilityValid(attribute)) {
121-
throw new ValidationError('visibility should be one of "public", "team" or "org"')
122+
throw new ValidationError('visibility should be one of "public", "team", "org" or "org_staff"')
122123
}
123124

124125
const conn = await db()
@@ -209,10 +210,11 @@ async function setProfile (attributeValues, profileType, id) {
209210
tags = pick(map(prop('id'), tagsInDB), tags)
210211

211212
// Add the attribute values
212-
tags = attributeValues.reduce(
213-
(acc, curr) => mergeRight(acc, { [curr['key_id']]: curr['value'] }),
214-
tags
215-
)
213+
attributeValues.forEach(tagPair => {
214+
if (tagPair.key_id) {
215+
tags[tagPair.key_id] = tagPair.value
216+
}
217+
})
216218

217219
const table = getTableForProfileType(profileType)
218220

app/manage/profiles.js

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,26 +30,42 @@ async function getUserOrgProfile (req, reply) {
3030

3131
// Get org keys & visibility
3232
orgKeys = await profile.getProfileKeysForOwner('org', orgId, 'user')
33-
requesterIsMemberOfOrg = await org.isMember(orgId, requesterId)
34-
requesterIsManagerOfOrg = await org.isManager(orgId, requesterId)
35-
requesterIsOwnerOfOrg = await org.isManager(orgId, requesterId)
3633

37-
// Get visibile keys
38-
orgKeys.forEach((key) => {
39-
const { visibility } = key
40-
switch (visibility) {
41-
case 'public': {
42-
visibleKeys.push(key)
43-
break
44-
}
45-
case 'org': {
46-
if (requesterIsMemberOfOrg || requesterIsOwnerOfOrg || requesterIsManagerOfOrg) {
34+
if (requesterId === osmId) {
35+
const allIds = orgKeys.map(prop('id'))
36+
const allValues = pick(allIds, tags)
37+
const keysToSend = orgKeys.map(key => {
38+
return assoc('value', allValues[key.id], key)
39+
})
40+
return reply.send(keysToSend)
41+
} else {
42+
requesterIsMemberOfOrg = await org.isMember(orgId, requesterId)
43+
requesterIsManagerOfOrg = await org.isManager(orgId, requesterId)
44+
requesterIsOwnerOfOrg = await org.isOwner(orgId, requesterId)
45+
46+
// Get visibile keys
47+
orgKeys.forEach((key) => {
48+
const { visibility } = key
49+
switch (visibility) {
50+
case 'public': {
4751
visibleKeys.push(key)
52+
break
53+
}
54+
case 'org_staff': {
55+
if (requesterIsOwnerOfOrg || requesterIsManagerOfOrg) {
56+
visibleKeys.push(key)
57+
}
58+
break
59+
}
60+
case 'org': {
61+
if (requesterIsMemberOfOrg || requesterIsOwnerOfOrg || requesterIsManagerOfOrg) {
62+
visibleKeys.push(key)
63+
}
64+
break
4865
}
49-
break
5066
}
51-
}
52-
})
67+
})
68+
}
5369

5470
// Get values for keys
5571
const visibleKeyIds = visibleKeys.map(prop('id'))
@@ -82,6 +98,7 @@ async function getTeamProfile (req, reply) {
8298
let teamKeys = []
8399
let requesterIsMemberOfTeam = false
84100
let requesterIsMemberOfOrg = false
101+
let requesterIsManagerOfOrg = false
85102
let requesterIsOwnerOfOrg = false
86103

87104
const values = await profile.getProfile('team', teamId)
@@ -99,10 +116,11 @@ async function getTeamProfile (req, reply) {
99116

100117
const isUserModerator = await team.isModerator(teamId, requesterId)
101118

102-
// Get team attributes
119+
// Get team attributes from org
103120
teamKeys = await profile.getProfileKeysForOwner('org', associatedOrg.organization_id, 'team')
104121
requesterIsMemberOfTeam = await team.isMember(teamId, requesterId) // Is the requester part of this team?
105-
requesterIsMemberOfOrg = await org.isMember(associatedOrg.organization_id, requesterId)
122+
requesterIsMemberOfOrg = await org.isMemberOrStaff(associatedOrg.organization_id, requesterId)
123+
requesterIsManagerOfOrg = await org.isManager(associatedOrg.organization_id, requesterId)
106124
requesterIsOwnerOfOrg = await org.isOwner(associatedOrg.organization_id, requesterId)
107125

108126
if (isUserModerator || requesterIsOwnerOfOrg) {
@@ -128,6 +146,12 @@ async function getTeamProfile (req, reply) {
128146
}
129147
break
130148
}
149+
case 'org_staff': {
150+
if (requesterIsOwnerOfOrg || requesterIsManagerOfOrg) {
151+
visibleKeys.push(key)
152+
}
153+
break
154+
}
131155
case 'org': {
132156
if (requesterIsMemberOfOrg) {
133157
visibleKeys.push(key)

components/profile-attribute-form.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ export default function ProfileAttributeForm ({ onSubmit, initialValues = defaul
4646
const addAttributeText = `Submit ${isSubmitting ? ' 🕙' : ''}`
4747
let typeOption = <option value='team'>Team</option>
4848
if (formType === 'org') {
49-
typeOption = <option value='org'>Organization</option>
49+
typeOption = <>
50+
<option value='org'>Organization</option>
51+
<option value='org_staff'>Organization Staff</option>
52+
</>
5053
}
5154

5255
return (

0 commit comments

Comments
 (0)