Files

79 lines
2.5 KiB
Go

package postgres
import (
"context"
"database/sql"
"fmt"
"git.nianxx.cn/wangxuming/NianAIGC/backend/internal/identity"
)
const FindAuthorizationSnapshotSQL = `SELECT
u.id,
u.phone,
u.display_name,
u.role,
u.organization_id,
u.status,
u.session_version,
o.id,
o.name,
o.status
FROM public.platform_users AS u
LEFT JOIN public.platform_organizations AS o ON o.id = u.organization_id
WHERE u.id = $1::text`
// FindAuthorizationSnapshot loads all database-authoritative identity claims in
// one query. Account and organization state are deliberately not filtered so
// the Identity module can apply one authorization policy to every result.
func (db *Database) FindAuthorizationSnapshot(ctx context.Context, identityKey string) (identity.AuthorizationSnapshot, bool, error) {
if db.config.Backend != BackendPostgres || db.querier == nil {
return identity.AuthorizationSnapshot{}, false, fmt.Errorf("PostgreSQL is unavailable when ZHINIAN_DATA_BACKEND=%s", db.config.Backend)
}
rows, err := db.querier.Query(ctx, FindAuthorizationSnapshotSQL, identityKey)
if err != nil {
return identity.AuthorizationSnapshot{}, false, fmt.Errorf("query authorization snapshot: %w", err)
}
defer rows.Close()
if !rows.Next() {
if err := rows.Err(); err != nil {
return identity.AuthorizationSnapshot{}, false, fmt.Errorf("read authorization snapshot: %w", err)
}
return identity.AuthorizationSnapshot{}, false, nil
}
var snapshot identity.AuthorizationSnapshot
var organizationID sql.NullString
var joinedOrganizationID sql.NullString
var organizationName sql.NullString
var organizationStatus sql.NullString
if err := rows.Scan(
&snapshot.Account.ID,
&snapshot.Account.Phone,
&snapshot.Account.DisplayName,
&snapshot.Account.Role,
&organizationID,
&snapshot.Account.Status,
&snapshot.Account.SessionVersion,
&joinedOrganizationID,
&organizationName,
&organizationStatus,
); err != nil {
return identity.AuthorizationSnapshot{}, false, fmt.Errorf("scan authorization snapshot: %w", err)
}
if organizationID.Valid {
snapshot.Account.OrganizationID = organizationID.String
}
if joinedOrganizationID.Valid {
snapshot.Organization = &identity.OrganizationSnapshot{
ID: joinedOrganizationID.String,
Name: organizationName.String,
Status: organizationStatus.String,
}
}
if err := rows.Err(); err != nil {
return identity.AuthorizationSnapshot{}, false, fmt.Errorf("read authorization snapshot: %w", err)
}
return snapshot, true, nil
}