mirror of
https://github.com/coder/coder.git
synced 2026-10-29 17:44:33 +08:00
fix: move oauth2 routes (#12240)
* fix: move oauth2 routes From /login/oauth2/* to /oauth2/*. /login/oauth2 causes /login to no longer get served by the frontend, even if nothing is actually served on /login itself. * Add forgotten comment on delete
This commit is contained in:
Generated
+140
-140
@@ -1491,146 +1491,6 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/login/oauth2/authorize": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"CoderSessionToken": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Enterprise"
|
|
||||||
],
|
|
||||||
"summary": "OAuth2 authorization request.",
|
|
||||||
"operationId": "oauth2-authorization-request",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Client ID",
|
|
||||||
"name": "client_id",
|
|
||||||
"in": "query",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "A random unguessable string",
|
|
||||||
"name": "state",
|
|
||||||
"in": "query",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enum": [
|
|
||||||
"code"
|
|
||||||
],
|
|
||||||
"type": "string",
|
|
||||||
"description": "Response type",
|
|
||||||
"name": "response_type",
|
|
||||||
"in": "query",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Redirect here after authorization",
|
|
||||||
"name": "redirect_uri",
|
|
||||||
"in": "query"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Token scopes (currently ignored)",
|
|
||||||
"name": "scope",
|
|
||||||
"in": "query"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"302": {
|
|
||||||
"description": "Found"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/login/oauth2/tokens": {
|
|
||||||
"post": {
|
|
||||||
"produces": [
|
|
||||||
"application/json"
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Enterprise"
|
|
||||||
],
|
|
||||||
"summary": "OAuth2 token exchange.",
|
|
||||||
"operationId": "oauth2-token-exchange",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Client ID, required if grant_type=authorization_code",
|
|
||||||
"name": "client_id",
|
|
||||||
"in": "formData"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Client secret, required if grant_type=authorization_code",
|
|
||||||
"name": "client_secret",
|
|
||||||
"in": "formData"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Authorization code, required if grant_type=authorization_code",
|
|
||||||
"name": "code",
|
|
||||||
"in": "formData"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Refresh token, required if grant_type=refresh_token",
|
|
||||||
"name": "refresh_token",
|
|
||||||
"in": "formData"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enum": [
|
|
||||||
"authorization_code",
|
|
||||||
"refresh_token"
|
|
||||||
],
|
|
||||||
"type": "string",
|
|
||||||
"description": "Grant type",
|
|
||||||
"name": "grant_type",
|
|
||||||
"in": "formData",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/oauth2.Token"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"delete": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"CoderSessionToken": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tags": [
|
|
||||||
"Enterprise"
|
|
||||||
],
|
|
||||||
"summary": "Delete OAuth2 application tokens.",
|
|
||||||
"operationId": "delete-oauth2-application-tokens",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Client ID",
|
|
||||||
"name": "client_id",
|
|
||||||
"in": "query",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"204": {
|
|
||||||
"description": "No Content"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/oauth2-provider/apps": {
|
"/oauth2-provider/apps": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -1915,6 +1775,146 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/oauth2/authorize": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"CoderSessionToken": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Enterprise"
|
||||||
|
],
|
||||||
|
"summary": "OAuth2 authorization request.",
|
||||||
|
"operationId": "oauth2-authorization-request",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Client ID",
|
||||||
|
"name": "client_id",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "A random unguessable string",
|
||||||
|
"name": "state",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum": [
|
||||||
|
"code"
|
||||||
|
],
|
||||||
|
"type": "string",
|
||||||
|
"description": "Response type",
|
||||||
|
"name": "response_type",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Redirect here after authorization",
|
||||||
|
"name": "redirect_uri",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Token scopes (currently ignored)",
|
||||||
|
"name": "scope",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"302": {
|
||||||
|
"description": "Found"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/oauth2/tokens": {
|
||||||
|
"post": {
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Enterprise"
|
||||||
|
],
|
||||||
|
"summary": "OAuth2 token exchange.",
|
||||||
|
"operationId": "oauth2-token-exchange",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Client ID, required if grant_type=authorization_code",
|
||||||
|
"name": "client_id",
|
||||||
|
"in": "formData"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Client secret, required if grant_type=authorization_code",
|
||||||
|
"name": "client_secret",
|
||||||
|
"in": "formData"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Authorization code, required if grant_type=authorization_code",
|
||||||
|
"name": "code",
|
||||||
|
"in": "formData"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Refresh token, required if grant_type=refresh_token",
|
||||||
|
"name": "refresh_token",
|
||||||
|
"in": "formData"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum": [
|
||||||
|
"authorization_code",
|
||||||
|
"refresh_token"
|
||||||
|
],
|
||||||
|
"type": "string",
|
||||||
|
"description": "Grant type",
|
||||||
|
"name": "grant_type",
|
||||||
|
"in": "formData",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/oauth2.Token"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"CoderSessionToken": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Enterprise"
|
||||||
|
],
|
||||||
|
"summary": "Delete OAuth2 application tokens.",
|
||||||
|
"operationId": "delete-oauth2-application-tokens",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Client ID",
|
||||||
|
"name": "client_id",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "No Content"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/organizations": {
|
"/organizations": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
|||||||
Generated
+127
-127
@@ -1291,133 +1291,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/login/oauth2/authorize": {
|
|
||||||
"post": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"CoderSessionToken": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tags": ["Enterprise"],
|
|
||||||
"summary": "OAuth2 authorization request.",
|
|
||||||
"operationId": "oauth2-authorization-request",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Client ID",
|
|
||||||
"name": "client_id",
|
|
||||||
"in": "query",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "A random unguessable string",
|
|
||||||
"name": "state",
|
|
||||||
"in": "query",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enum": ["code"],
|
|
||||||
"type": "string",
|
|
||||||
"description": "Response type",
|
|
||||||
"name": "response_type",
|
|
||||||
"in": "query",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Redirect here after authorization",
|
|
||||||
"name": "redirect_uri",
|
|
||||||
"in": "query"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Token scopes (currently ignored)",
|
|
||||||
"name": "scope",
|
|
||||||
"in": "query"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"302": {
|
|
||||||
"description": "Found"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/login/oauth2/tokens": {
|
|
||||||
"post": {
|
|
||||||
"produces": ["application/json"],
|
|
||||||
"tags": ["Enterprise"],
|
|
||||||
"summary": "OAuth2 token exchange.",
|
|
||||||
"operationId": "oauth2-token-exchange",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Client ID, required if grant_type=authorization_code",
|
|
||||||
"name": "client_id",
|
|
||||||
"in": "formData"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Client secret, required if grant_type=authorization_code",
|
|
||||||
"name": "client_secret",
|
|
||||||
"in": "formData"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Authorization code, required if grant_type=authorization_code",
|
|
||||||
"name": "code",
|
|
||||||
"in": "formData"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Refresh token, required if grant_type=refresh_token",
|
|
||||||
"name": "refresh_token",
|
|
||||||
"in": "formData"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enum": ["authorization_code", "refresh_token"],
|
|
||||||
"type": "string",
|
|
||||||
"description": "Grant type",
|
|
||||||
"name": "grant_type",
|
|
||||||
"in": "formData",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"200": {
|
|
||||||
"description": "OK",
|
|
||||||
"schema": {
|
|
||||||
"$ref": "#/definitions/oauth2.Token"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"delete": {
|
|
||||||
"security": [
|
|
||||||
{
|
|
||||||
"CoderSessionToken": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tags": ["Enterprise"],
|
|
||||||
"summary": "Delete OAuth2 application tokens.",
|
|
||||||
"operationId": "delete-oauth2-application-tokens",
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"type": "string",
|
|
||||||
"description": "Client ID",
|
|
||||||
"name": "client_id",
|
|
||||||
"in": "query",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"responses": {
|
|
||||||
"204": {
|
|
||||||
"description": "No Content"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"/oauth2-provider/apps": {
|
"/oauth2-provider/apps": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -1670,6 +1543,133 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/oauth2/authorize": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"CoderSessionToken": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": ["Enterprise"],
|
||||||
|
"summary": "OAuth2 authorization request.",
|
||||||
|
"operationId": "oauth2-authorization-request",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Client ID",
|
||||||
|
"name": "client_id",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "A random unguessable string",
|
||||||
|
"name": "state",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum": ["code"],
|
||||||
|
"type": "string",
|
||||||
|
"description": "Response type",
|
||||||
|
"name": "response_type",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Redirect here after authorization",
|
||||||
|
"name": "redirect_uri",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Token scopes (currently ignored)",
|
||||||
|
"name": "scope",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"302": {
|
||||||
|
"description": "Found"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/oauth2/tokens": {
|
||||||
|
"post": {
|
||||||
|
"produces": ["application/json"],
|
||||||
|
"tags": ["Enterprise"],
|
||||||
|
"summary": "OAuth2 token exchange.",
|
||||||
|
"operationId": "oauth2-token-exchange",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Client ID, required if grant_type=authorization_code",
|
||||||
|
"name": "client_id",
|
||||||
|
"in": "formData"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Client secret, required if grant_type=authorization_code",
|
||||||
|
"name": "client_secret",
|
||||||
|
"in": "formData"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Authorization code, required if grant_type=authorization_code",
|
||||||
|
"name": "code",
|
||||||
|
"in": "formData"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Refresh token, required if grant_type=refresh_token",
|
||||||
|
"name": "refresh_token",
|
||||||
|
"in": "formData"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enum": ["authorization_code", "refresh_token"],
|
||||||
|
"type": "string",
|
||||||
|
"description": "Grant type",
|
||||||
|
"name": "grant_type",
|
||||||
|
"in": "formData",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/oauth2.Token"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"CoderSessionToken": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": ["Enterprise"],
|
||||||
|
"summary": "Delete OAuth2 application tokens.",
|
||||||
|
"operationId": "delete-oauth2-application-tokens",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Client ID",
|
||||||
|
"name": "client_id",
|
||||||
|
"in": "query",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "No Content"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/organizations": {
|
"/organizations": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
|
|||||||
@@ -236,10 +236,10 @@ func OAuth2ProviderApp(accessURL *url.URL, dbApp database.OAuth2ProviderApp) cod
|
|||||||
Icon: dbApp.Icon,
|
Icon: dbApp.Icon,
|
||||||
Endpoints: codersdk.OAuth2AppEndpoints{
|
Endpoints: codersdk.OAuth2AppEndpoints{
|
||||||
Authorization: accessURL.ResolveReference(&url.URL{
|
Authorization: accessURL.ResolveReference(&url.URL{
|
||||||
Path: "/login/oauth2/authorize",
|
Path: "/oauth2/authorize",
|
||||||
}).String(),
|
}).String(),
|
||||||
Token: accessURL.ResolveReference(&url.URL{
|
Token: accessURL.ResolveReference(&url.URL{
|
||||||
Path: "/login/oauth2/tokens",
|
Path: "/oauth2/tokens",
|
||||||
}).String(),
|
}).String(),
|
||||||
// We do not currently support DeviceAuth.
|
// We do not currently support DeviceAuth.
|
||||||
DeviceAuth: "",
|
DeviceAuth: "",
|
||||||
|
|||||||
+1
-1
@@ -213,7 +213,7 @@ func (e OAuth2ProviderResponseType) Valid() bool {
|
|||||||
// RevokeOAuth2ProviderApp completely revokes an app's access for the
|
// RevokeOAuth2ProviderApp completely revokes an app's access for the
|
||||||
// authenticated user.
|
// authenticated user.
|
||||||
func (c *Client) RevokeOAuth2ProviderApp(ctx context.Context, appID uuid.UUID) error {
|
func (c *Client) RevokeOAuth2ProviderApp(ctx context.Context, appID uuid.UUID) error {
|
||||||
res, err := c.Request(ctx, http.MethodDelete, "/login/oauth2/tokens", nil, func(r *http.Request) {
|
res, err := c.Request(ctx, http.MethodDelete, "/oauth2/tokens", nil, func(r *http.Request) {
|
||||||
q := r.URL.Query()
|
q := r.URL.Query()
|
||||||
q.Set("client_id", appID.String())
|
q.Set("client_id", appID.String())
|
||||||
r.URL.RawQuery = q.Encode()
|
r.URL.RawQuery = q.Encode()
|
||||||
|
|||||||
Generated
+121
-121
@@ -534,127 +534,6 @@ curl -X DELETE http://coder-server:8080/api/v2/licenses/{id} \
|
|||||||
|
|
||||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||||
|
|
||||||
## OAuth2 authorization request.
|
|
||||||
|
|
||||||
### Code samples
|
|
||||||
|
|
||||||
```shell
|
|
||||||
# Example request using curl
|
|
||||||
curl -X POST http://coder-server:8080/api/v2/login/oauth2/authorize?client_id=string&state=string&response_type=code \
|
|
||||||
-H 'Coder-Session-Token: API_KEY'
|
|
||||||
```
|
|
||||||
|
|
||||||
`POST /login/oauth2/authorize`
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
| Name | In | Type | Required | Description |
|
|
||||||
| --------------- | ----- | ------ | -------- | --------------------------------- |
|
|
||||||
| `client_id` | query | string | true | Client ID |
|
|
||||||
| `state` | query | string | true | A random unguessable string |
|
|
||||||
| `response_type` | query | string | true | Response type |
|
|
||||||
| `redirect_uri` | query | string | false | Redirect here after authorization |
|
|
||||||
| `scope` | query | string | false | Token scopes (currently ignored) |
|
|
||||||
|
|
||||||
#### Enumerated Values
|
|
||||||
|
|
||||||
| Parameter | Value |
|
|
||||||
| --------------- | ------ |
|
|
||||||
| `response_type` | `code` |
|
|
||||||
|
|
||||||
### Responses
|
|
||||||
|
|
||||||
| Status | Meaning | Description | Schema |
|
|
||||||
| ------ | ---------------------------------------------------------- | ----------- | ------ |
|
|
||||||
| 302 | [Found](https://tools.ietf.org/html/rfc7231#section-6.4.3) | Found | |
|
|
||||||
|
|
||||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
|
||||||
|
|
||||||
## OAuth2 token exchange.
|
|
||||||
|
|
||||||
### Code samples
|
|
||||||
|
|
||||||
```shell
|
|
||||||
# Example request using curl
|
|
||||||
curl -X POST http://coder-server:8080/api/v2/login/oauth2/tokens \
|
|
||||||
-H 'Accept: application/json'
|
|
||||||
```
|
|
||||||
|
|
||||||
`POST /login/oauth2/tokens`
|
|
||||||
|
|
||||||
> Body parameter
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
client_id: string
|
|
||||||
client_secret: string
|
|
||||||
code: string
|
|
||||||
refresh_token: string
|
|
||||||
grant_type: authorization_code
|
|
||||||
```
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
| Name | In | Type | Required | Description |
|
|
||||||
| ----------------- | ---- | ------ | -------- | ------------------------------------------------------------- |
|
|
||||||
| `body` | body | object | false | |
|
|
||||||
| `» client_id` | body | string | false | Client ID, required if grant_type=authorization_code |
|
|
||||||
| `» client_secret` | body | string | false | Client secret, required if grant_type=authorization_code |
|
|
||||||
| `» code` | body | string | false | Authorization code, required if grant_type=authorization_code |
|
|
||||||
| `» refresh_token` | body | string | false | Refresh token, required if grant_type=refresh_token |
|
|
||||||
| `» grant_type` | body | string | true | Grant type |
|
|
||||||
|
|
||||||
#### Enumerated Values
|
|
||||||
|
|
||||||
| Parameter | Value |
|
|
||||||
| -------------- | -------------------- |
|
|
||||||
| `» grant_type` | `authorization_code` |
|
|
||||||
| `» grant_type` | `refresh_token` |
|
|
||||||
|
|
||||||
### Example responses
|
|
||||||
|
|
||||||
> 200 Response
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"access_token": "string",
|
|
||||||
"expiry": "string",
|
|
||||||
"refresh_token": "string",
|
|
||||||
"token_type": "string"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Responses
|
|
||||||
|
|
||||||
| Status | Meaning | Description | Schema |
|
|
||||||
| ------ | ------------------------------------------------------- | ----------- | -------------------------------------- |
|
|
||||||
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [oauth2.Token](schemas.md#oauth2token) |
|
|
||||||
|
|
||||||
## Delete OAuth2 application tokens.
|
|
||||||
|
|
||||||
### Code samples
|
|
||||||
|
|
||||||
```shell
|
|
||||||
# Example request using curl
|
|
||||||
curl -X DELETE http://coder-server:8080/api/v2/login/oauth2/tokens?client_id=string \
|
|
||||||
-H 'Coder-Session-Token: API_KEY'
|
|
||||||
```
|
|
||||||
|
|
||||||
`DELETE /login/oauth2/tokens`
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
| Name | In | Type | Required | Description |
|
|
||||||
| ----------- | ----- | ------ | -------- | ----------- |
|
|
||||||
| `client_id` | query | string | true | Client ID |
|
|
||||||
|
|
||||||
### Responses
|
|
||||||
|
|
||||||
| Status | Meaning | Description | Schema |
|
|
||||||
| ------ | --------------------------------------------------------------- | ----------- | ------ |
|
|
||||||
| 204 | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content | |
|
|
||||||
|
|
||||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
|
||||||
|
|
||||||
## Get OAuth2 applications.
|
## Get OAuth2 applications.
|
||||||
|
|
||||||
### Code samples
|
### Code samples
|
||||||
@@ -1031,6 +910,127 @@ curl -X DELETE http://coder-server:8080/api/v2/oauth2-provider/apps/{app}/secret
|
|||||||
|
|
||||||
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||||
|
|
||||||
|
## OAuth2 authorization request.
|
||||||
|
|
||||||
|
### Code samples
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Example request using curl
|
||||||
|
curl -X POST http://coder-server:8080/api/v2/oauth2/authorize?client_id=string&state=string&response_type=code \
|
||||||
|
-H 'Coder-Session-Token: API_KEY'
|
||||||
|
```
|
||||||
|
|
||||||
|
`POST /oauth2/authorize`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
| Name | In | Type | Required | Description |
|
||||||
|
| --------------- | ----- | ------ | -------- | --------------------------------- |
|
||||||
|
| `client_id` | query | string | true | Client ID |
|
||||||
|
| `state` | query | string | true | A random unguessable string |
|
||||||
|
| `response_type` | query | string | true | Response type |
|
||||||
|
| `redirect_uri` | query | string | false | Redirect here after authorization |
|
||||||
|
| `scope` | query | string | false | Token scopes (currently ignored) |
|
||||||
|
|
||||||
|
#### Enumerated Values
|
||||||
|
|
||||||
|
| Parameter | Value |
|
||||||
|
| --------------- | ------ |
|
||||||
|
| `response_type` | `code` |
|
||||||
|
|
||||||
|
### Responses
|
||||||
|
|
||||||
|
| Status | Meaning | Description | Schema |
|
||||||
|
| ------ | ---------------------------------------------------------- | ----------- | ------ |
|
||||||
|
| 302 | [Found](https://tools.ietf.org/html/rfc7231#section-6.4.3) | Found | |
|
||||||
|
|
||||||
|
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||||
|
|
||||||
|
## OAuth2 token exchange.
|
||||||
|
|
||||||
|
### Code samples
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Example request using curl
|
||||||
|
curl -X POST http://coder-server:8080/api/v2/oauth2/tokens \
|
||||||
|
-H 'Accept: application/json'
|
||||||
|
```
|
||||||
|
|
||||||
|
`POST /oauth2/tokens`
|
||||||
|
|
||||||
|
> Body parameter
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
client_id: string
|
||||||
|
client_secret: string
|
||||||
|
code: string
|
||||||
|
refresh_token: string
|
||||||
|
grant_type: authorization_code
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
| Name | In | Type | Required | Description |
|
||||||
|
| ----------------- | ---- | ------ | -------- | ------------------------------------------------------------- |
|
||||||
|
| `body` | body | object | false | |
|
||||||
|
| `» client_id` | body | string | false | Client ID, required if grant_type=authorization_code |
|
||||||
|
| `» client_secret` | body | string | false | Client secret, required if grant_type=authorization_code |
|
||||||
|
| `» code` | body | string | false | Authorization code, required if grant_type=authorization_code |
|
||||||
|
| `» refresh_token` | body | string | false | Refresh token, required if grant_type=refresh_token |
|
||||||
|
| `» grant_type` | body | string | true | Grant type |
|
||||||
|
|
||||||
|
#### Enumerated Values
|
||||||
|
|
||||||
|
| Parameter | Value |
|
||||||
|
| -------------- | -------------------- |
|
||||||
|
| `» grant_type` | `authorization_code` |
|
||||||
|
| `» grant_type` | `refresh_token` |
|
||||||
|
|
||||||
|
### Example responses
|
||||||
|
|
||||||
|
> 200 Response
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"access_token": "string",
|
||||||
|
"expiry": "string",
|
||||||
|
"refresh_token": "string",
|
||||||
|
"token_type": "string"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Responses
|
||||||
|
|
||||||
|
| Status | Meaning | Description | Schema |
|
||||||
|
| ------ | ------------------------------------------------------- | ----------- | -------------------------------------- |
|
||||||
|
| 200 | [OK](https://tools.ietf.org/html/rfc7231#section-6.3.1) | OK | [oauth2.Token](schemas.md#oauth2token) |
|
||||||
|
|
||||||
|
## Delete OAuth2 application tokens.
|
||||||
|
|
||||||
|
### Code samples
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# Example request using curl
|
||||||
|
curl -X DELETE http://coder-server:8080/api/v2/oauth2/tokens?client_id=string \
|
||||||
|
-H 'Coder-Session-Token: API_KEY'
|
||||||
|
```
|
||||||
|
|
||||||
|
`DELETE /oauth2/tokens`
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
|
||||||
|
| Name | In | Type | Required | Description |
|
||||||
|
| ----------- | ----- | ------ | -------- | ----------- |
|
||||||
|
| `client_id` | query | string | true | Client ID |
|
||||||
|
|
||||||
|
### Responses
|
||||||
|
|
||||||
|
| Status | Meaning | Description | Schema |
|
||||||
|
| ------ | --------------------------------------------------------------- | ----------- | ------ |
|
||||||
|
| 204 | [No Content](https://tools.ietf.org/html/rfc7231#section-6.3.5) | No Content | |
|
||||||
|
|
||||||
|
To perform this operation, you must be authenticated. [Learn more](authentication.md).
|
||||||
|
|
||||||
## Get groups by organization
|
## Get groups by organization
|
||||||
|
|
||||||
### Code samples
|
### Code samples
|
||||||
|
|||||||
+17
-16
@@ -168,24 +168,25 @@ func New(ctx context.Context, options *Options) (_ *API, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
api.AGPL.RootHandler.Group(func(r chi.Router) {
|
api.AGPL.RootHandler.Group(func(r chi.Router) {
|
||||||
r.Use(
|
|
||||||
api.oAuth2ProviderMiddleware,
|
|
||||||
// Fetch the app as system because in the /tokens route there will be no
|
|
||||||
// authenticated user.
|
|
||||||
httpmw.AsAuthzSystem(httpmw.ExtractOAuth2ProviderApp(options.Database)),
|
|
||||||
)
|
|
||||||
// Oauth2 linking routes do not make sense under the /api/v2 path.
|
// Oauth2 linking routes do not make sense under the /api/v2 path.
|
||||||
r.Route("/login", func(r chi.Router) {
|
r.Route("/oauth2", func(r chi.Router) {
|
||||||
r.Route("/oauth2", func(r chi.Router) {
|
r.Use(
|
||||||
r.Group(func(r chi.Router) {
|
api.oAuth2ProviderMiddleware,
|
||||||
r.Use(apiKeyMiddleware)
|
// Fetch the app as system because in the /tokens route there will be no
|
||||||
r.Get("/authorize", api.postOAuth2ProviderAppAuthorize())
|
// authenticated user.
|
||||||
r.Delete("/tokens", api.deleteOAuth2ProviderAppTokens())
|
httpmw.AsAuthzSystem(httpmw.ExtractOAuth2ProviderApp(options.Database)),
|
||||||
})
|
)
|
||||||
// The /tokens endpoint will be called from an unauthorized client so we
|
r.Group(func(r chi.Router) {
|
||||||
// cannot require an API key.
|
r.Use(apiKeyMiddleware)
|
||||||
r.Post("/tokens", api.postOAuth2ProviderAppToken())
|
r.Get("/authorize", api.postOAuth2ProviderAppAuthorize())
|
||||||
|
// DELETE on /tokens is not part of the OAuth2 spec. It is our own
|
||||||
|
// route used to revoke permissions from an application. It is here for
|
||||||
|
// parity with POST on /tokens.
|
||||||
|
r.Delete("/tokens", api.deleteOAuth2ProviderAppTokens())
|
||||||
})
|
})
|
||||||
|
// The /tokens endpoint will be called from an unauthorized client so we
|
||||||
|
// cannot require an API key.
|
||||||
|
r.Post("/tokens", api.postOAuth2ProviderAppToken())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ func authorizeMW(accessURL *url.URL) func(next http.Handler) http.Handler {
|
|||||||
// a minimum in order to detect whether "allow" has been pressed, however.
|
// a minimum in order to detect whether "allow" has been pressed, however.
|
||||||
cameFromSelf := (origin == "" || originU.Hostname() == accessURL.Hostname()) &&
|
cameFromSelf := (origin == "" || originU.Hostname() == accessURL.Hostname()) &&
|
||||||
refererU.Hostname() == accessURL.Hostname() &&
|
refererU.Hostname() == accessURL.Hostname() &&
|
||||||
refererU.Path == "/login/oauth2/authorize"
|
refererU.Path == "/oauth2/authorize"
|
||||||
|
|
||||||
// If we were redirected here from this same page it means the user
|
// If we were redirected here from this same page it means the user
|
||||||
// pressed the allow button so defer to the authorize handler which
|
// pressed the allow button so defer to the authorize handler which
|
||||||
|
|||||||
@@ -291,7 +291,7 @@ func (api *API) deleteOAuth2ProviderAppSecret(rw http.ResponseWriter, r *http.Re
|
|||||||
// @Param redirect_uri query string false "Redirect here after authorization"
|
// @Param redirect_uri query string false "Redirect here after authorization"
|
||||||
// @Param scope query string false "Token scopes (currently ignored)"
|
// @Param scope query string false "Token scopes (currently ignored)"
|
||||||
// @Success 302
|
// @Success 302
|
||||||
// @Router /login/oauth2/authorize [post]
|
// @Router /oauth2/authorize [post]
|
||||||
func (api *API) postOAuth2ProviderAppAuthorize() http.HandlerFunc {
|
func (api *API) postOAuth2ProviderAppAuthorize() http.HandlerFunc {
|
||||||
return identityprovider.Authorize(api.Database, api.AccessURL)
|
return identityprovider.Authorize(api.Database, api.AccessURL)
|
||||||
}
|
}
|
||||||
@@ -306,7 +306,7 @@ func (api *API) postOAuth2ProviderAppAuthorize() http.HandlerFunc {
|
|||||||
// @Param refresh_token formData string false "Refresh token, required if grant_type=refresh_token"
|
// @Param refresh_token formData string false "Refresh token, required if grant_type=refresh_token"
|
||||||
// @Param grant_type formData codersdk.OAuth2ProviderGrantType true "Grant type"
|
// @Param grant_type formData codersdk.OAuth2ProviderGrantType true "Grant type"
|
||||||
// @Success 200 {object} oauth2.Token
|
// @Success 200 {object} oauth2.Token
|
||||||
// @Router /login/oauth2/tokens [post]
|
// @Router /oauth2/tokens [post]
|
||||||
func (api *API) postOAuth2ProviderAppToken() http.HandlerFunc {
|
func (api *API) postOAuth2ProviderAppToken() http.HandlerFunc {
|
||||||
return identityprovider.Tokens(api.Database, api.DeploymentValues.SessionDuration.Value())
|
return identityprovider.Tokens(api.Database, api.DeploymentValues.SessionDuration.Value())
|
||||||
}
|
}
|
||||||
@@ -317,7 +317,7 @@ func (api *API) postOAuth2ProviderAppToken() http.HandlerFunc {
|
|||||||
// @Tags Enterprise
|
// @Tags Enterprise
|
||||||
// @Param client_id query string true "Client ID"
|
// @Param client_id query string true "Client ID"
|
||||||
// @Success 204
|
// @Success 204
|
||||||
// @Router /login/oauth2/tokens [delete]
|
// @Router /oauth2/tokens [delete]
|
||||||
func (api *API) deleteOAuth2ProviderAppTokens() http.HandlerFunc {
|
func (api *API) deleteOAuth2ProviderAppTokens() http.HandlerFunc {
|
||||||
return identityprovider.RevokeApp(api.Database)
|
return identityprovider.RevokeApp(api.Database)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3411,8 +3411,8 @@ export const MockOAuth2ProviderApps: TypesGen.OAuth2ProviderApp[] = [
|
|||||||
callback_url: "http://localhost:3001",
|
callback_url: "http://localhost:3001",
|
||||||
icon: "/icon/github.svg",
|
icon: "/icon/github.svg",
|
||||||
endpoints: {
|
endpoints: {
|
||||||
authorization: "http://localhost:3001/login/oauth2/authorize",
|
authorization: "http://localhost:3001/oauth2/authorize",
|
||||||
token: "http://localhost:3001/login/oauth2/token",
|
token: "http://localhost:3001/oauth2/token",
|
||||||
device_authorization: "",
|
device_authorization: "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user