mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2026-03-28 15:00:06 +01:00
🐛 Refactor custom environment variables
This commit is contained in:
@@ -13,7 +13,7 @@ class RealShell: ShellProtocol, @unchecked Sendable {
|
|||||||
init(binPath: String) {
|
init(binPath: String) {
|
||||||
self.binPath = binPath
|
self.binPath = binPath
|
||||||
self._PATH = RealShell.getPath()
|
self._PATH = RealShell.getPath()
|
||||||
self._exports = ""
|
self._exports = [:]
|
||||||
}
|
}
|
||||||
|
|
||||||
private(set) var binPath: String
|
private(set) var binPath: String
|
||||||
@@ -38,8 +38,9 @@ class RealShell: ShellProtocol, @unchecked Sendable {
|
|||||||
/**
|
/**
|
||||||
Exports are additional environment variables set by the user via the custom configuration.
|
Exports are additional environment variables set by the user via the custom configuration.
|
||||||
These are populated when the configuration file is being loaded.
|
These are populated when the configuration file is being loaded.
|
||||||
|
These are now set via via Process.environment to avoid security issues, like shell injection.
|
||||||
*/
|
*/
|
||||||
internal var exports: String {
|
internal var exports: [String: String] {
|
||||||
get { shellQueue.sync { _exports } }
|
get { shellQueue.sync { _exports } }
|
||||||
set { shellQueue.sync { _exports = newValue } }
|
set { shellQueue.sync { _exports = newValue } }
|
||||||
}
|
}
|
||||||
@@ -49,7 +50,7 @@ class RealShell: ShellProtocol, @unchecked Sendable {
|
|||||||
/** Thread-safe access to PATH and exports is ensured via this queue. */
|
/** Thread-safe access to PATH and exports is ensured via this queue. */
|
||||||
private let shellQueue = DispatchQueue(label: "com.nicoverbruggen.phpmon.shell_queue")
|
private let shellQueue = DispatchQueue(label: "com.nicoverbruggen.phpmon.shell_queue")
|
||||||
private var _PATH: String
|
private var _PATH: String
|
||||||
private var _exports: String
|
private var _exports: [String: String]
|
||||||
|
|
||||||
// MARK: - Methods
|
// MARK: - Methods
|
||||||
|
|
||||||
@@ -75,22 +76,23 @@ class RealShell: ShellProtocol, @unchecked Sendable {
|
|||||||
This process still needs to be started, or one can attach output handlers.
|
This process still needs to be started, or one can attach output handlers.
|
||||||
*/
|
*/
|
||||||
private func getShellProcess(for command: String) -> Process {
|
private func getShellProcess(for command: String) -> Process {
|
||||||
var completeCommand = ""
|
let completeCommand = "export PATH=\(binPath):$PATH && " + command
|
||||||
|
|
||||||
// Basic export (PATH)
|
|
||||||
completeCommand += "export PATH=\(binPath):$PATH && "
|
|
||||||
|
|
||||||
// Put additional exports (as defined by the user) in between
|
|
||||||
if !self.exports.isEmpty {
|
|
||||||
completeCommand += "\(self.exports) && "
|
|
||||||
}
|
|
||||||
|
|
||||||
completeCommand += command
|
|
||||||
|
|
||||||
let task = Process()
|
let task = Process()
|
||||||
task.launchPath = self.launchPath
|
task.launchPath = self.launchPath
|
||||||
task.arguments = ["--noprofile", "-norc", "--login", "-c", completeCommand]
|
task.arguments = ["--noprofile", "-norc", "--login", "-c", completeCommand]
|
||||||
|
|
||||||
|
// Set user-defined environment variables safely via Process API
|
||||||
|
// instead of interpolating them into the shell command string.
|
||||||
|
let currentExports = self.exports
|
||||||
|
if !currentExports.isEmpty {
|
||||||
|
var env = ProcessInfo.processInfo.environment
|
||||||
|
for (key, value) in currentExports {
|
||||||
|
env[key] = value
|
||||||
|
}
|
||||||
|
task.environment = env
|
||||||
|
}
|
||||||
|
|
||||||
return task
|
return task
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,9 +150,7 @@ class RealShell: ShellProtocol, @unchecked Sendable {
|
|||||||
These will be exported when a command is executed.
|
These will be exported when a command is executed.
|
||||||
*/
|
*/
|
||||||
public func setCustomEnvironmentVariables(_ variables: [String: String]) {
|
public func setCustomEnvironmentVariables(_ variables: [String: String]) {
|
||||||
self.exports = variables.map { (key, value) in
|
self.exports = variables
|
||||||
return "export \(key)=\(value)"
|
|
||||||
}.joined(separator: "&&")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Shellable Protocol
|
// MARK: - Shellable Protocol
|
||||||
|
|||||||
@@ -14,14 +14,6 @@ struct CustomPrefs: Decodable {
|
|||||||
let services: [String]?
|
let services: [String]?
|
||||||
let environmentVariables: [String: String]?
|
let environmentVariables: [String: String]?
|
||||||
|
|
||||||
var exportAsString: String {
|
|
||||||
return self.environmentVariables!
|
|
||||||
.map { (key, value) in
|
|
||||||
return "export \(key)=\(value)"
|
|
||||||
}
|
|
||||||
.joined(separator: "&&")
|
|
||||||
}
|
|
||||||
|
|
||||||
public func hasPresets() -> Bool {
|
public func hasPresets() -> Bool {
|
||||||
return self.presets != nil && !self.presets!.isEmpty
|
return self.presets != nil && !self.presets!.isEmpty
|
||||||
}
|
}
|
||||||
@@ -89,7 +81,7 @@ extension Preferences {
|
|||||||
if customPreferences.hasEnvironmentVariables() {
|
if customPreferences.hasEnvironmentVariables() {
|
||||||
Log.info("Configuring the additional exports...")
|
Log.info("Configuring the additional exports...")
|
||||||
if let shell = App.shared.container.shell as? RealShell {
|
if let shell = App.shared.container.shell as? RealShell {
|
||||||
shell.exports = customPreferences.exportAsString
|
shell.exports = customPreferences.environmentVariables ?? [:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
Reference in New Issue
Block a user