This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"data-terminal-cloud/internal/audit"
|
||||
"data-terminal-cloud/internal/database"
|
||||
"data-terminal-cloud/internal/deviceactivation"
|
||||
"data-terminal-cloud/internal/devicebinding"
|
||||
"data-terminal-cloud/internal/identity"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
@@ -72,6 +73,11 @@ func (s *Service) ChangeDeviceBinding(ctx context.Context, principal identity.Pr
|
||||
return err
|
||||
}
|
||||
var bindingID string
|
||||
if input.Action == DeviceBindingActionTransfer {
|
||||
if err = devicebinding.RequireLegacy(ctx, tx, access.deviceID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := tx.QueryRow(ctx, `SELECT public_id::text FROM device_binding WHERE device_id=$1::uuid AND tenant_id=$2::uuid AND unbound_at IS NULL FOR UPDATE`, access.deviceID, access.tenantID).Scan(&bindingID); errors.Is(err, pgx.ErrNoRows) {
|
||||
return ErrDeviceBindingStale
|
||||
} else if err != nil {
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"data-terminal-cloud/internal/audit"
|
||||
"data-terminal-cloud/internal/database"
|
||||
"data-terminal-cloud/internal/deviceactivation"
|
||||
"data-terminal-cloud/internal/devicebinding"
|
||||
"data-terminal-cloud/internal/identity"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
@@ -57,6 +58,9 @@ func (s *Service) ClaimDevice(ctx context.Context, principal identity.Principal,
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("resolve device claim: %w", err)
|
||||
}
|
||||
if err = devicebinding.RequireLegacy(ctx, tx, deviceID); err != nil {
|
||||
return err
|
||||
}
|
||||
if revokedAt != nil || !expiresAt.After(time.Now()) {
|
||||
return ErrDeviceClaimInvalid
|
||||
}
|
||||
@@ -70,7 +74,10 @@ func (s *Service) ClaimDevice(ctx context.Context, principal identity.Principal,
|
||||
JOIN device d ON d.id=b.device_id AND d.tenant_id=b.tenant_id
|
||||
JOIN household h ON h.id=b.household_id AND h.tenant_id=b.tenant_id
|
||||
JOIN subject_profile sp ON sp.id=b.subject_id AND sp.tenant_id=b.tenant_id
|
||||
WHERE b.id=$1::uuid`, *usedBindingID).Scan(&result.BindingID, &result.DeviceID, &result.HouseholdID, &result.SubjectID, &result.BoundAt); err != nil {
|
||||
WHERE b.id=$1::uuid AND b.unbound_at IS NULL AND b.generation=d.binding_generation`, *usedBindingID).Scan(&result.BindingID, &result.DeviceID, &result.HouseholdID, &result.SubjectID, &result.BoundAt); err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return ErrDeviceClaimUsed
|
||||
}
|
||||
return fmt.Errorf("read used device claim binding: %w", err)
|
||||
}
|
||||
if result.HouseholdID != householdPublicID || result.SubjectID != subjectPublicID {
|
||||
|
||||
@@ -364,6 +364,7 @@ func TestDeviceClaimIsOneTimeAndRetrySafe(t *testing.T) {
|
||||
if bindingID != "" {
|
||||
_, _ = pool.Exec(ctx, `DELETE FROM device_binding WHERE public_id=$1::uuid`, bindingID)
|
||||
}
|
||||
_, _ = pool.Exec(ctx,`UPDATE device SET activation_state='CLAIMABLE' WHERE public_id='10000000-0000-0000-0000-000000000512'::uuid AND NOT EXISTS(SELECT 1 FROM device_binding WHERE device_id=device.id AND unbound_at IS NULL)`)
|
||||
_, _ = pool.Exec(ctx, `DELETE FROM audit_event WHERE request_id='saas-integration-device-claim'`)
|
||||
}()
|
||||
if _, _, err := service.ClaimDevice(ctx, outsider, claimCode, householdID, subjectID, "saas-integration-outsider-claim"); !errors.Is(err, ErrAccessDenied) {
|
||||
|
||||
Reference in New Issue
Block a user