mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat: add endpoints to list all authed external apps (#10944)
* feat: add endpoints to list all authed external apps Listing the apps allows users to auth to external apps without going through the create workspace flow.
This commit is contained in:
@ -10,6 +10,7 @@ import (
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/database/db2sdk"
|
||||
"github.com/coder/coder/v2/coderd/database/dbtime"
|
||||
"github.com/coder/coder/v2/coderd/externalauth"
|
||||
"github.com/coder/coder/v2/coderd/httpapi"
|
||||
@ -20,8 +21,8 @@ import (
|
||||
// @Summary Get external auth by ID
|
||||
// @ID get-external-auth-by-id
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Git
|
||||
// @Produce json
|
||||
// @Param externalauth path string true "Git Provider ID" format(string)
|
||||
// @Success 200 {object} codersdk.ExternalAuth
|
||||
// @Router /external-auth/{externalauth} [get]
|
||||
@ -77,6 +78,39 @@ func (api *API) externalAuthByID(w http.ResponseWriter, r *http.Request) {
|
||||
httpapi.Write(ctx, w, http.StatusOK, res)
|
||||
}
|
||||
|
||||
// deleteExternalAuthByID only deletes the link on the Coder side, does not revoke the token on the provider side.
|
||||
//
|
||||
// @Summary Delete external auth user link by ID
|
||||
// @ID delete-external-auth-user-link-by-id
|
||||
// @Security CoderSessionToken
|
||||
// @Tags Git
|
||||
// @Success 200
|
||||
// @Param externalauth path string true "Git Provider ID" format(string)
|
||||
// @Router /external-auth/{externalauth} [delete]
|
||||
func (api *API) deleteExternalAuthByID(w http.ResponseWriter, r *http.Request) {
|
||||
config := httpmw.ExternalAuthParam(r)
|
||||
apiKey := httpmw.APIKey(r)
|
||||
ctx := r.Context()
|
||||
|
||||
err := api.Database.DeleteExternalAuthLink(ctx, database.DeleteExternalAuthLinkParams{
|
||||
ProviderID: config.ID,
|
||||
UserID: apiKey.UserID,
|
||||
})
|
||||
if err != nil {
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.ResourceNotFound(w)
|
||||
return
|
||||
}
|
||||
httpapi.Write(ctx, w, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Failed to delete external auth link.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, w, http.StatusOK, "OK")
|
||||
}
|
||||
|
||||
// @Summary Post external auth device by ID
|
||||
// @ID post-external-auth-device-by-id
|
||||
// @Security CoderSessionToken
|
||||
@ -275,3 +309,64 @@ func (api *API) externalAuthCallback(externalAuthConfig *externalauth.Config) ht
|
||||
http.Redirect(rw, r, redirect, http.StatusTemporaryRedirect)
|
||||
}
|
||||
}
|
||||
|
||||
// listUserExternalAuths lists all external auths available to a user and
|
||||
// their auth links if they exist.
|
||||
//
|
||||
// @Summary Get user external auths
|
||||
// @ID get-user-external-auths
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Git
|
||||
// @Success 200 {object} codersdk.ExternalAuthLink
|
||||
// @Router /external-auth [get]
|
||||
func (api *API) listUserExternalAuths(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
key := httpmw.APIKey(r)
|
||||
|
||||
links, err := api.Database.GetExternalAuthLinksByUserID(ctx, key.UserID)
|
||||
if err != nil {
|
||||
if httpapi.Is404Error(err) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error fetching user's external auths.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Note: It would be really nice if we could cfg.Validate() the links and
|
||||
// return their authenticated status. To do this, we would also have to
|
||||
// refresh expired tokens too. For now, I do not want to cause the excess
|
||||
// traffic on this request, so the user will have to do this with a separate
|
||||
// call.
|
||||
httpapi.Write(ctx, rw, http.StatusOK, codersdk.ListUserExternalAuthResponse{
|
||||
Providers: ExternalAuthConfigs(api.ExternalAuthConfigs),
|
||||
Links: db2sdk.ExternalAuths(links),
|
||||
})
|
||||
}
|
||||
|
||||
func ExternalAuthConfigs(auths []*externalauth.Config) []codersdk.ExternalAuthLinkProvider {
|
||||
out := make([]codersdk.ExternalAuthLinkProvider, 0, len(auths))
|
||||
for _, auth := range auths {
|
||||
if auth == nil {
|
||||
continue
|
||||
}
|
||||
out = append(out, ExternalAuthConfig(auth))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func ExternalAuthConfig(cfg *externalauth.Config) codersdk.ExternalAuthLinkProvider {
|
||||
return codersdk.ExternalAuthLinkProvider{
|
||||
ID: cfg.ID,
|
||||
Type: cfg.Type,
|
||||
Device: cfg.DeviceAuth != nil,
|
||||
DisplayName: cfg.DisplayName,
|
||||
DisplayIcon: cfg.DisplayIcon,
|
||||
AllowRefresh: !cfg.NoRefresh,
|
||||
AllowValidate: cfg.ValidateURL != "",
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user