1
0
mirror of synced 2026-01-26 03:06:48 -05:00

Merge pull request #24785 from github/repo-sync

repo sync
This commit is contained in:
Octomerger Bot
2023-03-30 18:35:40 -04:00
committed by GitHub
18 changed files with 146 additions and 85 deletions

View File

@@ -37,7 +37,7 @@ export default function ClientSideRedirectExceptions() {
sp.set('hash', hash.replace(/^#/, ''))
// call the anchor-redirect endpoint to get the redirect url
const response = await fetch(`/anchor-redirect?${sp.toString()}`, {
const response = await fetch(`/api/anchor-redirect?${sp.toString()}`, {
signal,
})

View File

@@ -19,10 +19,12 @@ For example, if you want your app to change the `Status` field of an issue on a
To make an API request as an installation, you must first generate an installation access token. Then, you will send the installation access token in the `Authorization` header of your subsequent API requests. You can also use {% data variables.product.company_short %}'s Octokit SDKs, which can generate an installation access token for you.
If a REST API endpoint works with a {% data variables.product.prodname_github_app %} installation access token, the REST reference documentation for that endpoint will say "Works with {% data variables.product.prodname_github_apps %}." Additionally, your app must have the required permissions to use the endpoint. For more information about the permissions required for REST API endpoints, see "[Permissions required for GitHub Apps](/rest/overview/permissions-required-for-github-apps)."
If a REST API endpoint works with a {% data variables.product.prodname_github_app %} installation access token, the REST reference documentation for that endpoint will say "Works with {% data variables.product.prodname_github_apps %}." Additionally, your app must have the required permissions to use the endpoint. For more information, see "[AUTOTITLE](/apps/creating-github-apps/creating-github-apps/choosing-permissions-for-a-github-app)."
App installations can also use the GraphQL API. Similar to the REST API, the app must have certain permissions to access objects in the GraphQL API. For GraphQL requests, you should test you app to ensure that your app has the required permissions for the GraphQL queries and mutations that you want to make.
You can also use an installation access token to authenticate for HTTP-based Git access. You app must have the "Contents" repository permission. You can then use the installation access token as the HTTP password. Replace `TOKEN` with the installation access token: `git clone https://x-access-token:TOKEN@github.com/owner/repo.git"`.
Requests made with an installation access token are sometimes called "server-to-server" requests.
For more information about authenticating as an app on behalf of a user instead of as an app installation, see "[AUTOTITLE](/apps/creating-github-apps/authenticating-with-a-github-app/identifying-and-authorizing-users-for-github-apps)".
@@ -39,7 +41,7 @@ To authenticate as an installation with an installation access token, first use
To authenticate with an installation access token, include it in the `Authorization` header of an API request. The access token will work with both the GraphQL API and the REST API.
Your app must have the required permissions to use the endpoint. For more information about the permissions required for REST API endpoints, see "[Permissions required for GitHub Apps](/rest/overview/permissions-required-for-github-apps)." For GraphQL requests, you should test your app to ensure that it has the required permissions for the GraphQL queries and mutations that you want to make.
Your app must have the required permissions to use the endpoint. For more information, see "[AUTOTITLE](/apps/creating-github-apps/creating-github-apps/choosing-permissions-for-a-github-app)."
In the following example, replace `INSTALLATION_ACCESS_TOKEN` with an installation access token:
@@ -89,7 +91,7 @@ You must install and import `octokit` in order to use the Octokit.js library. Th
1. Use an `octokit` method to make a request to the API.
Your app must have the required permissions to use the endpoint. For more information about the permissions required for REST API endpoints, see "[Permissions required for GitHub Apps](/rest/overview/permissions-required-for-github-apps)." For GraphQL requests, you should test you app to ensure that your app has the required permissions for the GraphQL queries and mutations that you want to make.
Your app must have the required permissions to use the endpoint. For more information, see "[AUTOTITLE](/apps/creating-github-apps/creating-github-apps/choosing-permissions-for-a-github-app)."
For example, to make a request to the GraphQL API:

View File

@@ -26,7 +26,7 @@ Similarly, if the request triggers a corresponding entry in the audit logs and s
To make an API request on behalf of a user, the user must authorize your app. If an app is installed on an organization that includes multiple members, each member will need to authorize the app before the app can act on their behalf. An app does not need to be installed in order for a user to authorize the app.
When a user installs an app on their account or organization, they grant the app permission to access the organization and repository resources that it requested. During the installation process, they will also see a list of user permissions that the app can request for individual users. When a user authorizes an app, they grant the app permission to act on their behalf, and they grant the user permissions that the app requested.
When a user installs an app on their account or organization, they grant the app permission to access the organization and repository resources that it requested. During the installation process, they will also see a list of account permissions that the app can request for individual users. When a user authorizes an app, they grant the app permission to act on their behalf, and they grant the account permissions that the app requested.
Once a user has authorized your app, you can generate a user access token, which is a type of OAuth token. You should send the user access token in the `Authorization` header of your subsequent API requests. For more information about prompting a user to authorize your app and generating a user access token, see "[AUTOTITLE](/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-user-access-token-for-a-github-app)."

View File

@@ -0,0 +1,69 @@
---
title: Choosing permissions for a GitHub App
shortTitle: Permissions
intro: "The permissions of a GitHub App determine what the app can do with {% data variables.product.company_short %}'s APIs and what webhooks the app can receive."
redirect_from:
- /apps/building-integrations/setting-up-and-registering-github-apps/about-permissions-for-github-apps
- /apps/building-github-apps/permissions-for-github-apps
- /apps/building-github-apps/setting-permissions-for-github-apps
- /developers/apps/setting-permissions-for-github-apps
- /developers/apps/building-github-apps/setting-permissions-for-github-apps
- /apps/creating-github-apps/creating-github-apps/setting-permissions-for-github-apps
versions:
fpt: '*'
ghes: '*'
ghae: '*'
ghec: '*'
topics:
- GitHub Apps
---
## About {% data variables.product.prodname_github_app %} permissions
{% data variables.product.prodname_github_app %}s don't have any permissions by default. When you create an app, you can select permissions for the app. The permissions that you select determine what the app can do with {% data variables.product.company_short %}'s APIs and what webhooks the app can subscribe to. You should select the minimum permissions required for the app.
App permissions are classified as repository, organization, or account permissions. Repository permissions allow your app to access resources related to repositories that are owned by the account where the app is installed. Organization permissions allow your app to access resources related to the organization where the app is installed, if it is installed on an organization account. Account permissions allow your app to access resources related to a user if the user has also authorized your app. For more information about user authorization of apps, see "[AUTOTITLE](/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-with-a-github-app-on-behalf-of-a-user)."
When a user installs an app on their account or organization, they see and grant the repository and organization permissions that the app requested. They will also see a list of account permissions that the app can request for individual users. When a user authorizes an app to act on their behalf, they will see and grant the account permissions that the app requested.
You can modify the permissions for your app at any time. When you modify the permissions, the owner of each account where the app was installed will be prompted to approve the new permissions. If the account owner does not approve the new permissions, their installation will continue to use the old permissions.
Some webhooks and API access requires "Administration" permissions. If your app requires "Administration" permissions, consider explaining this requirement on your app's homepage. This will help users understand why your app needs a high level permission.
For more information about specifying permissions during app creation, see "[AUTOTITLE](/apps/creating-github-apps/creating-github-apps/creating-a-github-app)." For more information about modifying permissions, see "[AUTOTITLE](/apps/maintaining-github-apps/editing-a-github-apps-permissions)."
## Choosing permissions for webhook access
The webhook documentation indicates whether each webhook is available to {% data variables.product.prodname_github_app %}s. For each webhook that you want to subscribe to, refer to the webhook documentation to see what permissions a {% data variables.product.prodname_github_app %} needs to subscribe to that webhook. For more information, see "[AUTOTITLE](/webhooks-and-events/webhooks/webhook-events-and-payloads)."
For example, if you want your app to subscribe to `team` events, your app must have the "Members" organization permission.
On your app settings page, the available webhook events will change as you change your app's permissions. If you did not select sufficient permissions for your app to subscribe to an event, the event will not appear as an option on your app settings page.
## Choosing permissions for REST API access
For more information about which REST API endpoints you can access with each permission, see "[AUTOTITLE](/rest/overview/permissions-required-for-github-apps)." Some endpoints may require multiple permissions, and some endpoints may require one of multiple permissions. For more information, see the documentation for the endpoint.
For example, to use the `GET /orgs/{org}/dependabot/secrets` endpoint, your app must have at least read-level permission for the "organization dependabot secrets" permission.
The success of an API request with a user access token depends on the user's permissions as well as the app's permissions. For example, if the app was granted permission to write the contents of a repository, but the user can only read the contents, then the user access token can only read the contents. The success of an API request with an installation access token only depends on the app's permissions.
If your app makes a REST API request with insufficient permissions, the API will return a `403` response.
## Choosing permissions for GraphQL API access
For GraphQL requests, you should test your app to ensure that it has the required permissions for the GraphQL queries and mutations that you want to make.
The success of an API request with a user access token depends on the user's permissions as well as the app's permissions. For example, if the app was granted permission to write the contents of a repository, but the user can only read the contents, then the user access token can only read the contents. The success of an API request with an installation access token only depends on the app's permissions.
If your app makes a GraphQL API query or mutation with insufficient permissions, the API will return a `401` response.
## Choosing permissions for Git access
If you want your app to use an installation access token to authenticate for HTTP-based Git access, you should request the "Contents" repository permission.
You can then use the installation access token as the HTTP password. Replace `TOKEN` with the installation access token:
```
git clone https://x-access-token:TOKEN@github.com/owner/repo.git"
```

View File

@@ -52,7 +52,7 @@ You can create a {% data variables.product.prodname_github_app %} owned by your
1. If you selected **Active** in the previous step, under "Webhook URL", enter the URL that {% data variables.product.company_short %} should send webhook events to. For more information, see "[AUTOTITLE](/apps/creating-github-apps/creating-github-apps/using-webhooks-with-github-apps)."
1. Optionally, if you selected **Active** in the previous step, under "Webhook secret", enter a secret token to secure your webhooks. {% data variables.product.company_short %} highly recommends that you set a webhook secret. For more information, see "[AUTOTITLE](/apps/creating-github-apps/creating-github-apps/using-webhooks-with-github-apps)."
1. If you entered a webhook URL, under "SSL verification", select whether to enable SSL verification. {% data variables.product.company_short %} highly recommends that you enable SSL verification.
1. Under "Permissions", choose the permissions that your app needs. For each permission, select the dropdown menu and click **Read-only**, **Read & write**, or **No access**. You should select the minimum permissions necessary for your app.
1. Under "Permissions", choose the permissions that your app needs. For each permission, select the dropdown menu and click **Read-only**, **Read & write**, or **No access**. You should select the minimum permissions necessary for your app. For more information, see "[AUTOTITLE](/apps/creating-github-apps/creating-github-apps/choosing-permissions-for-a-github-app)."
1. If you selected **Active** in the earlier step to indicate that your app should receive webhook events, under "Subscribe to events", select the webhook events that you want your app to receive. The permissions that you selected in the previous step determine what webhook events are available. For more information about each webhook event, see "[AUTOTITLE](/webhooks-and-events/webhooks/webhook-events-and-payloads)."
1. Under "Where can this GitHub App be installed?", select **Only on this account** or **Any account**. For more information on installation options, see "[AUTOTITLE](/apps/creating-github-apps/creating-github-apps/making-a-github-app-public-or-private)."
1. Click **Create GitHub App**.

View File

@@ -16,10 +16,11 @@ children:
- /rate-limits-for-github-apps
- /creating-a-github-app
- /using-webhooks-with-github-apps
- /setting-permissions-for-github-apps
- /choosing-permissions-for-a-github-app
- /making-a-github-app-public-or-private
- /creating-a-github-app-from-a-manifest
- /creating-a-github-app-using-url-parameters
- /creating-a-custom-badge-for-your-github-app
- /about-the-user-authorization-callback-url
---

View File

@@ -1,19 +0,0 @@
---
title: Setting permissions for GitHub Apps
intro: '{% data reusables.shortdesc.permissions_github_apps %}'
redirect_from:
- /apps/building-integrations/setting-up-and-registering-github-apps/about-permissions-for-github-apps
- /apps/building-github-apps/permissions-for-github-apps
- /apps/building-github-apps/setting-permissions-for-github-apps
- /developers/apps/setting-permissions-for-github-apps
- /developers/apps/building-github-apps/setting-permissions-for-github-apps
versions:
fpt: '*'
ghes: '*'
ghae: '*'
ghec: '*'
topics:
- GitHub Apps
shortTitle: Set permissions
---
GitHub Apps don't have any permissions by default. When you create a GitHub App, you can select the permissions it needs to access end user data. Permissions can also be added and removed. For more information, see "[AUTOTITLE](/apps/maintaining-github-apps/editing-a-github-apps-permissions)."

View File

@@ -54,7 +54,7 @@ After creating a webhook secret for your app, you will need to configure your se
## Subscribing to webhook events
You can subscribe your {% data variables.product.prodname_github_app %} to receive webhook payloads for specific events. The specific webhook events that you can select in your app settings are determined by the type of permissions you selected for your app. You will first need to select the permissions you would like your app to have, and then you can subscribe your app to webhook events that are related to that set of permissions.
You can subscribe your {% data variables.product.prodname_github_app %} to receive webhook payloads for specific events. The specific webhook events that you can select in your app settings are determined by the type of permissions you selected for your app. You will first need to select the permissions you would like your app to have, and then you can subscribe your app to webhook events that are related to that set of permissions. For more information, see "[AUTOTITLE](/apps/creating-github-apps/creating-github-apps/choosing-permissions-for-a-github-app)."
For example, if you would like your app to receive a webhook event payload whenever a new issue is opened in your repository, you would first need to give your app permission to access "Issues" under "Repository permissions." Then under "Subscribe to events" you can select "Issues."

View File

@@ -26,7 +26,7 @@ shortTitle: Edit permissions
{% data reusables.user-settings.github_apps %}
{% data reusables.user-settings.modify_github_app %}
5. In the {% data variables.product.prodname_github_apps %} settings sidebar, click **Permissions & events**.
6. Under "Repository permissions", "Organization permissions", and "Account permissions" sections, modify the permissions you'd like to change. For each type of permission, select either "Read-only", "Read and write", or "No access" from the dropdown.
6. Under "Repository permissions", "Organization permissions", and "Account permissions" sections, modify the permissions you'd like to change. For each type of permission, select either "Read-only", "Read and write", or "No access" from the dropdown. For more information, see "[AUTOTITLE](/apps/creating-github-apps/creating-github-apps/choosing-permissions-for-a-github-app)."
7. Under "Subscribe to events", select any events to which you'd like to subscribe your app.
8. Optionally, under "Add a note to users", add a note telling your users why you are changing the permissions that your GitHub App requests.
9. Click **Save changes**.

View File

@@ -1 +0,0 @@
When you create a GitHub App, you set the permissions that define the resources the app can access via the REST API.

View File

@@ -2,6 +2,7 @@ import express from 'express'
import { createProxyMiddleware } from 'http-proxy-middleware'
import events from '../../src/events/middleware.js'
import anchorRedirect from '../../src/rest/api/anchor-redirect.js'
import search from './search.js'
import webhooks from './webhooks.js'
@@ -9,6 +10,7 @@ const router = express.Router()
router.use('/events', events)
router.use('/webhooks', webhooks)
router.use('/anchor-redirect', anchorRedirect)
// The purpose of this is for convenience to everyone who runs this code
// base locally but don't have an Elasticsearch server locally.

View File

@@ -29,7 +29,6 @@ import blockRobots from './block-robots.js'
import archivedEnterpriseVersionsAssets from './archived-enterprise-versions-assets.js'
import api from './api/index.js'
import healthz from './healthz.js'
import anchorRedirect from './anchor-redirect.js'
import productIcons from './product-icons.js'
import remoteIP from './remote-ip.js'
import buildInfo from './build-info.js'
@@ -240,7 +239,6 @@ export default function (app) {
// *** Rendering, 2xx responses ***
app.use('/api', instrument(api, './api'))
app.use('/anchor-redirect', instrument(anchorRedirect, './anchor-redirect'))
app.get('/_ip', instrument(remoteIP, './remoteIP'))
app.get('/_build', instrument(buildInfo, './buildInfo'))
app.use('/producticons', instrument(productIcons, './product-icons'))

View File

@@ -0,0 +1,45 @@
import { jest, test } from '@jest/globals'
import { readdirSync, readFileSync } from 'fs'
import path from 'path'
import { get } from '../../../tests/helpers/e2etest.js'
import { REST_DATA_DIR, REST_SCHEMA_FILENAME } from '../../rest/lib/index.js'
// TODO: Change to test every automated page, not just rest
describe('REST references docs', () => {
jest.setTimeout(3 * 60 * 1000)
test('all category and subcategory REST pages render for free-pro-team', async () => {
// This currently just grabs the 'free-pro-team' schema, but ideally, we'd
// get a list of all categories across all versions.
const freeProTeamVersion = readdirSync(REST_DATA_DIR)
.filter((file) => file.startsWith('fpt'))
.shift()
const freeProTeamSchema = JSON.parse(
readFileSync(path.join(REST_DATA_DIR, freeProTeamVersion, REST_SCHEMA_FILENAME), 'utf8')
)
const restCategories = Object.entries(freeProTeamSchema)
.map(([key, subCategory]) => {
const subCategoryKeys = Object.keys(subCategory)
if (subCategoryKeys.length === 1) {
return key
} else {
return subCategoryKeys.map((elem) => `${key}/${elem}`)
}
})
.flat()
const statusCodes = await Promise.all(
restCategories.map(async (page) => {
const url = `/en/rest/${page}`
const res = await get(url)
return [url, res.statusCode]
})
)
for (const [url, status] of statusCodes) {
expect(status, url).toBe(200)
}
expect.assertions(restCategories.length)
})
})

View File

@@ -1,9 +1,9 @@
import express from 'express'
import path from 'path'
import { readCompressedJsonFileFallbackLazily } from '../lib/read-json-file.js'
import { defaultCacheControl } from './cache-control.js'
import { REST_DATA_DIR } from '../src/rest/lib/index.js'
import { readCompressedJsonFileFallbackLazily } from '../../../lib/read-json-file.js'
import { defaultCacheControl } from '../../../middleware/cache-control.js'
import { REST_DATA_DIR } from '../lib/index.js'
const clientSideRestAPIRedirects = readCompressedJsonFileFallbackLazily(
path.join(REST_DATA_DIR, 'client-side-rest-api-redirects.json')

View File

@@ -2,15 +2,15 @@ import fs from 'fs'
import { describe, expect } from '@jest/globals'
import { get } from '../helpers/e2etest.js'
import { get } from '../../../tests/helpers/e2etest.js'
import {
SURROGATE_ENUMS,
makeLanguageSurrogateKey,
} from '../../middleware/set-fastly-surrogate-key.js'
} from '../../../middleware/set-fastly-surrogate-key.js'
describe('anchor-redirect middleware', () => {
describe('anchor-redirect api', () => {
const clientSideRedirects = JSON.parse(
fs.readFileSync('./src/rest/data/client-side-rest-api-redirects.json', 'utf-8')
fs.readFileSync('src/rest/data/client-side-rest-api-redirects.json', 'utf-8')
)
test('returns correct redirect to url', async () => {
@@ -20,7 +20,7 @@ describe('anchor-redirect middleware', () => {
const sp = new URLSearchParams()
sp.set('path', path)
sp.set('hash', hash)
const res = await get('/anchor-redirect?' + sp)
const res = await get('/api/anchor-redirect?' + sp)
expect(res.statusCode).toBe(200)
const { to } = JSON.parse(res.text)
expect(to).toBe(value)
@@ -31,7 +31,7 @@ describe('anchor-redirect middleware', () => {
const hash = key.split('#')[1]
const sp = new URLSearchParams()
sp.set('hash', hash)
const res = await get('/anchor-redirect?' + sp)
const res = await get('/api/anchor-redirect?' + sp)
expect(res.statusCode).toBe(400)
})
test('errors when path is not passed', async () => {
@@ -40,14 +40,14 @@ describe('anchor-redirect middleware', () => {
const path = key.split('#')[0]
const sp = new URLSearchParams()
sp.set('path', path)
const res = await get('/anchor-redirect?' + sp)
const res = await get('/api/anchor-redirect?' + sp)
expect(res.statusCode).toBe(400)
})
test('unfound redirect returns undefined', async () => {
const sp = new URLSearchParams()
sp.set('path', 'foo')
sp.set('hash', 'bar')
const res = await get('/anchor-redirect?' + sp)
const res = await get('/api/anchor-redirect?' + sp)
const { to } = JSON.parse(res.text)
expect(to).toBe(undefined)
})
@@ -55,7 +55,7 @@ describe('anchor-redirect middleware', () => {
const sp = new URLSearchParams()
sp.set('path', 'foo')
sp.set('hash', 'bar')
const res = await get('/anchor-redirect?' + sp)
const res = await get('/api/anchor-redirect?' + sp)
expect(res.headers['cache-control']).toContain('public')
expect(res.headers['cache-control']).toMatch(/max-age=[1-9]/)
expect(res.headers['surrogate-control']).toContain('public')

View File

@@ -1,5 +1,5 @@
import { describe, expect } from '@jest/globals'
import getCodeSamples, { mergeExamples } from '../../src/rest/scripts/utils/create-rest-examples.js'
import getCodeSamples, { mergeExamples } from '../scripts/utils/create-rest-examples.js'
import {
operation,
noContent,
@@ -7,7 +7,7 @@ import {
noResponse,
oneToOne,
matchingTags,
} from '../fixtures/openapi-examples.js'
} from './fixtures/create-rest-examples.js'
describe('rest example requests and responses', () => {
// If there is a request with no request body parameters and all of

View File

@@ -1,50 +1,14 @@
import { jest, test } from '@jest/globals'
import { slug } from 'github-slugger'
import { readdirSync, readFileSync } from 'fs'
import path from 'path'
import { get, getDOM } from '../helpers/e2etest.js'
import getRest, { REST_DATA_DIR, REST_SCHEMA_FILENAME } from '../../src/rest/lib/index.js'
import { isApiVersioned, allVersions } from '../../lib/all-versions.js'
import { getDiffOpenAPIContentRest } from '../../src/rest/scripts/test-open-api-schema.js'
import { getDOM } from '../../../tests/helpers/e2etest.js'
import getRest from '../lib/index.js'
import { isApiVersioned, allVersions } from '../../../lib/all-versions.js'
import { getDiffOpenAPIContentRest } from '../scripts/test-open-api-schema.js'
describe('REST references docs', () => {
jest.setTimeout(3 * 60 * 1000)
test('all category and subcategory REST pages render for free-pro-team', async () => {
// This currently just grabs the 'free-pro-team' schema, but ideally, we'd
// get a list of all categories across all versions.
const freeProTeamVersion = readdirSync(REST_DATA_DIR)
.filter((file) => file.startsWith('fpt'))
.shift()
const freeProTeamSchema = JSON.parse(
readFileSync(path.join(REST_DATA_DIR, freeProTeamVersion, REST_SCHEMA_FILENAME), 'utf8')
)
const restCategories = Object.entries(freeProTeamSchema)
.map(([key, subCategory]) => {
const subCategoryKeys = Object.keys(subCategory)
if (subCategoryKeys.length === 1) {
return key
} else {
return subCategoryKeys.map((elem) => `${key}/${elem}`)
}
})
.flat()
const statusCodes = await Promise.all(
restCategories.map(async (page) => {
const url = `/en/rest/${page}`
const res = await get(url)
return [url, res.statusCode]
})
)
for (const [url, status] of statusCodes) {
expect(status, url).toBe(200)
}
expect.assertions(restCategories.length)
})
// Checks that every version of the /rest/checks
// page has every operation defined in the openapi schema.
test('loads schema data for all versions', async () => {