88 lines
2.4 KiB
Go
88 lines
2.4 KiB
Go
package device
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync/atomic"
|
|
)
|
|
|
|
type Credential struct {
|
|
Username string
|
|
Password string
|
|
}
|
|
|
|
type DisplayInfo struct {
|
|
Name string
|
|
Location string
|
|
}
|
|
|
|
var activeService atomic.Pointer[Service]
|
|
|
|
// ReadCredential is an internal adapter port. Credentials must never be
|
|
// returned from HTTP handlers, logged, or placed in a URL.
|
|
func ReadCredential(ctx context.Context, id string) (Credential, error) {
|
|
return ReadONVIFCredential(ctx, id)
|
|
}
|
|
func ReadONVIFCredential(ctx context.Context, id string) (Credential, error) {
|
|
service := activeService.Load()
|
|
if service == nil {
|
|
return Credential{}, fmt.Errorf("device service is not ready")
|
|
}
|
|
item, err := service.store.Get(ctx, id)
|
|
if err != nil {
|
|
return Credential{}, err
|
|
}
|
|
if len(item.CredentialCiphertext) == 0 {
|
|
return Credential{}, fmt.Errorf("device credential is not configured")
|
|
}
|
|
username, password, err := service.vault.Decrypt(item.CredentialCiphertext)
|
|
return Credential{Username: username, Password: password}, err
|
|
}
|
|
|
|
func ReadRTSPCredential(ctx context.Context, id string) (Credential, error) {
|
|
service := activeService.Load()
|
|
if service == nil {
|
|
return Credential{}, fmt.Errorf("device service is not ready")
|
|
}
|
|
item, err := service.store.Get(ctx, id)
|
|
if err != nil {
|
|
return Credential{}, err
|
|
}
|
|
if len(item.RTSPCredentialCiphertext) == 0 {
|
|
return Credential{}, fmt.Errorf("RTSP credential is not configured")
|
|
}
|
|
username, password, err := service.vault.Decrypt(item.RTSPCredentialCiphertext)
|
|
return Credential{Username: username, Password: password}, err
|
|
}
|
|
|
|
func Describe(ctx context.Context, id string) (DisplayInfo, error) {
|
|
service := activeService.Load()
|
|
if service == nil {
|
|
return DisplayInfo{}, fmt.Errorf("device service is not ready")
|
|
}
|
|
item, err := service.store.Get(ctx, id)
|
|
if err != nil {
|
|
return DisplayInfo{}, err
|
|
}
|
|
return DisplayInfo{Name: item.Name, Location: item.Location}, nil
|
|
}
|
|
|
|
func MarkActive(ctx context.Context, id string) error {
|
|
service := activeService.Load()
|
|
if service == nil {
|
|
return fmt.Errorf("device service is not ready")
|
|
}
|
|
item, err := service.store.Get(ctx, id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if item.Status == StatusDisabled || item.Status == StatusActive {
|
|
return nil
|
|
}
|
|
expected := item.Version
|
|
item.Status = StatusActive
|
|
item.Version++
|
|
item.UpdatedAt = service.now().UTC()
|
|
return service.store.Update(ctx, item, expected)
|
|
}
|