MCPcopy Index your code
hub / github.com/bytebase/bytebase / preCheckAccess

Method preCheckAccess

backend/api/v1/sql_service.go:196–261  ·  view source on GitHub ↗

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)

Source from the content-addressed store, hash-verified

194// The returned grant has a non-nil Payload — callers may deref
195// `Payload.Unmask` / `Payload.Export` without an additional check.
196func (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))

Callers 2

QueryMethod · 0.95
ExportMethod · 0.95

Calls 12

BBErrorFunction · 0.92
FormatDatabaseFunction · 0.92
GetListAccessGrantFilterFunction · 0.92
GetUserFromContextFunction · 0.85
selectBestAccessGrantFunction · 0.85
DebugMethod · 0.80
GetProjectMethod · 0.65
StringMethod · 0.65
ListAccessGrantsMethod · 0.65
GetEngineMethod · 0.45

Tested by

no test coverage detected