Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd898737

Browse files
authored
feat: app sharing (now open source!) (#4378)
1 parent19d7281 commitd898737

File tree

55 files changed

+1069
-412
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1069
-412
lines changed

‎cli/tokens.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func createToken() *cobra.Command {
5555
returnxerrors.Errorf("create codersdk client: %w",err)
5656
}
5757

58-
res,err:=client.CreateToken(cmd.Context(),codersdk.Me)
58+
res,err:=client.CreateToken(cmd.Context(),codersdk.Me, codersdk.CreateTokenRequest{})
5959
iferr!=nil {
6060
returnxerrors.Errorf("create tokens: %w",err)
6161
}

‎coderd/apikey.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,23 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) {
3434
return
3535
}
3636

37+
varcreateToken codersdk.CreateTokenRequest
38+
if!httpapi.Read(ctx,rw,r,&createToken) {
39+
return
40+
}
41+
42+
scope:=database.APIKeyScopeAll
43+
ifscope!="" {
44+
scope=database.APIKeyScope(createToken.Scope)
45+
}
46+
3747
// tokens last 100 years
3848
lifeTime:=time.Hour*876000
3949
cookie,err:=api.createAPIKey(ctx,createAPIKeyParams{
4050
UserID:user.ID,
4151
LoginType:database.LoginTypeToken,
4252
ExpiresAt:database.Now().Add(lifeTime),
53+
Scope:scope,
4354
LifetimeSeconds:int64(lifeTime.Seconds()),
4455
})
4556
iferr!=nil {
@@ -54,6 +65,7 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) {
5465
}
5566

5667
// Creates a new session key, used for logging in via the CLI.
68+
// DEPRECATED: use postToken instead.
5769
func (api*API)postAPIKey(rw http.ResponseWriter,r*http.Request) {
5870
ctx:=r.Context()
5971
user:=httpmw.UserParam(r)
@@ -229,6 +241,11 @@ func (api *API) createAPIKey(ctx context.Context, params createAPIKeyParams) (*h
229241
ifparams.Scope!="" {
230242
scope=params.Scope
231243
}
244+
switchscope {
245+
casedatabase.APIKeyScopeAll,database.APIKeyScopeApplicationConnect:
246+
default:
247+
returnnil,xerrors.Errorf("invalid API key scope: %q",scope)
248+
}
232249

233250
key,err:=api.Database.InsertAPIKey(ctx, database.InsertAPIKeyParams{
234251
ID:keyID,

‎coderd/apikey_test.go

Lines changed: 52 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,30 +14,61 @@ import (
1414

1515
funcTestTokens(t*testing.T) {
1616
t.Parallel()
17-
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
18-
defercancel()
19-
client:=coderdtest.New(t,&coderdtest.Options{IncludeProvisionerDaemon:true})
20-
_=coderdtest.CreateFirstUser(t,client)
21-
keys,err:=client.GetTokens(ctx,codersdk.Me)
22-
require.NoError(t,err)
23-
require.Empty(t,keys)
2417

25-
res,err:=client.CreateToken(ctx,codersdk.Me)
26-
require.NoError(t,err)
27-
require.Greater(t,len(res.Key),2)
18+
t.Run("CRUD",func(t*testing.T) {
19+
t.Parallel()
2820

29-
keys,err=client.GetTokens(ctx,codersdk.Me)
30-
require.NoError(t,err)
31-
require.EqualValues(t,len(keys),1)
32-
require.Contains(t,res.Key,keys[0].ID)
33-
// expires_at must be greater than 50 years
34-
require.Greater(t,keys[0].ExpiresAt,time.Now().Add(time.Hour*438300))
21+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
22+
defercancel()
23+
client:=coderdtest.New(t,nil)
24+
_=coderdtest.CreateFirstUser(t,client)
25+
keys,err:=client.GetTokens(ctx,codersdk.Me)
26+
require.NoError(t,err)
27+
require.Empty(t,keys)
3528

36-
err=client.DeleteAPIKey(ctx,codersdk.Me,keys[0].ID)
37-
require.NoError(t,err)
38-
keys,err=client.GetTokens(ctx,codersdk.Me)
39-
require.NoError(t,err)
40-
require.Empty(t,keys)
29+
res,err:=client.CreateToken(ctx,codersdk.Me, codersdk.CreateTokenRequest{})
30+
require.NoError(t,err)
31+
require.Greater(t,len(res.Key),2)
32+
33+
keys,err=client.GetTokens(ctx,codersdk.Me)
34+
require.NoError(t,err)
35+
require.EqualValues(t,len(keys),1)
36+
require.Contains(t,res.Key,keys[0].ID)
37+
// expires_at must be greater than 50 years
38+
require.Greater(t,keys[0].ExpiresAt,time.Now().Add(time.Hour*438300))
39+
require.Equal(t,codersdk.APIKeyScopeAll,keys[0].Scope)
40+
41+
// no update
42+
43+
err=client.DeleteAPIKey(ctx,codersdk.Me,keys[0].ID)
44+
require.NoError(t,err)
45+
keys,err=client.GetTokens(ctx,codersdk.Me)
46+
require.NoError(t,err)
47+
require.Empty(t,keys)
48+
})
49+
50+
t.Run("Scoped",func(t*testing.T) {
51+
t.Parallel()
52+
53+
ctx,cancel:=context.WithTimeout(context.Background(),testutil.WaitLong)
54+
defercancel()
55+
client:=coderdtest.New(t,nil)
56+
_=coderdtest.CreateFirstUser(t,client)
57+
58+
res,err:=client.CreateToken(ctx,codersdk.Me, codersdk.CreateTokenRequest{
59+
Scope:codersdk.APIKeyScopeApplicationConnect,
60+
})
61+
require.NoError(t,err)
62+
require.Greater(t,len(res.Key),2)
63+
64+
keys,err:=client.GetTokens(ctx,codersdk.Me)
65+
require.NoError(t,err)
66+
require.EqualValues(t,len(keys),1)
67+
require.Contains(t,res.Key,keys[0].ID)
68+
// expires_at must be greater than 50 years
69+
require.Greater(t,keys[0].ExpiresAt,time.Now().Add(time.Hour*438300))
70+
require.Equal(t,keys[0].Scope,codersdk.APIKeyScopeApplicationConnect)
71+
})
4172
}
4273

4374
funcTestAPIKey(t*testing.T) {

‎coderd/coderd.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ func New(options *Options) *API {
197197
RedirectToLogin:false,
198198
Optional:true,
199199
}),
200-
httpmw.ExtractUserParam(api.Database),
200+
httpmw.ExtractUserParam(api.Database,false),
201201
httpmw.ExtractWorkspaceAndAgentParam(api.Database),
202202
),
203203
// Build-Version is helpful for debugging.
@@ -214,8 +214,18 @@ func New(options *Options) *API {
214214
r.Use(
215215
tracing.Middleware(api.TracerProvider),
216216
httpmw.RateLimitPerMinute(options.APIRateLimit),
217-
apiKeyMiddlewareRedirect,
218-
httpmw.ExtractUserParam(api.Database),
217+
httpmw.ExtractAPIKey(httpmw.ExtractAPIKeyConfig{
218+
DB:options.Database,
219+
OAuth2Configs:oauthConfigs,
220+
// Optional is true to allow for public apps. If an
221+
// authorization check fails and the user is not authenticated,
222+
// they will be redirected to the login page by the app handler.
223+
RedirectToLogin:false,
224+
Optional:true,
225+
}),
226+
// Redirect to the login page if the user tries to open an app with
227+
// "me" as the username and they are not logged in.
228+
httpmw.ExtractUserParam(api.Database,true),
219229
// Extracts the <workspace.agent> from the url
220230
httpmw.ExtractWorkspaceAndAgentParam(api.Database),
221231
)
@@ -310,7 +320,7 @@ func New(options *Options) *API {
310320
r.Get("/roles",api.assignableOrgRoles)
311321
r.Route("/{user}",func(r chi.Router) {
312322
r.Use(
313-
httpmw.ExtractUserParam(options.Database),
323+
httpmw.ExtractUserParam(options.Database,false),
314324
httpmw.ExtractOrganizationMemberParam(options.Database),
315325
)
316326
r.Put("/roles",api.putMemberRoles)
@@ -389,7 +399,7 @@ func New(options *Options) *API {
389399
r.Get("/",api.assignableSiteRoles)
390400
})
391401
r.Route("/{user}",func(r chi.Router) {
392-
r.Use(httpmw.ExtractUserParam(options.Database))
402+
r.Use(httpmw.ExtractUserParam(options.Database,false))
393403
r.Delete("/",api.deleteUser)
394404
r.Get("/",api.userByName)
395405
r.Put("/profile",api.putUserProfile)

‎coderd/database/databasefake/databasefake.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2324,6 +2324,10 @@ func (q *fakeQuerier) InsertWorkspaceApp(_ context.Context, arg database.InsertW
23242324
q.mutex.Lock()
23252325
deferq.mutex.Unlock()
23262326

2327+
ifarg.SharingLevel=="" {
2328+
arg.SharingLevel=database.AppSharingLevelOwner
2329+
}
2330+
23272331
// nolint:gosimple
23282332
workspaceApp:= database.WorkspaceApp{
23292333
ID:arg.ID,
@@ -2334,6 +2338,7 @@ func (q *fakeQuerier) InsertWorkspaceApp(_ context.Context, arg database.InsertW
23342338
Command:arg.Command,
23352339
Url:arg.Url,
23362340
Subdomain:arg.Subdomain,
2341+
SharingLevel:arg.SharingLevel,
23372342
HealthcheckUrl:arg.HealthcheckUrl,
23382343
HealthcheckInterval:arg.HealthcheckInterval,
23392344
HealthcheckThreshold:arg.HealthcheckThreshold,

‎coderd/database/dump.sql

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- Drop column sharing_level from workspace_apps
2+
ALTERTABLE workspace_apps DROP COLUMN sharing_level;
3+
4+
-- Drop type app_sharing_level
5+
DROPTYPE app_sharing_level;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-- Add enum app_sharing_level
2+
CREATETYPEapp_sharing_levelAS ENUM (
3+
-- only the workspace owner can access the app
4+
'owner',
5+
-- any authenticated user on the site can access the app
6+
'authenticated',
7+
-- any user can access the app even if they are not authenticated
8+
'public'
9+
);
10+
11+
-- Add sharing_level column to workspace_apps table
12+
ALTERTABLE workspace_apps ADD COLUMN sharing_level app_sharing_levelNOT NULL DEFAULT'owner'::app_sharing_level;

‎coderd/database/models.go

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries.sql.go

Lines changed: 13 additions & 5 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp