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

Commitfd6e329

Browse files
committed
feat: rename special API key scopes to coder:* namespace
This change unifies scope handling by migrating special scopes to thecoder:* namespace while maintaining backward compatibility:- Database: 'all' -> 'coder:all', 'application_connect' -> 'coder:application_connect'- API accepts both legacy and canonical forms in requests- Responses maintain legacy format for existing client compatibility- Scope catalog returns all public scopes including canonical specials- Validation enforces public scope requirements using unified logicThe migration preserves existing API key functionality while establishingconsistent scope naming conventions for future extensibility.
1 parent2ea1b29 commitfd6e329

File tree

35 files changed

+332
-113
lines changed

35 files changed

+332
-113
lines changed

‎Makefile‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ codersdk/rbacresources_gen.go: scripts/typegen/codersdk.gotmpl scripts/typegen/m
872872
touch "$@"
873873

874874
codersdk/apikey_scopes_gen.go: scripts/apikeyscopesgen/main.go coderd/rbac/scopes_catalog.go coderd/rbac/scopes.go
875-
# Generate SDK constants forpublic low-level API key scopes.
875+
# Generate SDK constants forexternal API key scopes.
876876
go run ./scripts/apikeyscopesgen> /tmp/apikey_scopes_gen.go
877877
mv /tmp/apikey_scopes_gen.go codersdk/apikey_scopes_gen.go
878878
touch"$@"

‎coderd/apidoc/docs.go‎

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

‎coderd/apidoc/swagger.json‎

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

‎coderd/apikey.go‎

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,39 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) {
6767
}
6868

6969
// Map and validate requested scope.
70-
// Accept special scopes (all, application_connect) and curated public low-level scopes.
71-
scopes:= database.APIKeyScopes{database.APIKeyScopeAll}
72-
ifcreateToken.Scope!="" {
70+
// Accept legacy special scopes (all, application_connect) and external scopes.
71+
// Default to coder:all scopes for backward compatibility.
72+
scopes:= database.APIKeyScopes{database.ApiKeyScopeCoderAll}
73+
iflen(createToken.Scopes)>0 {
74+
scopes=make(database.APIKeyScopes,0,len(createToken.Scopes))
75+
for_,s:=rangecreateToken.Scopes {
76+
name:=string(s)
77+
if!rbac.IsExternalScope(rbac.ScopeName(name)) {
78+
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
79+
Message:"Failed to create API key.",
80+
Detail:fmt.Sprintf("invalid or unsupported API key scope: %q",name),
81+
})
82+
return
83+
}
84+
scopes=append(scopes,database.APIKeyScope(name))
85+
}
86+
}elseifstring(createToken.Scope)!="" {
7387
name:=string(createToken.Scope)
7488
if!rbac.IsExternalScope(rbac.ScopeName(name)) {
7589
httpapi.Write(ctx,rw,http.StatusBadRequest, codersdk.Response{
7690
Message:"Failed to create API key.",
77-
Detail:fmt.Sprintf("invalid API key scope: %q",name),
91+
Detail:fmt.Sprintf("invalidor unsupportedAPI key scope: %q",name),
7892
})
7993
return
8094
}
81-
scopes= database.APIKeyScopes{database.APIKeyScope(name)}
95+
switchname {
96+
case"all":
97+
scopes= database.APIKeyScopes{database.ApiKeyScopeCoderAll}
98+
case"application_connect":
99+
scopes= database.APIKeyScopes{database.ApiKeyScopeCoderApplicationConnect}
100+
default:
101+
scopes= database.APIKeyScopes{database.APIKeyScope(name)}
102+
}
82103
}
83104

84105
tokenName:=namesgenerator.GetRandomName(1)

‎coderd/apikey/apikey.go‎

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@ type CreateParams struct {
2525
// Optional.
2626
ExpiresAt time.Time
2727
LifetimeSecondsint64
28+
2829
// Scope is legacy single-scope input kept for backward compatibility.
2930
//
30-
// Deprecated:Prefer Scopesfor new code.
31+
// Deprecated:use Scopesinstead.
3132
Scope database.APIKeyScope
3233
// Scopes is the full list of scopes to attach to the key.
33-
// If empty and Scope is set, the generator will use [Scope].
34-
// If both are empty, the generator will default to [APIKeyScopeAll].
3534
Scopes database.APIKeyScopes
3635
TokenNamestring
3736
RemoteAddrstring
@@ -74,9 +73,19 @@ func Generate(params CreateParams) (database.InsertAPIKeyParams, string, error)
7473
caselen(params.Scopes)>0:
7574
scopes=params.Scopes
7675
caseparams.Scope!="":
77-
scopes= database.APIKeyScopes{params.Scope}
76+
varscope database.APIKeyScope
77+
switchparams.Scope {
78+
case"all":
79+
scope=database.ApiKeyScopeCoderAll
80+
case"application_connect":
81+
scope=database.ApiKeyScopeCoderApplicationConnect
82+
default:
83+
scope=params.Scope
84+
}
85+
scopes= database.APIKeyScopes{scope}
7886
default:
79-
scopes= database.APIKeyScopes{database.APIKeyScopeAll}
87+
// Default to coder:all scope for backward compatibility.
88+
scopes= database.APIKeyScopes{database.ApiKeyScopeCoderAll}
8089
}
8190

8291
for_,s:=rangescopes {

‎coderd/apikey/apikey_test.go‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func TestGenerate(t *testing.T) {
3535
LifetimeSeconds:int64(time.Hour.Seconds()),
3636
TokenName:"hello",
3737
RemoteAddr:"1.2.3.4",
38-
Scope:database.APIKeyScopeApplicationConnect,
38+
Scope:database.ApiKeyScopeCoderApplicationConnect,
3939
},
4040
},
4141
{
@@ -62,7 +62,7 @@ func TestGenerate(t *testing.T) {
6262
ExpiresAt: time.Time{},
6363
TokenName:"hello",
6464
RemoteAddr:"1.2.3.4",
65-
Scope:database.APIKeyScopeApplicationConnect,
65+
Scope:database.ApiKeyScopeCoderApplicationConnect,
6666
},
6767
},
6868
{
@@ -75,7 +75,7 @@ func TestGenerate(t *testing.T) {
7575
ExpiresAt: time.Time{},
7676
TokenName:"hello",
7777
RemoteAddr:"1.2.3.4",
78-
Scope:database.APIKeyScopeApplicationConnect,
78+
Scope:database.ApiKeyScopeCoderApplicationConnect,
7979
},
8080
},
8181
{
@@ -88,7 +88,7 @@ func TestGenerate(t *testing.T) {
8888
LifetimeSeconds:int64(time.Hour.Seconds()),
8989
TokenName:"hello",
9090
RemoteAddr:"",
91-
Scope:database.APIKeyScopeApplicationConnect,
91+
Scope:database.ApiKeyScopeCoderApplicationConnect,
9292
},
9393
},
9494
{
@@ -161,7 +161,7 @@ func TestGenerate(t *testing.T) {
161161
iftc.params.Scope!="" {
162162
assert.True(t,key.Scopes.Has(tc.params.Scope))
163163
}else {
164-
assert.True(t,key.Scopes.Has(database.APIKeyScopeAll))
164+
assert.True(t,key.Scopes.Has(database.ApiKeyScopeCoderAll))
165165
}
166166

167167
iftc.params.TokenName!="" {

‎coderd/apikey_scopes_validation_test.go‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ func TestTokenCreation_ScopeValidation(t *testing.T) {
2222
{name:"AllowsPublicLowLevelScope",scope:"workspace:read",wantErr:false},
2323
{name:"RejectsInternalOnlyScope",scope:"debug_info:read",wantErr:true},
2424
{name:"AllowsLegacyScopes",scope:"application_connect",wantErr:false},
25-
{name:"AllowsCanonicalSpecialScope",scope:"all",wantErr:false},
25+
{name:"AllowsLegacyScopes2",scope:"all",wantErr:false},
26+
{name:"AllowsCanonicalSpecialScope",scope:"coder:all",wantErr:false},
2627
}
2728

2829
for_,tc:=rangecases {
@@ -42,6 +43,22 @@ func TestTokenCreation_ScopeValidation(t *testing.T) {
4243
}
4344
require.NoError(t,err)
4445
require.NotEmpty(t,resp.Key)
46+
47+
// Fetch and verify the stored scopes match expectation.
48+
keys,err:=client.Tokens(ctx,codersdk.Me, codersdk.TokensFilter{})
49+
require.NoError(t,err)
50+
require.Len(t,keys,1)
51+
52+
// Normalize legacy singular scopes to canonical coder:* values.
53+
expected:=tc.scope
54+
switchtc.scope {
55+
casecodersdk.APIKeyScopeAll:
56+
expected=codersdk.APIKeyScopeCoderAll
57+
casecodersdk.APIKeyScopeApplicationConnect:
58+
expected=codersdk.APIKeyScopeCoderApplicationConnect
59+
}
60+
61+
require.Contains(t,keys[0].Scopes,expected)
4562
})
4663
}
4764
}

‎coderd/apikey_test.go‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,54 @@ func TestTokenScoped(t *testing.T) {
8888
require.Equal(t,keys[0].Scope,codersdk.APIKeyScopeApplicationConnect)
8989
}
9090

91+
// Ensure backward-compat: when a token is created using the legacy singular
92+
// scope names ("all" or "application_connect"), the API returns the same
93+
// legacy value in the deprecated singular Scope field while also supporting
94+
// the new multi-scope field.
95+
funcTestTokenLegacySingularScopeCompat(t*testing.T) {
96+
t.Parallel()
97+
98+
cases:= []struct {
99+
namestring
100+
scope codersdk.APIKeyScope
101+
scopes []codersdk.APIKeyScope
102+
}{
103+
{
104+
name:"all",
105+
scope:codersdk.APIKeyScopeAll,
106+
scopes: []codersdk.APIKeyScope{codersdk.APIKeyScopeCoderAll},
107+
},
108+
{
109+
name:"application_connect",
110+
scope:codersdk.APIKeyScopeApplicationConnect,
111+
scopes: []codersdk.APIKeyScope{codersdk.APIKeyScopeCoderApplicationConnect},
112+
},
113+
}
114+
115+
for_,tc:=rangecases {
116+
t.Run(tc.name,func(t*testing.T) {
117+
t.Parallel()
118+
ctx,cancel:=context.WithTimeout(t.Context(),testutil.WaitLong)
119+
defercancel()
120+
client:=coderdtest.New(t,nil)
121+
_=coderdtest.CreateFirstUser(t,client)
122+
123+
// Create with legacy singular scope.
124+
_,err:=client.CreateToken(ctx,codersdk.Me, codersdk.CreateTokenRequest{
125+
Scope:tc.scope,
126+
})
127+
require.NoError(t,err)
128+
129+
// Read back and ensure the deprecated singular field matches exactly.
130+
keys,err:=client.Tokens(ctx,codersdk.Me, codersdk.TokensFilter{})
131+
require.NoError(t,err)
132+
require.Len(t,keys,1)
133+
require.Equal(t,tc.scope,keys[0].Scope)
134+
require.ElementsMatch(t,keys[0].Scopes,tc.scopes)
135+
})
136+
}
137+
}
138+
91139
funcTestUserSetTokenDuration(t*testing.T) {
92140
t.Parallel()
93141

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp