Skip to content

Commit 3014777

Browse files
code-asherEmyrk
andauthored
feat: add endpoints to oauth2 provider applications (#11718)
These will show up when configuring the application along with the client ID and everything else. Should make it easier to configure the application, otherwise you will have to go look up the URLs in the docs (which are not yet written). Co-authored-by: Steven Masley <stevenmasley@gmail.com>
1 parent 8e0a153 commit 3014777

File tree

10 files changed

+187
-32
lines changed

10 files changed

+187
-32
lines changed

coderd/apidoc/docs.go

+23
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+23
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/db2sdk/db2sdk.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package db2sdk
44
import (
55
"encoding/json"
66
"fmt"
7+
"net/url"
78
"strconv"
89
"strings"
910
"time"
@@ -226,19 +227,29 @@ func templateVersionParameterOptions(rawOptions json.RawMessage) ([]codersdk.Tem
226227
return options, nil
227228
}
228229

229-
func OAuth2ProviderApp(dbApp database.OAuth2ProviderApp) codersdk.OAuth2ProviderApp {
230+
func OAuth2ProviderApp(accessURL *url.URL, dbApp database.OAuth2ProviderApp) codersdk.OAuth2ProviderApp {
230231
return codersdk.OAuth2ProviderApp{
231232
ID: dbApp.ID,
232233
Name: dbApp.Name,
233234
CallbackURL: dbApp.CallbackURL,
234235
Icon: dbApp.Icon,
236+
Endpoints: codersdk.OAuth2AppEndpoints{
237+
Authorization: accessURL.ResolveReference(&url.URL{
238+
Path: "/login/oauth2/authorize",
239+
}).String(),
240+
Token: accessURL.ResolveReference(&url.URL{
241+
Path: "/login/oauth2/tokens",
242+
}).String(),
243+
// We do not currently support DeviceAuth.
244+
DeviceAuth: "",
245+
},
235246
}
236247
}
237248

238-
func OAuth2ProviderApps(dbApps []database.OAuth2ProviderApp) []codersdk.OAuth2ProviderApp {
249+
func OAuth2ProviderApps(accessURL *url.URL, dbApps []database.OAuth2ProviderApp) []codersdk.OAuth2ProviderApp {
239250
apps := []codersdk.OAuth2ProviderApp{}
240251
for _, dbApp := range dbApps {
241-
apps = append(apps, OAuth2ProviderApp(dbApp))
252+
apps = append(apps, OAuth2ProviderApp(accessURL, dbApp))
242253
}
243254
return apps
244255
}

codersdk/oauth2.go

+12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@ type OAuth2ProviderApp struct {
1414
Name string `json:"name"`
1515
CallbackURL string `json:"callback_url"`
1616
Icon string `json:"icon"`
17+
18+
// Endpoints are included in the app response for easier discovery. The OAuth2
19+
// spec does not have a defined place to find these (for comparison, OIDC has
20+
// a '/.well-known/openid-configuration' endpoint).
21+
Endpoints OAuth2AppEndpoints `json:"endpoints"`
22+
}
23+
24+
type OAuth2AppEndpoints struct {
25+
Authorization string `json:"authorization"`
26+
Token string `json:"token"`
27+
// DeviceAuth is optional.
28+
DeviceAuth string `json:"device_authorization"`
1729
}
1830

1931
// OAuth2ProviderApps returns the applications configured to authenticate using

docs/api/enterprise.md

+31-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/api/schemas.md

+30-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

enterprise/coderd/oauth2.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func (api *API) oAuth2ProviderApps(rw http.ResponseWriter, r *http.Request) {
5454
httpapi.InternalServerError(rw, err)
5555
return
5656
}
57-
httpapi.Write(ctx, rw, http.StatusOK, db2sdk.OAuth2ProviderApps(dbApps))
57+
httpapi.Write(ctx, rw, http.StatusOK, db2sdk.OAuth2ProviderApps(api.AccessURL, dbApps))
5858
}
5959

6060
// @Summary Get OAuth2 application.
@@ -65,10 +65,10 @@ func (api *API) oAuth2ProviderApps(rw http.ResponseWriter, r *http.Request) {
6565
// @Param app path string true "App ID"
6666
// @Success 200 {object} codersdk.OAuth2ProviderApp
6767
// @Router /oauth2-provider/apps/{app} [get]
68-
func (*API) oAuth2ProviderApp(rw http.ResponseWriter, r *http.Request) {
68+
func (api *API) oAuth2ProviderApp(rw http.ResponseWriter, r *http.Request) {
6969
ctx := r.Context()
7070
app := httpmw.OAuth2ProviderApp(r)
71-
httpapi.Write(ctx, rw, http.StatusOK, db2sdk.OAuth2ProviderApp(app))
71+
httpapi.Write(ctx, rw, http.StatusOK, db2sdk.OAuth2ProviderApp(api.AccessURL, app))
7272
}
7373

7474
// @Summary Create OAuth2 application.
@@ -101,7 +101,7 @@ func (api *API) postOAuth2ProviderApp(rw http.ResponseWriter, r *http.Request) {
101101
})
102102
return
103103
}
104-
httpapi.Write(ctx, rw, http.StatusCreated, db2sdk.OAuth2ProviderApp(app))
104+
httpapi.Write(ctx, rw, http.StatusCreated, db2sdk.OAuth2ProviderApp(api.AccessURL, app))
105105
}
106106

107107
// @Summary Update OAuth2 application.
@@ -135,7 +135,7 @@ func (api *API) putOAuth2ProviderApp(rw http.ResponseWriter, r *http.Request) {
135135
})
136136
return
137137
}
138-
httpapi.Write(ctx, rw, http.StatusOK, db2sdk.OAuth2ProviderApp(app))
138+
httpapi.Write(ctx, rw, http.StatusOK, db2sdk.OAuth2ProviderApp(api.AccessURL, app))
139139
}
140140

141141
// @Summary Delete OAuth2 application.

site/src/api/typesGenerated.ts

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/src/pages/DeploySettingsPage/OAuth2AppsSettingsPage/EditOAuth2AppPageView.tsx

+36-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useTheme } from "@emotion/react";
1+
import { type Interpolation, type Theme, useTheme } from "@emotion/react";
22
import CopyIcon from "@mui/icons-material/FileCopyOutlined";
33
import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft";
44
import Divider from "@mui/material/Divider";
@@ -139,16 +139,28 @@ export const EditOAuth2AppPageView: FC<EditOAuth2AppProps> = ({
139139
onCancel={() => setShowDelete(false)}
140140
/>
141141

142-
<h2 css={{ marginBottom: 0 }}>Client ID</h2>
143-
<CopyableValue value={app.id}>
144-
{app.id}{" "}
145-
<CopyIcon
146-
css={{
147-
width: 16,
148-
height: 16,
149-
}}
150-
/>
151-
</CopyableValue>
142+
<dl css={styles.dataList}>
143+
<dt>Client ID</dt>
144+
<dd>
145+
<CopyableValue value={app.id}>
146+
{app.id} <CopyIcon css={{ width: 16, height: 16 }} />
147+
</CopyableValue>
148+
</dd>
149+
<dt>Authorization URL</dt>
150+
<dd>
151+
<CopyableValue value={app.endpoints.authorization}>
152+
{app.endpoints.authorization}{" "}
153+
<CopyIcon css={{ width: 16, height: 16 }} />
154+
</CopyableValue>
155+
</dd>
156+
<dt>Token URL</dt>
157+
<dd>
158+
<CopyableValue value={app.endpoints.token}>
159+
{app.endpoints.token}{" "}
160+
<CopyIcon css={{ width: 16, height: 16 }} />
161+
</CopyableValue>
162+
</dd>
163+
</dl>
152164

153165
<Divider css={{ borderColor: theme.palette.divider }} />
154166

@@ -303,3 +315,16 @@ const OAuth2SecretRow: FC<OAuth2SecretRowProps> = ({
303315
</TableRow>
304316
);
305317
};
318+
319+
const styles = {
320+
dataList: {
321+
display: "grid",
322+
gridTemplateColumns: "max-content auto",
323+
"& > dt": {
324+
fontWeight: "bold",
325+
},
326+
"& > dd": {
327+
marginLeft: 10,
328+
},
329+
},
330+
} satisfies Record<string, Interpolation<Theme>>;

site/src/testHelpers/entities.ts

+5
Original file line numberDiff line numberDiff line change
@@ -3371,6 +3371,11 @@ export const MockOAuth2ProviderApps: TypesGen.OAuth2ProviderApp[] = [
33713371
name: "foo",
33723372
callback_url: "http://localhost:3001",
33733373
icon: "/icon/github.svg",
3374+
endpoints: {
3375+
authorization: "http://localhost:3001/login/oauth2/authorize",
3376+
token: "http://localhost:3001/login/oauth2/token",
3377+
device_authorization: "",
3378+
},
33743379
},
33753380
];
33763381

0 commit comments

Comments
 (0)