mirror of
https://github.com/juanfont/headscale.git
synced 2026-11-04 04:34:07 +09:00
api/v2: refuse an unknown keyType
This commit is contained in:
1 parent
e13ed03e70
commit
70d96ccd8f
3 files changed
+29
-7
No files matched your search
@@ -156,11 +156,16 @@ func registerKeys(api huma.API, b Backend) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in.Body.KeyType == keyTypeClient {
|
||||
switch in.Body.KeyType {
|
||||
case keyTypeClient:
|
||||
return createOAuthClient(ctx, b, in.Body)
|
||||
case "", keyTypeAuth:
|
||||
return createAuthKey(ctx, b, in.Body)
|
||||
default:
|
||||
return nil, huma.Error400BadRequest(
|
||||
"invalid key type, " + strconv.Quote(in.Body.KeyType) + " is not supported",
|
||||
)
|
||||
}
|
||||
|
||||
return createAuthKey(ctx, b, in.Body)
|
||||
})
|
||||
|
||||
huma.Register(api, huma.Operation{
|
||||
|
||||
@@ -71,9 +71,7 @@ var apiv2CompatSkipReasons = map[string]string{
|
||||
"key-list/setup-token-keys/4/tags": mintTagsNotEchoed,
|
||||
"key-list/setup-token-keys/6/tags": mintTagsNotEchoed,
|
||||
|
||||
"oauth/K2/0/status": unknownKeyType,
|
||||
"oauth/K2/0/outcome": unknownKeyType,
|
||||
"oauth/K5/0/status": unknownKeyType,
|
||||
"oauth/K5/0/status": unknownKeyType,
|
||||
|
||||
"oauth/E4/0/status": tagRefusalStatus,
|
||||
"oauth/E5/0/status": tagRefusalStatus,
|
||||
@@ -202,7 +200,7 @@ const (
|
||||
const (
|
||||
mintScopeRefusalStatus = "TOKEN_SCOPE_REFUSAL_STATUS: SaaS refuses a token scope the client lacks with 403 and a message; headscale with 400 invalid_scope"
|
||||
mintTagsNotEchoed = "TOKEN_TAGS_NOT_ECHOED: SaaS's token answer names the token's tags; headscale's has no tags"
|
||||
unknownKeyType = "UNKNOWN_KEY_TYPE: SaaS refuses an unknown keyType with 400 before it checks scopes; headscale makes an auth key from it"
|
||||
unknownKeyType = "UNKNOWN_KEY_TYPE: SaaS refuses an unknown keyType with 400 before it checks scopes; headscale checks the scope first and answers 403"
|
||||
tagRefusalStatus = "TAG_REFUSAL_STATUS: SaaS refuses a tag outside the token's grant with 400 requested tags are invalid or not permitted; headscale with 403"
|
||||
keyListWithoutAll = "KEY_LIST_WITHOUT_ALL: without all=true SaaS lists an OAuth token only the auth keys OAuth tokens made, whatever its tags and theirs; headscale lists every key"
|
||||
keyListInvalidKeys = "KEY_LIST_INVALID_KEYS: SaaS leaves spent and revoked auth keys out of a listing; headscale lists them"
|
||||
|
||||
@@ -275,6 +275,25 @@ func TestAPIv2OAuth_ValidationErrorsBounded(t *testing.T) {
|
||||
assert.Equal(t, "and 980 more", out.Data[0].Errors[20])
|
||||
}
|
||||
|
||||
// TestAPIv2OAuth_UnknownKeyTypeRefused: a keyType other than auth or client
|
||||
// is refused, not taken as an auth key.
|
||||
func TestAPIv2OAuth_UnknownKeyTypeRefused(t *testing.T) {
|
||||
app, baseURL, admin := newOAuthTestServer(t)
|
||||
|
||||
status, body := apiReq(t, http.MethodPost, baseURL+"/api/v2/tailnet/-/keys", admin, map[string]any{
|
||||
"keyType": "nosuch",
|
||||
"capabilities": map[string]any{"devices": map[string]any{"create": map[string]any{
|
||||
"reusable": true, "ephemeral": false, "preauthorized": true, "tags": []string{"tag:ci"},
|
||||
}}},
|
||||
})
|
||||
assert.Equal(t, http.StatusBadRequest, status)
|
||||
assert.Contains(t, string(body), `invalid key type, \"nosuch\" is not supported`)
|
||||
|
||||
keys, err := app.state.ListPreAuthKeys()
|
||||
require.NoError(t, err)
|
||||
assert.Empty(t, keys)
|
||||
}
|
||||
|
||||
// TestAPIv2OAuth_UnknownPropertiesIgnored: a body property the API does not
|
||||
// define is ignored, at the top and nested, as Tailscale's API does.
|
||||
func TestAPIv2OAuth_UnknownPropertiesIgnored(t *testing.T) {
|
||||
|
||||
Reference in new issue
Block a user