connection updates
This commit is contained in:
+66
-12
@@ -5179,6 +5179,16 @@ private struct WorkbenchAccountManagerView: View {
|
|||||||
@State private var password = ""
|
@State private var password = ""
|
||||||
@State private var databaseName = ""
|
@State private var databaseName = ""
|
||||||
@State private var privilege = "SELECT"
|
@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 previewSQL = ""
|
||||||
@State private var confirm = false
|
@State private var confirm = false
|
||||||
@State private var running = false
|
@State private var running = false
|
||||||
@@ -5217,11 +5227,47 @@ private struct WorkbenchAccountManagerView: View {
|
|||||||
SecureField("Password", text: $password)
|
SecureField("Password", text: $password)
|
||||||
}
|
}
|
||||||
if action == .grant || action == .revoke {
|
if action == .grant || action == .revoke {
|
||||||
TextField("Database", text: $databaseName)
|
Picker("Privilege scope", selection: $privilegeScope) {
|
||||||
Picker("Privilege", selection: $privilege) {
|
Text("Schema").tag("Schema")
|
||||||
ForEach(privileges, id: \.self) { item in
|
Text("Global").tag("Global")
|
||||||
Text(item).tag(item)
|
|
||||||
}
|
}
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5241,7 +5287,7 @@ private struct WorkbenchAccountManagerView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(20)
|
.padding(20)
|
||||||
.frame(width: 590)
|
.frame(minWidth: 650, idealWidth: 760, minHeight: 520)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
if let selectedAccount {
|
if let selectedAccount {
|
||||||
let parts = selectedAccount.split(separator: "\u{001f}", omittingEmptySubsequences: false)
|
let parts = selectedAccount.split(separator: "\u{001f}", omittingEmptySubsequences: false)
|
||||||
@@ -5285,15 +5331,23 @@ private struct WorkbenchAccountManagerView: View {
|
|||||||
case .unlock:
|
case .unlock:
|
||||||
return ("ALTER USER \(account) ACCOUNT UNLOCK", "ALTER USER \(account) ACCOUNT UNLOCK")
|
return ("ALTER USER \(account) ACCOUNT UNLOCK", "ALTER USER \(account) ACCOUNT UNLOCK")
|
||||||
case .grant, .revoke:
|
case .grant, .revoke:
|
||||||
guard !databaseName.isEmpty,
|
guard !selectedPrivileges.isEmpty, selectedPrivileges.allSatisfy({ privileges.contains($0) }) else {
|
||||||
databaseName.unicodeScalars.allSatisfy({ allowed.contains($0) }),
|
throw AccountError.invalid("Select at least one privilege.")
|
||||||
privileges.contains(privilege) else {
|
|
||||||
throw AccountError.invalid("Enter a valid database name and 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
|
let command = action == .grant
|
||||||
? "GRANT \(privilege) ON \(db) TO \(account)"
|
? "GRANT \(rights) ON \(target) TO \(account)"
|
||||||
: "REVOKE \(privilege) ON \(db) FROM \(account)"
|
: "REVOKE \(rights) ON \(target) FROM \(account)"
|
||||||
return (command, command)
|
return (command, command)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user