preCheckAccess returns the user's most capable active access grant matching the given query, or nil if none. When `requireExport` is true the CEL filter is narrowed to grants with `export == true`, so an unmask-only grant on the same statement can't shadow a separately-active export grant via slice-
(ctx context.Context, statement string, instance *store.InstanceMessage, database *store.DatabaseMessage, requireExport bool)
| 194 | // The returned grant has a non-nil Payload — callers may deref |
| 195 | // `Payload.Unmask` / `Payload.Export` without an additional check. |
| 196 | func (s *SQLService) preCheckAccess(ctx context.Context, statement string, instance *store.InstanceMessage, database *store.DatabaseMessage, requireExport bool) *store.AccessGrantMessage { |
| 197 | project, err := s.store.GetProject(ctx, &store.FindProjectMessage{ |
| 198 | Workspace: common.GetWorkspaceIDFromContext(ctx), |
| 199 | ResourceID: &database.ProjectID, |
| 200 | }) |
| 201 | if err != nil { |
| 202 | slog.Warn("failed to find project", slog.String("project_id", database.ProjectID), log.BBError(err)) |
| 203 | return nil |
| 204 | } |
| 205 | if project == nil { |
| 206 | slog.Warn("project not found", slog.String("project_id", database.ProjectID)) |
| 207 | return nil |
| 208 | } |
| 209 | if !project.Setting.AllowJustInTimeAccess { |
| 210 | slog.Debug("JIT is not enabled in the project", slog.String("project_id", database.ProjectID)) |
| 211 | return nil |
| 212 | } |
| 213 | |
| 214 | user, ok := GetUserFromContext(ctx) |
| 215 | if !ok || user == nil { |
| 216 | return nil |
| 217 | } |
| 218 | |
| 219 | databaseFullName := common.FormatDatabase(database.InstanceID, database.DatabaseName) |
| 220 | now := time.Now().UTC().Format(time.RFC3339) |
| 221 | |
| 222 | filter := fmt.Sprintf( |
| 223 | `status == "ACTIVE" && target == %q && expire_time > %q && query == %q`, |
| 224 | databaseFullName, |
| 225 | now, |
| 226 | strings.TrimSpace(statement), |
| 227 | ) |
| 228 | if requireExport { |
| 229 | filter += ` && export == true` |
| 230 | } |
| 231 | filterQ, err := store.GetListAccessGrantFilter(filter) |
| 232 | if err != nil { |
| 233 | slog.Warn("failed to build access grant filter", log.BBError(err)) |
| 234 | return nil |
| 235 | } |
| 236 | |
| 237 | grants, err := s.store.ListAccessGrants(ctx, &store.FindAccessGrantMessage{ |
| 238 | Workspace: common.GetWorkspaceIDFromContext(ctx), |
| 239 | ProjectID: &database.ProjectID, |
| 240 | Creator: &user.Email, |
| 241 | FilterQ: filterQ, |
| 242 | }) |
| 243 | if err != nil { |
| 244 | slog.Warn("failed to list access grants", log.BBError(err)) |
| 245 | return nil |
| 246 | } |
| 247 | |
| 248 | if len(grants) == 0 { |
| 249 | return nil |
| 250 | } |
| 251 | readOnly, err := isReadOnlyStatementForAccessGrant(ctx, instance.Metadata.GetEngine(), statement) |
| 252 | if err != nil { |
| 253 | slog.Warn("failed to validate access grant query", log.BBError(err)) |
no test coverage detected