Skip to content

Commit 8d51623

Browse files
committed
feat: add endpoints to oauth2 provider applications
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).
1 parent fa99f6a commit 8d51623

File tree

10 files changed

+194
-32
lines changed

10 files changed

+194
-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+
// Included in app response for easier discovery. The O~uth spec does not have
19+
// a defined place to find these (for comparison, OIDC has a
20+
// '/.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

+43-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,35 @@ 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>
144+
Client ID
145+
</dt>
146+
<dd>
147+
<CopyableValue value={app.id}>
148+
{app.id}{" "}
149+
<CopyIcon css={{ width: 16, height: 16 }} />
150+
</CopyableValue>
151+
</dd>
152+
<dt>
153+
Authorization URL
154+
</dt>
155+
<dd>
156+
<CopyableValue value={app.endpoints.authorization}>
157+
{app.endpoints.authorization}{" "}
158+
<CopyIcon css={{ width: 16, height: 16 }} />
159+
</CopyableValue>
160+
</dd>
161+
<dt>
162+
Token URL
163+
</dt>
164+
<dd>
165+
<CopyableValue value={app.endpoints.token}>
166+
{app.endpoints.token}{" "}
167+
<CopyIcon css={{ width: 16, height: 16 }} />
168+
</CopyableValue>
169+
</dd>
170+
</dl>
152171

153172
<Divider css={{ borderColor: theme.palette.divider }} />
154173

@@ -303,3 +322,16 @@ const OAuth2SecretRow: FC<OAuth2SecretRowProps> = ({
303322
</TableRow>
304323
);
305324
};
325+
326+
const styles = {
327+
dataList: {
328+
display: "grid",
329+
gridTemplateColumns: "max-content auto",
330+
"& > dt": {
331+
fontWeight: "bold",
332+
},
333+
"& > dd": {
334+
marginLeft: 10,
335+
},
336+
},
337+
} satisfies Record<string, Interpolation<Theme>>;

0 commit comments

Comments
 (0)