connection updates

This commit is contained in:
Mark Gregory
2026-10-19 11:41:44 +01:00
parent a34faa3b29
commit 07c7e7d328
+66 -12
View File
@@ -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)
}
}