mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08: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:
@@ -16,6 +16,24 @@ import (
|
||||
"github.com/coder/coder/v2/provisionersdk/proto"
|
||||
)
|
||||
|
||||
func ExternalAuths(auths []database.ExternalAuthLink) []codersdk.ExternalAuthLink {
|
||||
out := make([]codersdk.ExternalAuthLink, 0, len(auths))
|
||||
for _, auth := range auths {
|
||||
out = append(out, ExternalAuth(auth))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func ExternalAuth(auth database.ExternalAuthLink) codersdk.ExternalAuthLink {
|
||||
return codersdk.ExternalAuthLink{
|
||||
ProviderID: auth.ProviderID,
|
||||
CreatedAt: auth.CreatedAt,
|
||||
UpdatedAt: auth.UpdatedAt,
|
||||
HasRefreshToken: auth.OAuthRefreshToken != "",
|
||||
Expires: auth.OAuthExpiry,
|
||||
}
|
||||
}
|
||||
|
||||
func WorkspaceBuildParameters(params []database.WorkspaceBuildParameter) []codersdk.WorkspaceBuildParameter {
|
||||
out := make([]codersdk.WorkspaceBuildParameter, len(params))
|
||||
for i, p := range params {
|
||||
|
||||
@@ -754,6 +754,13 @@ func (q *querier) DeleteCoordinator(ctx context.Context, id uuid.UUID) error {
|
||||
return q.db.DeleteCoordinator(ctx, id)
|
||||
}
|
||||
|
||||
func (q *querier) DeleteExternalAuthLink(ctx context.Context, arg database.DeleteExternalAuthLinkParams) error {
|
||||
return deleteQ(q.log, q.auth, func(ctx context.Context, arg database.DeleteExternalAuthLinkParams) (database.ExternalAuthLink, error) {
|
||||
//nolint:gosimple
|
||||
return q.db.GetExternalAuthLink(ctx, database.GetExternalAuthLinkParams{UserID: arg.UserID, ProviderID: arg.ProviderID})
|
||||
}, q.db.DeleteExternalAuthLink)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) DeleteGitSSHKey(ctx context.Context, userID uuid.UUID) error {
|
||||
return deleteQ(q.log, q.auth, q.db.GetGitSSHKey, q.db.DeleteGitSSHKey)(ctx, userID)
|
||||
}
|
||||
@@ -996,10 +1003,7 @@ func (q *querier) GetExternalAuthLink(ctx context.Context, arg database.GetExter
|
||||
}
|
||||
|
||||
func (q *querier) GetExternalAuthLinksByUserID(ctx context.Context, userID uuid.UUID) ([]database.ExternalAuthLink, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetExternalAuthLinksByUserID(ctx, userID)
|
||||
return fetchWithPostFilter(q.auth, q.db.GetExternalAuthLinksByUserID)(ctx, userID)
|
||||
}
|
||||
|
||||
func (q *querier) GetFileByHashAndCreator(ctx context.Context, arg database.GetFileByHashAndCreatorParams) (database.File, error) {
|
||||
|
||||
@@ -1027,6 +1027,29 @@ func (*FakeQuerier) DeleteCoordinator(context.Context, uuid.UUID) error {
|
||||
return ErrUnimplemented
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) DeleteExternalAuthLink(_ context.Context, arg database.DeleteExternalAuthLinkParams) error {
|
||||
err := validateDatabaseType(arg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for index, key := range q.externalAuthLinks {
|
||||
if key.UserID != arg.UserID {
|
||||
continue
|
||||
}
|
||||
if key.ProviderID != arg.ProviderID {
|
||||
continue
|
||||
}
|
||||
q.externalAuthLinks[index] = q.externalAuthLinks[len(q.externalAuthLinks)-1]
|
||||
q.externalAuthLinks = q.externalAuthLinks[:len(q.externalAuthLinks)-1]
|
||||
return nil
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) DeleteGitSSHKey(_ context.Context, userID uuid.UUID) error {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
@@ -176,6 +176,13 @@ func (m metricsStore) DeleteCoordinator(ctx context.Context, id uuid.UUID) error
|
||||
return m.s.DeleteCoordinator(ctx, id)
|
||||
}
|
||||
|
||||
func (m metricsStore) DeleteExternalAuthLink(ctx context.Context, arg database.DeleteExternalAuthLinkParams) error {
|
||||
start := time.Now()
|
||||
r0 := m.s.DeleteExternalAuthLink(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("DeleteExternalAuthLink").Observe(time.Since(start).Seconds())
|
||||
return r0
|
||||
}
|
||||
|
||||
func (m metricsStore) DeleteGitSSHKey(ctx context.Context, userID uuid.UUID) error {
|
||||
start := time.Now()
|
||||
err := m.s.DeleteGitSSHKey(ctx, userID)
|
||||
|
||||
@@ -238,6 +238,20 @@ func (mr *MockStoreMockRecorder) DeleteCoordinator(arg0, arg1 interface{}) *gomo
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCoordinator", reflect.TypeOf((*MockStore)(nil).DeleteCoordinator), arg0, arg1)
|
||||
}
|
||||
|
||||
// DeleteExternalAuthLink mocks base method.
|
||||
func (m *MockStore) DeleteExternalAuthLink(arg0 context.Context, arg1 database.DeleteExternalAuthLinkParams) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteExternalAuthLink", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DeleteExternalAuthLink indicates an expected call of DeleteExternalAuthLink.
|
||||
func (mr *MockStoreMockRecorder) DeleteExternalAuthLink(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteExternalAuthLink", reflect.TypeOf((*MockStore)(nil).DeleteExternalAuthLink), arg0, arg1)
|
||||
}
|
||||
|
||||
// DeleteGitSSHKey mocks base method.
|
||||
func (m *MockStore) DeleteGitSSHKey(arg0 context.Context, arg1 uuid.UUID) error {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@@ -51,6 +51,7 @@ type sqlcQuerier interface {
|
||||
DeleteAllTailnetTunnels(ctx context.Context, arg DeleteAllTailnetTunnelsParams) error
|
||||
DeleteApplicationConnectAPIKeysByUserID(ctx context.Context, userID uuid.UUID) error
|
||||
DeleteCoordinator(ctx context.Context, id uuid.UUID) error
|
||||
DeleteExternalAuthLink(ctx context.Context, arg DeleteExternalAuthLinkParams) error
|
||||
DeleteGitSSHKey(ctx context.Context, userID uuid.UUID) error
|
||||
DeleteGroupByID(ctx context.Context, id uuid.UUID) error
|
||||
DeleteGroupMemberFromGroup(ctx context.Context, arg DeleteGroupMemberFromGroupParams) error
|
||||
|
||||
@@ -788,6 +788,20 @@ func (q *sqlQuerier) RevokeDBCryptKey(ctx context.Context, activeKeyDigest strin
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteExternalAuthLink = `-- name: DeleteExternalAuthLink :exec
|
||||
DELETE FROM external_auth_links WHERE provider_id = $1 AND user_id = $2
|
||||
`
|
||||
|
||||
type DeleteExternalAuthLinkParams struct {
|
||||
ProviderID string `db:"provider_id" json:"provider_id"`
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) DeleteExternalAuthLink(ctx context.Context, arg DeleteExternalAuthLinkParams) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteExternalAuthLink, arg.ProviderID, arg.UserID)
|
||||
return err
|
||||
}
|
||||
|
||||
const getExternalAuthLink = `-- name: GetExternalAuthLink :one
|
||||
SELECT provider_id, user_id, created_at, updated_at, oauth_access_token, oauth_refresh_token, oauth_expiry, oauth_access_token_key_id, oauth_refresh_token_key_id, oauth_extra FROM external_auth_links WHERE provider_id = $1 AND user_id = $2
|
||||
`
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
-- name: GetExternalAuthLink :one
|
||||
SELECT * FROM external_auth_links WHERE provider_id = $1 AND user_id = $2;
|
||||
|
||||
-- name: DeleteExternalAuthLink :exec
|
||||
DELETE FROM external_auth_links WHERE provider_id = $1 AND user_id = $2;
|
||||
|
||||
-- name: GetExternalAuthLinksByUserID :many
|
||||
SELECT * FROM external_auth_links WHERE user_id = $1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user