From 60754334024f787f8a8b005e4709c93933742c06 Mon Sep 17 00:00:00 2001 From: ila <2+ila@noreply.git.ilapage.cn> Date: Thu, 13 Aug 2026 12:23:46 +0800 Subject: [PATCH] feat: complete split camera credentials (#50) --- .../app/sense/admission/service_test.go | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/Sense/server/app/sense/admission/service_test.go b/Sense/server/app/sense/admission/service_test.go index 5a407c0..1463e62 100644 --- a/Sense/server/app/sense/admission/service_test.go +++ b/Sense/server/app/sense/admission/service_test.go @@ -22,6 +22,20 @@ type fakeRTSP struct{} func (fakeRTSP) Verify(context.Context, string, rtsp.Credential) (rtsp.Result, error) { return rtsp.Result{Status: "ready"}, nil } + +type credentialCapturingONVIF struct{ got onvif.Credential } + +func (f *credentialCapturingONVIF) Profiles(_ context.Context, _ string, credential onvif.Credential) ([]onvif.Profile, error) { + f.got = credential + return fakeONVIF{}.Profiles(context.Background(), "", credential) +} + +type credentialCapturingRTSP struct{ got rtsp.Credential } + +func (f *credentialCapturingRTSP) Verify(_ context.Context, _ string, credential rtsp.Credential) (rtsp.Result, error) { + f.got = credential + return rtsp.Result{Status: "ready"}, nil +} func TestProbeProfilesWithoutCredentialURI(t *testing.T) { vault, err := device.NewCredentialVault(base64.StdEncoding.EncodeToString([]byte("0123456789abcdef0123456789abcdef")), false) if err != nil { @@ -44,3 +58,41 @@ func TestProbeProfilesWithoutCredentialURI(t *testing.T) { t.Fatalf("result=%#v err=%v", result, err) } } + +func TestProbeUsesSeparateCredentialsPersistsProfilesAndActivatesDevice(t *testing.T) { + vault, err := device.NewCredentialVault(base64.StdEncoding.EncodeToString([]byte("0123456789abcdef0123456789abcdef")), false) + if err != nil { + t.Fatal(err) + } + deviceStore := device.NewMemoryStore() + deviceService := device.NewService(deviceStore, vault) + device.NewModule(deviceService).Register(platform.NewApp(platform.Config{DatabaseMode: platform.DatabaseModeMemory}, nil, nil)) + item, err := deviceService.Create(context.Background(), identity.Principal{}, "camera", "gate", device.ModalityVideo, nil) + if err != nil { + t.Fatal(err) + } + if _, err = deviceService.SetCredentials(context.Background(), identity.Principal{}, item.ID, "onvif-user", "onvif-password", false, "rtsp-user", "rtsp-password"); err != nil { + t.Fatal(err) + } + onvifClient := &credentialCapturingONVIF{} + rtspVerifier := &credentialCapturingRTSP{} + store := NewMemoryStore() + service := NewService(onvifClient, rtspVerifier, "", store) + result, err := service.Probe(context.Background(), identity.Principal{}, item.ID, "http://camera.invalid/onvif/device_service") + if err != nil { + t.Fatal(err) + } + if onvifClient.got.Username != "onvif-user" || rtspVerifier.got.Username != "rtsp-user" { + t.Fatal("credentials were not separated") + } + restarted := NewService(onvifClient, rtspVerifier, "", store) + persisted, ok := restarted.Get(item.ID) + if !ok || len(persisted.Profiles) != len(result.Profiles) { + t.Fatalf("persisted=%#v", persisted) + } + updated, err := deviceService.Get(context.Background(), item.ID) + if err != nil || updated.Status != device.StatusActive { + t.Fatalf("device=%#v err=%v", updated, err) + } +} +