connection updates
This commit is contained in:
+66
-12
@@ -5179,6 +5179,16 @@ private struct WorkbenchAccountManagerView: View {
|
||||
@State private var password = ""
|
||||
@State private var databaseName = ""
|
||||
@State private var privilege = "SELECT"
|
||||
@State private var selectedPrivileges: Set<String> = ["SELECT"]
|
||||
@State private var privilegeScope = "Schema"
|
||||
@State private var selectedRole = "Custom"
|
||||
private let rolePresets: [(String, String, [String])] = [
|
||||
("Custom", "Choose individual privileges", []),
|
||||
("Read Only", "Read tables and views", ["SELECT", "SHOW VIEW"]),
|
||||
("Read / Write", "Read and modify records", ["SELECT", "INSERT", "UPDATE", "DELETE", "SHOW VIEW"]),
|
||||
("DB Designer", "Create and alter schema objects", ["SELECT", "CREATE", "ALTER", "DROP", "INDEX", "REFERENCES", "CREATE VIEW", "SHOW VIEW", "TRIGGER"]),
|
||||
("DB Manager", "Manage all supported schema privileges", ["SELECT", "INSERT", "UPDATE", "DELETE", "CREATE", "ALTER", "DROP", "INDEX", "REFERENCES", "EXECUTE", "CREATE VIEW", "SHOW VIEW", "TRIGGER"])
|
||||
]
|
||||
@State private var previewSQL = ""
|
||||
@State private var confirm = false
|
||||
@State private var running = false
|
||||
@@ -5217,12 +5227,48 @@ private struct WorkbenchAccountManagerView: View {
|
||||
SecureField("Password", text: $password)
|
||||
}
|
||||
if action == .grant || action == .revoke {
|
||||
TextField("Database", text: $databaseName)
|
||||
Picker("Privilege", selection: $privilege) {
|
||||
ForEach(privileges, id: \.self) { item in
|
||||
Text(item).tag(item)
|
||||
Picker("Privilege scope", selection: $privilegeScope) {
|
||||
Text("Schema").tag("Schema")
|
||||
Text("Global").tag("Global")
|
||||
}
|
||||
if privilegeScope == "Schema" {
|
||||
TextField("Schema name", text: $databaseName)
|
||||
.help("Enter an existing database name. Privileges apply to all objects in this schema.")
|
||||
} else {
|
||||
Text("Global privileges affect every database on this server. Review carefully before applying.")
|
||||
.foregroundStyle(.orange)
|
||||
}
|
||||
Picker("Role preset", selection: $selectedRole) {
|
||||
ForEach(rolePresets.map { $0.0 }, id: \.self) { role in
|
||||
Text(role).tag(role)
|
||||
}
|
||||
}
|
||||
.onChange(of: selectedRole) { _, newRole in
|
||||
if let preset = rolePresets.first(where: { $0.0 == newRole }), newRole != "Custom" {
|
||||
selectedPrivileges = Set(preset.2)
|
||||
}
|
||||
}
|
||||
Text("Select the privileges to \(action == .grant ? "grant" : "revoke")")
|
||||
.font(.headline)
|
||||
LazyVGrid(columns: [GridItem(.adaptive(minimum: 165), spacing: 10)], alignment: .leading, spacing: 12) {
|
||||
ForEach(privileges, id: \.self) { item in
|
||||
Toggle(item, isOn: Binding(
|
||||
get: { selectedPrivileges.contains(item) },
|
||||
set: { enabled in
|
||||
if enabled { selectedPrivileges.insert(item) }
|
||||
else { selectedPrivileges.remove(item) }
|
||||
selectedRole = "Custom"
|
||||
}
|
||||
))
|
||||
.toggleStyle(.checkbox)
|
||||
}
|
||||
}
|
||||
HStack {
|
||||
Button("Select All") { selectedPrivileges = Set(privileges); selectedRole = "Custom" }
|
||||
Button("Clear") { selectedPrivileges.removeAll(); selectedRole = "Custom" }
|
||||
Spacer()
|
||||
Text("\(selectedPrivileges.count) selected").foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
}
|
||||
.formStyle(.grouped)
|
||||
@@ -5241,7 +5287,7 @@ private struct WorkbenchAccountManagerView: View {
|
||||
}
|
||||
}
|
||||
.padding(20)
|
||||
.frame(width: 590)
|
||||
.frame(minWidth: 650, idealWidth: 760, minHeight: 520)
|
||||
.onAppear {
|
||||
if let selectedAccount {
|
||||
let parts = selectedAccount.split(separator: "\u{001f}", omittingEmptySubsequences: false)
|
||||
@@ -5285,15 +5331,23 @@ private struct WorkbenchAccountManagerView: View {
|
||||
case .unlock:
|
||||
return ("ALTER USER \(account) ACCOUNT UNLOCK", "ALTER USER \(account) ACCOUNT UNLOCK")
|
||||
case .grant, .revoke:
|
||||
guard !databaseName.isEmpty,
|
||||
databaseName.unicodeScalars.allSatisfy({ allowed.contains($0) }),
|
||||
privileges.contains(privilege) else {
|
||||
throw AccountError.invalid("Enter a valid database name and privilege.")
|
||||
guard !selectedPrivileges.isEmpty, selectedPrivileges.allSatisfy({ privileges.contains($0) }) else {
|
||||
throw AccountError.invalid("Select at least one privilege.")
|
||||
}
|
||||
let db = "`\(databaseName)`.*"
|
||||
let target: String
|
||||
if privilegeScope == "Global" {
|
||||
target = "*.*"
|
||||
} else {
|
||||
guard !databaseName.isEmpty,
|
||||
databaseName.unicodeScalars.allSatisfy({ allowed.contains($0) }) else {
|
||||
throw AccountError.invalid("Enter a valid schema name.")
|
||||
}
|
||||
target = "`\(databaseName.replacingOccurrences(of: "`", with: "``"))`.*"
|
||||
}
|
||||
let rights = selectedPrivileges.sorted().joined(separator: ", ")
|
||||
let command = action == .grant
|
||||
? "GRANT \(privilege) ON \(db) TO \(account)"
|
||||
: "REVOKE \(privilege) ON \(db) FROM \(account)"
|
||||
? "GRANT \(rights) ON \(target) TO \(account)"
|
||||
: "REVOKE \(rights) ON \(target) FROM \(account)"
|
||||
return (command, command)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user