Skip to content

Commit b42d33e

Browse files
authored
Update wording for fine-grained tokens on REST (#50753)
1 parent b426503 commit b42d33e

File tree

12 files changed

+5238
-5214
lines changed

12 files changed

+5238
-5214
lines changed

data/ui.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,10 @@ rest_reference:
168168
button_text:
169169
copy_to_clipboard: Copy to clipboard
170170
copied: Copied!
171-
works_with_tokens: 'This endpoint works with the following token types'
172-
permission_sets: 'The token must have at least one of the following permission sets'
173-
permission_set: 'The token must have the following permission set'
174-
no_permission_sets: 'The token does not require any permissions.'
171+
works_with_fine_grained_tokens: 'This endpoint works with the following fine-grained token types'
172+
permission_sets: 'The fine-grained token must have at least one of the following permission sets'
173+
permission_set: 'The fine-grained token must have the following permission set'
174+
no_permission_sets: 'The fine-grained token does not require any permissions.'
175175
allows_public_read_access: This endpoint can be used without authentication or the aforementioned permissions if only public resources are requested.
176176
allows_public_read_access_no_permissions: This endpoint can be used without authentication if only public resources are requested.
177177
user_access_token_name: GitHub App user access tokens

src/fixtures/fixtures/data/ui.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,10 @@ rest_reference:
168168
button_text:
169169
copy_to_clipboard: Copy to clipboard
170170
copied: Copied!
171-
works_with_tokens: 'This endpoint works with the following token types'
172-
permission_sets: 'The token must have at least one of the following permission sets'
173-
permission_set: 'The token must have the following permission set'
174-
no_permission_sets: 'The token does not require any permissions.'
171+
works_with_fine_grained_tokens: 'This endpoint works with the following fine-grained token types'
172+
permission_sets: 'The fine-grained token must have at least one of the following permission sets'
173+
permission_set: 'The fine-grained token must have the following permission set'
174+
no_permission_sets: 'The fine-grained token does not require any permissions.'
175175
allows_public_read_access: This endpoint can be used without authentication or the aforementioned permissions if only public resources are requested.
176176
allows_public_read_access_no_permissions: This endpoint can be used without authentication if only public resources are requested.
177177
user_access_token_name: GitHub App user access tokens

src/github-apps/scripts/sync.js

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,7 @@ export async function syncGitHubAppsData(openApiSource, sourceSchemas, progAcces
6464
// permissions
6565
for (const permissionSet of progAccessData[operation.operationId].permissions) {
6666
for (const [permissionName, readOrWrite] of Object.entries(permissionSet)) {
67-
const tempTitle = permissionName.replace(/_/g, ' ')
68-
const permissionNameExists = progActorResources[permissionName]
69-
if (!permissionNameExists) {
70-
console.warn(
71-
`The permission ${permissionName} is missing from config/locales/programmatic_actor_fine_grained_resources.en.yml. Creating a placeholder value of ${tempTitle} until it's added.`,
72-
)
73-
}
74-
const title = progActorResources[permissionName]?.title || tempTitle
75-
const resourceGroup = progActorResources[permissionName]?.resource_group || ''
76-
const displayTitle = getDisplayTitle(title, resourceGroup)
67+
const { title, displayTitle } = getDisplayTitle(permissionName, progActorResources)
7768
const additionalPermissions =
7869
progAccessData[operation.operationId].permissions.length > 1 ||
7970
progAccessData[operation.operationId].permissions.some(
@@ -153,7 +144,7 @@ export async function syncGitHubAppsData(openApiSource, sourceSchemas, progAcces
153144
}
154145
}
155146

156-
export async function getProgAccessData(progAccessSource) {
147+
export async function getProgAccessData(progAccessSource, isRest = false) {
157148
const useRemoteGitHubFiles = progAccessSource === 'rest-api-description'
158149
// check for required PAT
159150
if (useRemoteGitHubFiles && !process.env.GITHUB_TOKEN) {
@@ -189,14 +180,31 @@ export async function getProgAccessData(progAccessSource) {
189180
userToServerRest: operation.user_to_server.enabled,
190181
serverToServer: operation.server_to_server.enabled,
191182
fineGrainedPat: operation.user_to_server.enabled && !operation.disabled_for_patv2,
192-
permissions: operation.permission_sets || [],
183+
permissions: isRest
184+
? getDisplayPermissions(operation.permission_sets || [], progActorResources)
185+
: operation.permission_sets || [],
193186
allowPermissionlessAccess: operation.allows_permissionless_access,
194187
allowsPublicRead: operation.allows_public_read,
195188
}
196189
}
190+
197191
return { progAccessData, progActorResources }
198192
}
199193

194+
function getDisplayPermissions(permissionSets, progActorResources) {
195+
const displayPermissions = permissionSets.map((permissionSet) => {
196+
const displayPermissionSet = {}
197+
Object.entries(permissionSet).forEach(([key, value]) => {
198+
const { displayTitle } = getDisplayTitle(key, progActorResources, true)
199+
displayPermissionSet[displayTitle] = value
200+
})
201+
202+
return displayPermissionSet
203+
})
204+
205+
return displayPermissions
206+
}
207+
200208
function sortObjectByKeys(obj) {
201209
return Object.keys(obj)
202210
.sort()
@@ -223,15 +231,31 @@ function sortObjectByTitle(obj) {
223231
}, {})
224232
}
225233

226-
function getDisplayTitle(title, resourceGroup) {
234+
function getDisplayTitle(permissionName, progActorResources, isRest = false) {
235+
const tempTitle = permissionName.replace(/_/g, ' ')
236+
const permissionNameExists = progActorResources[permissionName]
237+
if (!permissionNameExists) {
238+
console.warn(
239+
`The permission ${permissionName} is missing from config/locales/programmatic_actor_fine_grained_resources.en.yml. Creating a placeholder value of ${tempTitle} until it's added.`,
240+
)
241+
}
242+
const title = progActorResources[permissionName]?.title || tempTitle
243+
const resourceGroup = progActorResources[permissionName]?.resource_group || ''
244+
227245
if (!title) {
228246
console.warn(`No title found for title ${title} resource group ${resourceGroup}`)
229247
return ''
230248
}
231249

232-
return !resourceGroup
233-
? sentenceCase(title) + ' permissions'
234-
: sentenceCase(resourceGroup) + ' permissions for ' + `"${title}"`
250+
const displayTitle = isRest
251+
? !resourceGroup
252+
? sentenceCase(title) + ' permissions'
253+
: `"${sentenceCase(title)}" ` + resourceGroup + ' permissions'
254+
: !resourceGroup
255+
? sentenceCase(title) + ' permissions'
256+
: sentenceCase(resourceGroup) + ' permissions for ' + `"${title}"`
257+
258+
return { title, displayTitle }
235259
}
236260

237261
function sentenceCase(str) {

src/rest/components/RestAuth.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,22 +54,22 @@ export function RestAuth({ progAccess, slug, heading }: Props) {
5454
? t('allows_public_read_access_no_permissions')
5555
: t('allows_public_read_access')
5656
// progAccess.permissions is an array of objects
57-
// For example: [ {'actions': 'read', 'packages': 'read'}, {'read': 'repo'} ]
57+
// For example: [ {'"Actions" repository permissions': 'read', '"Administration" organization permissions': 'write'}, {'"Secrets" organization permissions"': 'write'} ]
5858
// Each object represents a set of permissions containing one
5959
// or more key-value pairs. All permissions in a set are required.
6060
// If there is more than one set of permissions, any set can be used.
6161
const formattedPermissions = progAccess.permissions.map((permissionSet: Object, index) => {
6262
// Given the example above, the first object is now an array of tuples
63-
// [['actions', 'read'], ['packages', 'read']]
64-
// that can be formatted as a string like `actions:read` and `packages:read`
63+
// [['"Actions" repository permissions', 'read'], ['"Administration" organization permissions', 'read']]
64+
// that can be formatted as a string like `"Administration" organization permissions (write)'
6565
const permissionSetPairs = Object.entries(permissionSet)
6666
const numPermissionSetPairs = permissionSetPairs.length
6767

6868
return (
6969
<li key={`token-permissions-${index}`}>
7070
{permissionSetPairs.map(([key, value], setIndex) => (
7171
<span key={`token-permissions-text-${index}-${setIndex}`}>
72-
<code>{key + ':' + value}</code>
72+
<span>{`${key} (${value})`}</span>
7373
{setIndex < numPermissionSetPairs - 1 && <span> and </span>}
7474
</span>
7575
))}
@@ -79,7 +79,7 @@ export function RestAuth({ progAccess, slug, heading }: Props) {
7979

8080
const fineGrainedData = (
8181
<>
82-
<p>{t('works_with_tokens')}:</p>
82+
<p>{t('works_with_fine_grained_tokens')}:</p>
8383
<ul>
8484
{progAccess.userToServerRest && (
8585
<li>

0 commit comments

Comments
 (0)