Skip to content

Instantly share code, notes, and snippets.

@dominikh
Created October 9, 2012 08:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dominikh/3857485 to your computer and use it in GitHub Desktop.
Save dominikh/3857485 to your computer and use it in GitHub Desktop.
module Cinch
module Plugin
module ClassMethods
def enable_acl
hook(:pre, :for => [:match], :method => lambda {|m| check_acl(m)})
end
end
def check_acl(message)
shared[:acl].check(message, self)
end
end
end
module Cinch
module Extensions
class ACL
def initialize
@defaults = {:authname => {}, :channel => {}}
@acls = {
:authname => Hash.new {|h, k| h[k] = {}},
:channel => Hash.new {|h, k| h[k] = {}},
}
end
# @param [:authname, :channel] type
# @param [Class] plugin
# @param [:allow, :disallow] value
def set_default(type, plugin, value)
@defaults[type][plugin] = value
end
# @param [:authname, :channel] type
# @param [Class] plugin
# @param [String] name
# @return [void]
def allow(type, plugin, name)
if type != :authname && type != :channel
raise ArgumentError, "type must be one of [:authname, :channel]"
end
@acls[type][plugin][name] = :allow
end
# @param [:authname, :channel] type
# @param [Class] plugin
# @param [String] name
# @return [void]
def disallow(type, plugin, name)
if type != :authname && type != :channel
raise ArgumentError, "type must be one of [:authname, :channel]"
end
@acls[type][plugin][name] = :disallow
end
# @param [Message] message
# @param [Plugin] plugin
# @return [Boolean]
def check(message, plugin)
channel_name = message.channel && message.channel.name.irc_downcase(message.bot.irc.isupport["CASEMAPPING"])
authname_name = message.user && message.user.authname
authname_allowed = get_acl(plugin, :authname, authname_name) == :allow
channel_allowed = channel_name.nil? || get_acl(plugin, :channel, channel_name) == :allow
authname_allowed && channel_allowed
end
private
# @param [Plugin] plugin
# @param [:authname, :channel] type
# @param [String] name
# @return [:allow, :disallow]
def get_acl(plugin, type, name)
plugin = plugin.class
@acls[type][plugin][name] || @defaults[type][plugin] || @defaults[type][nil]
end
end
end
end
class ExamplePlugin
include Cinch::Plugin
enable_acl
# ...
end
bot = Cinch::Bot.new do
configure do |c|
# ...
# Generally, allow all plugins for all channels
acl.set_default(:channel, nil, :allow)
# Generally, disallow ExamplePlugin for all channels
acl.set_default(:channel, ExamplePlugin, :disallow)
# Allow ExamplePlugin in channels #foo and #bar
["#foo", "#bar"].each do |channel|
acl.allow(:channel, ExamplePlugin, channel)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment