UserTracking/UserTracking.psm1
param( $irc = $(PowerBot\Get-PowerBotIrcClient) ) Import-Module SQLitePSProvider -ErrorAction Stop ## NOTE: These might need to be configureable per network. The values given are for FreeNode: $NickServ = "NickServ" $Services = "services." ${ActiveUsers} = @{} ${PendingUsers} = @() # NOTE: PowerBot will create a "data:" drive if the "SQLite" module is present. if(!(Test-Path data:)) { Write-Warning "No data drive, UserTracking and Roles disabled" return } # So all we have to worry about is whether the Roles table is present if(!(Test-Path data:\Roles)) { New-Item data:\Roles -Value @{ Account="TEXT UNIQUE NOT NULL"; Roles="TEXT"; } } ################################################################################ ## These five functions serve as Authentication for FreeNode ## They are based on the fact that the user must be registered function Sync-Join { param($Source, $EventArgs) Write-Host "Sync Join: " $Nick if($irc.Nicknames -notcontains $Nick) { $irc.rfcWhoIs($Nick) } } function Sync-Part { param($Source, $EventArgs) Write-Host $EventArgs.Who "just parted" $EventArgs.Channel "saying" $EventArgs.PartMessage -fore DarkCyan if(${ActiveUsers}.ContainsKey($Nick)) { $null = ${ActiveUsers}.Remove($Nick) } } # function Sync-Who { # param($Source, $EventArgs) # Write-Host "Sync Who: " $EventArgs.Nick -fore DarkCyan # $irc.rfcWhoIs($EventArgs.Nick) # } function Sync-NickChange { param($Source, $EventArgs) # $irc.rfcWhoIs($Nick) Write-Host $EventArgs.OldNickname "is now" $EventArgs.NewNickname -fore DarkCyan if(${ActiveUsers}.ContainsKey($EventArgs.OldNickname)) { ${ActiveUsers}.($EventArgs.NewNickname) = ${ActiveUsers}.($EventArgs.OldNickname) $null = ${ActiveUsers}.Remove($EventArgs.OldNickname) } } # function Sync-Names { # param($Source, $EventArgs) # Write-Host "Sync Names: " $($EventArgs.UserList -join ' ') -fore DarkCyan # $Script:PendingUsers += @($EventArgs.UserList) # $Count = [Math]::Min(10, $Script:PendingUsers.Length) # foreach($i in 1..$Count) { # $Next, $Script:PendingUsers = $Script:PendingUsers # Write-Host "NAMES: WHOIS $Next + $($Script:PendingUsers.Length)" # $irc.rfcWhoIs($Next) # } # } function Sync-LoggedIn { # .Synopsis # Track the nicknames of logged-in users # .Description # For dancer (the IRCD for FreeNode) # As part of the WHOIS response, we get a Reply with ID 330 # Which maps the nick to the account name it's logged in as param($Source, $EventArgs) Write-Host ("'" + $EventArgs.Nick + "' is logged in as '" + $EventArgs.Account + "'") -fore DarkCyan ${ActiveUsers}.($EventArgs.Nick) = $EventArgs.Account Write-Host (${ActiveUsers} | Format-Table | Out-String) } ################################################################################ ## These functions map accounts to one or more roles ## And allow management of role-based access function Get-Role { #.Synopsis # Get the role(s) for a user account #.Description # Get the role(s) for the user. If the user doesn't have specified roles, # returns "User" for authenticated users, and "Guest" otherwise [CmdletBinding(DefaultParameterSetName="Nickname")] param( # The (Nickserv) account to fetch roles for [Parameter(Position=0, Mandatory=$True, ParameterSetName="Account")] $Account, # The current nickname [Parameter(Position=0, ParameterSetName="Nickname")] $Nick ) if($Nick) { Write-Host ("'" + (${ActiveUsers}.Keys -join "', '") + "' contains '" + $Nick + "' " + ${ActiveUsers}.ContainsKey($Nick)) if(${ActiveUsers}.ContainsKey($Nick)) { $Account = ${ActiveUsers}.$Nick Write-Host ("{0} = {1}" -f $Nick, $Account) } else { $irc.rfcWhoIs($Nick) } } if($Account) { if($Roles = (Get-Item -Path data:\Roles -filter "Account = '${Account}'").Roles -split "\s+") { @($Roles) } else { @("User") } } else { @("Guest") } } function Set-Role { [CmdletBinding(DefaultParameterSetName="Nickname")] param( # The (Nickserv) account to fetch roles for [Parameter(Position=0, Mandatory=$True, ParameterSetName="Account")] $Account, # The role(s) to assign ( [Parameter(Position=1, Mandatory=$true)] [ValidateScript({if($PowerBotUserRoles -contains $_){ $True } else { throw "$_ is not a valid Role. Please use one of: $PowerBotUserRoles"}})] [String[]]$Role ) if($Role -notcontains "User") { Write-Warning "The 'User' role was not included -- this user will not have access to default commands" } $Result = Set-Item data:\Roles -Filter "account = '$Account'" -Value @{Roles = $Role -join ' '} -Passthru -ErrorAction SilentlyContinue if(!$Result) { $Result = New-Item data:\Roles -Account $Account -Roles $($Role -join ' ') -ErrorAction SilentlyContinue } if($Result) { $Result.Roles -split "\s+" } } |