feat: add access profile selection support with device-specific profile persistence
Add SelectOwnProfile handler to allow users to choose from available access profiles. Store selected profile ID per device in settings table with device_access_profile category. Implement GetSelectedProfileID and SetSelectedProfileID repository methods using JSONB storage. Add ListSelectableProfiles to policy repository and service to query user/group/device-specific profiles ordered by priority. Filter gateway
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
@@ -18,6 +19,8 @@ type Repository interface {
|
||||
ListAll(ctx context.Context) ([]Device, error)
|
||||
GetLatestEnrollmentByUser(ctx context.Context, userID uuid.UUID) (EnrollmentResponse, error)
|
||||
GetEnrollmentByDeviceID(ctx context.Context, deviceID uuid.UUID) (EnrollmentResponse, error)
|
||||
GetSelectedProfileID(ctx context.Context, deviceID uuid.UUID) (*uuid.UUID, error)
|
||||
SetSelectedProfileID(ctx context.Context, deviceID uuid.UUID, profileID uuid.UUID) error
|
||||
Revoke(ctx context.Context, deviceID uuid.UUID) error
|
||||
Rotate(ctx context.Context, deviceID uuid.UUID) error
|
||||
}
|
||||
@@ -178,6 +181,43 @@ func (r *PGRepository) GetEnrollmentByDeviceID(ctx context.Context, deviceID uui
|
||||
return scanEnrollmentRow(row)
|
||||
}
|
||||
|
||||
func (r *PGRepository) GetSelectedProfileID(ctx context.Context, deviceID uuid.UUID) (*uuid.UUID, error) {
|
||||
row := r.db.QueryRow(ctx, `
|
||||
select value->>'profile_id'
|
||||
from settings
|
||||
where category = 'device_access_profile' and key = $1
|
||||
`, deviceID.String())
|
||||
|
||||
var raw string
|
||||
if err := row.Scan(&raw); err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
value, err := uuid.Parse(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &value, nil
|
||||
}
|
||||
|
||||
func (r *PGRepository) SetSelectedProfileID(ctx context.Context, deviceID uuid.UUID, profileID uuid.UUID) error {
|
||||
payload, err := json.Marshal(map[string]string{"profile_id": profileID.String()})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = r.db.Exec(ctx, `
|
||||
insert into settings (category, key, value, updated_at)
|
||||
values ('device_access_profile', $1, $2::jsonb, now())
|
||||
on conflict (category, key)
|
||||
do update set value = excluded.value, updated_at = now()
|
||||
`, deviceID.String(), string(payload))
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *PGRepository) ListByUser(ctx context.Context, userID uuid.UUID) ([]Device, error) {
|
||||
rows, err := r.db.Query(ctx, `
|
||||
select d.id, d.user_id, d.gateway_id, d.name, d.platform, d.status, coalesce(host(wp.assigned_ip), '')
|
||||
|
||||
Reference in New Issue
Block a user