Classes/Command.ps1
# Some custom exceptions dealing with executing commands class CommandException : Exception { CommandException() {} CommandException([string]$Message) : base($Message) {} } class CommandNotFoundException : CommandException { CommandNotFoundException() {} CommandNotFoundException([string]$Message) : base($Message) {} } class CommandFailed : CommandException { CommandFailed() {} CommandFailed([string]$Message) : base($Message) {} } class CommandDisabled : CommandException { CommandDisabled() {} CommandDisabled([string]$Message) : base($Message) {} } class CommandNotAuthorized : CommandException { CommandNotAuthorized() {} CommandNotAuthorized([string]$Message) : base($Message) {} } class CommandRequirementsNotMet : CommandException { CommandRequirementsNotMet() {} CommandRequirementsNotMet([string]$Message) : base($Message) {} } # Represent a command that can be executed class Command { # Unique (to the plugin) name of the command [string]$Name #[hashtable]$Subcommands = @{} [string]$Description [Trigger]$Trigger [string[]]$Usage [bool]$KeepHistory = $true [bool]$HideFromHelp = $false [bool]$AsJob = $true # Fully qualified name of a cmdlet or function in a module to execute [string]$ModuleCommand [string]$ManifestPath [System.Management.Automation.FunctionInfo]$FunctionInfo [AccessFilter]$AccessFilter = [AccessFilter]::new() [bool]$Enabled = $true # Execute the command in a PowerShell job and return the running job [object]Invoke([ParsedCommand]$ParsedCommand, [bool]$InvokeAsJob = $this.AsJob) { $outer = { [cmdletbinding()] param( [hashtable]$Options ) Import-Module -Name $Options.ManifestPath -Scope Local -Force -Verbose:$false -WarningAction SilentlyContinue $named = $Options.NamedParameters $pos = $Options.PositionalParameters $func = $Options.Function & $func @named @pos } [string]$sb = [string]::Empty $options = @{ NamedParameters = $ParsedCommand.NamedParameters PositionalParameters = $ParsedCommand.PositionalParameters ManifestPath = $this.ManifestPath Function = $this.FunctionInfo } if ($this.FunctionInfo) { $options.FunctionInfo = $this.FunctionInfo } if ($InvokeAsJob) { $fdt = Get-Date -Format FileDateTimeUniversal $jobName = "$($this.Name)_$fdt" $jobParams = @{ Name = $jobName ScriptBlock = $outer ArgumentList = $options } return (Start-Job @jobParams) } else { $errors = $null $information = $null $warning = $null New-Variable -Name opts -Value $options $cmdParams = @{ ScriptBlock = $outer ArgumentList = $Options ErrorVariable = 'errors' InformationVariable = 'information' WarningVariable = 'warning' Verbose = $true NoNewScope = $true } $output = Invoke-Command @cmdParams return @{ Error = @($errors) Information = @($Information) Output = $output Warning = @($warning) } } } [bool]IsAuthorized([string]$UserId, [RoleManager]$RoleManager) { $perms = $RoleManager.GetUserPermissions($UserId) foreach ($perm in $perms) { $result = $this.AccessFilter.Authorize($perm.Name) if ($result.Authorized) { return $true } } return $false } [void]Activate() { $this.Enabled = $true } [void]Deactivate() { $this.Enabled = $false } # [void]AddSubCommand([Command]$Command) { # $subCommandName = $null # if ($Command.Name.Contains('-')) { # $subCommandName = $Command.Name.Split('-')[0] # } elseIf ($Command.Name.Contains('_')) { # $subCommandName = $Command.Name.Split('_')[0] # } # if ($subCommandName) { # if (-not $this.Subcommands.ContainsKey($subCommandName)) { # $this.Subcommands.Add($subCommandName, $Command) # } # } # } [void]AddPermission([Permission]$Permission) { $this.AccessFilter.AddPermission($Permission) } [void]RemovePermission([Permission]$Permission) { $this.AccessFilter.RemovePermission($Permission) } # Returns TRUE/FALSE if this command matches a parsed command from the chat network [bool]TriggerMatch([ParsedCommand]$ParsedCommand, [bool]$CommandSearch = $true) { switch ($this.Trigger.Type) { 'Command' { if ($CommandSearch) { # Command tiggers only work with normal messages received from chat network if ($ParsedCommand.OriginalMessage.Type -eq [MessageType]::Message) { if ($this.Trigger.Trigger -eq $ParsedCommand.Command) { return $true } else { return $false } } else { return $false } } else { return $false } } 'Event' { if ($this.Trigger.MessageType -eq $ParsedCommand.OriginalMessage.Type) { if ($this.Trigger.MessageSubtype -eq $ParsedCommand.OriginalMessage.Subtype) { return $true } } else { return $false } } 'Regex' { if ($ParsedCommand.CommandString -match $this.Trigger.Trigger) { return $true } else { return $false } } } return $false } } |