From ec5667193b7d1ee216e6389ca7693f3f3f1f6c20 Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Sun, 5 Jul 2015 15:57:24 +0200 Subject: [PATCH] add Callbacks --- lib/diaspora_federation.rb | 122 ++++-------------- lib/diaspora_federation/callbacks.rb | 29 +++++ spec/lib/diaspora_federation_spec.rb | 12 +- .../initializers/diaspora_federation.rb | 9 +- 4 files changed, 63 insertions(+), 109 deletions(-) create mode 100644 lib/diaspora_federation/callbacks.rb diff --git a/lib/diaspora_federation.rb b/lib/diaspora_federation.rb index 38efcf4..3f1229b 100644 --- a/lib/diaspora_federation.rb +++ b/lib/diaspora_federation.rb @@ -1,12 +1,20 @@ require "diaspora_federation/logging" +require "diaspora_federation/callbacks" require "diaspora_federation/web_finger" # diaspora* federation library module DiasporaFederation extend Logging + @callbacks = Callbacks.new %i( + person_webfinger_fetch + person_hcard_fetch + ) + class << self + attr_reader :callbacks + # the pod url # # @example with uri @@ -15,124 +23,38 @@ module DiasporaFederation # config.server_uri = AppConfig.pod_uri attr_accessor :server_uri - # the class to use as +Person+ - # - # @example - # config.person_class = Person - # - # This class must have the following class methods::: - # - # +find_local_by_diaspora_handle+: - # This should return a +Person+, which is on this pod and the account is not closed. - # - # +find_local_by_guid+: - # This should return a +Person+, which is on this pod and the account is not closed. - # - # This class must have the following instance methods or attributes::: - # - # +diaspora_handle+: the diaspora handle - # "user@server.example" - # - # +nickname+: the username on the pod - # "user" - # - # +guid+: the guid - # "0123456789abcdef" - # - # +serialized_public_key+: the public key of the person (DER-encoded PKCS#1 key) - # "-----BEGIN PUBLIC KEY----- - # ABCDEF== - # -----END PUBLIC KEY-----" - # - # +searchable+: if the person is searchable by name - # true - # - # +alias_url+: alias url to the profile - # "https://server.example/people/0123456789abcdef" - # - # +hcard_url+: url to the hcard - # "https://server.example/hcard/users/0123456789abcdef" - # - # +seed_url+: pod url - # "https://server.example/" - # - # +profile_url+: url to the profile - # "https://server.example/u/user" - # - # +atom_url+: url to the atom rss feed - # "https://server.example/public/user.atom" - # - # +salmon_url+: private receive url for salmon - # "https://server.example/receive/users/0123456789abcdef" - # - # +photo_large_url+: large photo - # "https://server.example/uploads/l.jpg" - # - # +photo_medium_url+: medium photo - # "https://server.example/uploads/m.jpg" - # - # +photo_small_url+: small photo - # "https://server.example/uploads/s.jpg" - # - # +full_name+: full name - # "User Name" - # - # +first_name+: first name - # "User" - # - # +last_name+: last name - # "Name" - attr_accessor :person_class - - def person_class=(klass) - @person_class = klass.nil? ? nil : klass.to_s - end - - def person_class - const_get(@person_class) - end - # configure the federation library # + # @example # DiasporaFederation.configure do |config| - # config.server_uri = "http://localhost:3000/" + # config.server_uri = URI("http://localhost:3000/") + # + # config.define_callbacks do + # # callback configuration + # end # end def configure yield self end + def define_callbacks(&block) + @callbacks.instance_eval(&block) + end + # validates if the engine is configured correctly # # called from after_initialize # @raise [ConfigurationError] if the configuration is incomplete or invalid def validate_config - configuration_error "missing server_uri" unless @server_uri.respond_to? :host - validate_class(@person_class, "person_class", %i( - find_local_by_diaspora_handle find_local_by_guid - diaspora_handle nickname guid serialized_public_key searchable - alias_url hcard_url seed_url profile_url atom_url salmon_url - photo_large_url photo_medium_url photo_small_url - full_name first_name last_name - )) + configuration_error "Missing server_uri" unless @server_uri.respond_to? :host + unless @callbacks.definition_complete? + configuration_error "Missing handlers for #{@callbacks.missing_handlers.join(', ')}" + end logger.info "successfully configured the federation library" end private - def validate_class(klass, name, methods) - configuration_error "missing #{name}" unless klass - entity = const_get(klass) - - return logger.warn "table for #{entity} doesn't exist, skip validation" unless entity.table_exists? - - methods.each {|method| entity_respond_to?(entity, name, method) } - end - - def entity_respond_to?(entity, name, method) - valid = entity.respond_to?(method) || entity.column_names.include?(method.to_s) || entity.method_defined?(method) - configuration_error "the configured class #{entity} for #{name} doesn't respond to #{method}" unless valid - end - def configuration_error(message) logger.fatal("diaspora federation configuration error: #{message}") raise ConfigurationError, message diff --git a/lib/diaspora_federation/callbacks.rb b/lib/diaspora_federation/callbacks.rb new file mode 100644 index 0000000..0de9d88 --- /dev/null +++ b/lib/diaspora_federation/callbacks.rb @@ -0,0 +1,29 @@ +module DiasporaFederation + class Callbacks + def initialize(events) + @events = events + @handlers = {} + end + + def on(event, &callback) + raise ArgumentError, "Undefined event #{event}" unless @events.include? event + raise ArgumentError, "Already defined event #{event}" if @handlers.has_key? event + + @handlers[event] = callback + end + + def trigger(event, *args) + raise ArgumentError, "Undefined event #{event}" unless @events.include? event + + @handlers[event].call(*args) + end + + def definition_complete? + missing_handlers.empty? + end + + def missing_handlers + @events - @handlers.keys + end + end +end diff --git a/spec/lib/diaspora_federation_spec.rb b/spec/lib/diaspora_federation_spec.rb index d81c0ec..72434c5 100644 --- a/spec/lib/diaspora_federation_spec.rb +++ b/spec/lib/diaspora_federation_spec.rb @@ -2,22 +2,20 @@ module DiasporaFederation describe DiasporaFederation do context "validate_config" do it "should validate the config" do - expect(DiasporaFederation).to receive(:validate_class) + expect(DiasporaFederation.callbacks).to receive(:definition_complete?).and_return(true) DiasporaFederation.validate_config end it "should fails if the server_uri is missing" do temp = DiasporaFederation.server_uri DiasporaFederation.server_uri = nil - expect { DiasporaFederation.validate_config }.to raise_error ConfigurationError + expect { DiasporaFederation.validate_config }.to raise_error ConfigurationError, "Missing server_uri" DiasporaFederation.server_uri = temp end - it "should fails if the person_class is missing" do - temp = DiasporaFederation.person_class - DiasporaFederation.person_class = nil - expect { DiasporaFederation.validate_config }.to raise_error ConfigurationError - DiasporaFederation.person_class = temp + it "should validate the config" do + expect(DiasporaFederation.callbacks).to receive(:definition_complete?).and_return(false) + expect { DiasporaFederation.validate_config }.to raise_error ConfigurationError, "Missing handlers for " end end end diff --git a/test/dummy/config/initializers/diaspora_federation.rb b/test/dummy/config/initializers/diaspora_federation.rb index 26026c4..198ad90 100644 --- a/test/dummy/config/initializers/diaspora_federation.rb +++ b/test/dummy/config/initializers/diaspora_federation.rb @@ -3,6 +3,11 @@ DiasporaFederation.configure do |config| # the pod url config.server_uri = URI("http://localhost:3000/") - # the class to be used for a person - config.person_class = Person + config.define_callbacks do + on :person_webfinger_fetch do |handle| + end + + on :person_hcard_fetch do |guid| + end + end end