-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathQueryExecutionContext.java
More file actions
128 lines (114 loc) · 3.86 KB
/
Copy pathQueryExecutionContext.java
File metadata and controls
128 lines (114 loc) · 3.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package com.dbaagent.service;
import com.dbaagent.model.QueryExecutionOrigin;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
public record QueryExecutionContext(
QueryExecutionOrigin origin,
MutationMode mutationMode,
String actorUsername,
boolean actorIsAdmin,
boolean mutationConfirmed
) {
public enum MutationMode {
READ_ONLY_ONLY,
MAY_MUTATE
}
public static QueryExecutionContext chat() {
return new QueryExecutionContext(
QueryExecutionOrigin.CHAT,
MutationMode.READ_ONLY_ONLY,
resolveActorUsername(),
false,
false
);
}
public static QueryExecutionContext editor(String actorUsername, boolean actorIsAdmin, boolean mutationConfirmed) {
return new QueryExecutionContext(
QueryExecutionOrigin.EDITOR,
actorIsAdmin ? MutationMode.MAY_MUTATE : MutationMode.READ_ONLY_ONLY,
actorUsername,
actorIsAdmin,
mutationConfirmed
);
}
public static QueryExecutionContext internal() {
return new QueryExecutionContext(
QueryExecutionOrigin.INTERNAL,
MutationMode.MAY_MUTATE,
null,
true,
true
);
}
public static QueryExecutionContext mcp(String actorUsername) {
return mcp(actorUsername, false);
}
public static QueryExecutionContext mcp(String actorUsername, boolean actorIsAdmin) {
return mcp(actorUsername, actorIsAdmin, false);
}
/**
* MCP / coding-agent SQL. Developers stay read-only. Admins may run
* non-destructive DDL/DML after the same confirmation gate as the Editor.
* DROP and TRUNCATE stay blocked in {@link QueryExecutionPolicyService}.
*/
public static QueryExecutionContext mcp(
String actorUsername,
boolean actorIsAdmin,
boolean mutationConfirmed
) {
return new QueryExecutionContext(
QueryExecutionOrigin.MCP,
actorIsAdmin ? MutationMode.MAY_MUTATE : MutationMode.READ_ONLY_ONLY,
actorUsername,
actorIsAdmin,
mutationConfirmed
);
}
public static QueryExecutionContext forSqlSurface(
boolean mcpBearer,
String actorUsername,
boolean actorIsAdmin,
boolean mutationConfirmed
) {
if (mcpBearer) {
return mcp(actorUsername, actorIsAdmin, mutationConfirmed);
}
return editor(actorUsername, actorIsAdmin, mutationConfirmed);
}
public static QueryExecutionContext scheduled() {
return new QueryExecutionContext(
QueryExecutionOrigin.SCHEDULED,
MutationMode.MAY_MUTATE,
null,
true,
true
);
}
public static QueryExecutionContext api(String actorUsername) {
return api(actorUsername, false);
}
public static QueryExecutionContext api(String actorUsername, boolean actorIsAdmin) {
return new QueryExecutionContext(
QueryExecutionOrigin.API,
MutationMode.READ_ONLY_ONLY,
actorUsername,
actorIsAdmin,
false
);
}
private static String resolveActorUsername() {
String fromHolder = QueryActorContextHolder.currentUsername();
if (fromHolder != null && !fromHolder.isBlank()) {
return fromHolder;
}
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null || !authentication.isAuthenticated()) {
return null;
}
String name = authentication.getName();
if (name == null || name.isBlank() || "anonymousUser".equals(name)) {
return null;
}
return name;
}
}