Files
photoprism/internal/commands/auth_jwt_test.go
2025-09-26 02:38:49 +02:00

95 lines
3.0 KiB
Go

package commands
import (
"encoding/json"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/photoprism/photoprism/internal/config"
"github.com/photoprism/photoprism/internal/photoprism/get"
"github.com/photoprism/photoprism/internal/service/cluster"
reg "github.com/photoprism/photoprism/internal/service/cluster/registry"
"github.com/photoprism/photoprism/pkg/rnd"
)
func TestAuthJWTCommands(t *testing.T) {
conf := get.Config()
origEdition := conf.Options().Edition
origRole := conf.Options().NodeRole
origUUID := conf.Options().ClusterUUID
origPortal := conf.Options().PortalUrl
origJWKS := conf.JWKSUrl()
conf.Options().Edition = config.Portal
conf.Options().NodeRole = string(cluster.RolePortal)
conf.Options().ClusterUUID = "11111111-1111-4111-8111-111111111111"
conf.Options().PortalUrl = "https://portal.test"
conf.SetJWKSUrl("https://portal.test/.well-known/jwks.json")
get.SetConfig(conf)
conf.RegisterDb()
require.True(t, conf.IsPortal())
manager := get.JWTManager()
require.NotNil(t, manager)
_, err := manager.EnsureActiveKey()
require.NoError(t, err)
registry, err := reg.NewClientRegistryWithConfig(conf)
require.NoError(t, err)
nodeUUID := rnd.UUID()
node := &reg.Node{}
node.UUID = nodeUUID
node.Name = "pp-node-01"
node.Role = string(cluster.RoleInstance)
require.NoError(t, registry.Put(node))
t.Cleanup(func() {
conf.Options().Edition = origEdition
conf.Options().NodeRole = origRole
conf.Options().ClusterUUID = origUUID
conf.Options().PortalUrl = origPortal
conf.SetJWKSUrl(origJWKS)
get.SetConfig(conf)
conf.RegisterDb()
})
output, err := RunWithTestContext(AuthJWTIssueCommand, []string{"issue", "--node", nodeUUID})
require.NoError(t, err)
assert.Contains(t, output, "Issued JWT")
jsonOut, err := RunWithTestContext(AuthJWTIssueCommand, []string{"issue", "--node", nodeUUID, "--json"})
require.NoError(t, err)
var payload struct {
Token string `json:"token"`
}
require.NoError(t, json.Unmarshal([]byte(jsonOut), &payload))
require.NotEmpty(t, payload.Token)
inspectOut, err := RunWithTestContext(AuthJWTInspectCommand, []string{"inspect", "--json", payload.Token})
require.NoError(t, err)
assert.Contains(t, inspectOut, "\"verified\": true")
inspectStrict, err := RunWithTestContext(AuthJWTInspectCommand, []string{"inspect", "--json", "--expect-audience", "node:" + nodeUUID, "--require-scope", "cluster", payload.Token})
require.NoError(t, err)
assert.Contains(t, inspectStrict, "\"verified\": true")
keysOut, err := RunWithTestContext(AuthJWTKeysListCommand, []string{"ls", "--json"})
require.NoError(t, err)
assert.Contains(t, keysOut, "\"keys\"")
statusOut, err := RunWithTestContext(AuthJWTStatusCommand, []string{"status"})
require.NoError(t, err)
assert.Contains(t, statusOut, "JWKS URL")
assert.Contains(t, statusOut, "Cached Keys")
// invalid scope should fail
_, err = RunWithTestContext(AuthJWTIssueCommand, []string{"issue", "--node", nodeUUID, "--scope", "unknown"})
require.Error(t, err)
}