]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blobdiff - lib/rbot/core/webservice.rb
fix: TCPSocked.gethostbyname is deprecated
[user/henk/code/ruby/rbot.git] / lib / rbot / core / webservice.rb
index c3e61f49e2be43983d20b5e7c3004bcfda0bd3c8..6f90c574717794bcef204f0b645c795ab9cf1405 100644 (file)
@@ -17,6 +17,8 @@ require 'webrick/https'
 require 'openssl'
 require 'cgi'
 require 'json'
+require 'erb'
+require 'ostruct'
 
 module ::Irc
 class Bot
@@ -73,15 +75,19 @@ class Bot
             if botuser and botuser.password == password
               @source = botuser
               true
+            else
+              false
             end
-            false
           else
             true # no need to request auth at this point
           end
         }
 
         @path = req.path
-        debug '@path = ' + @path.inspect
+
+        @load_path = [File.join(Config::datadir, 'web')]
+        @load_path += @bot.plugins.core_module_dirs
+        @load_path += @bot.plugins.plugin_dirs
       end
 
       def parse_query(query)
@@ -123,6 +129,27 @@ class Bot
       def send_html(body, status=200)
         send_response(body, status, 'text/html')
       end
+
+      # Expands a relative filename to absolute using a list of load paths.
+      def get_load_path(filename)
+        @load_path.each do |path|
+          file = File.join(path, filename) 
+          return file if File.exists?(file)
+        end
+      end
+
+      # Renders a erb template and responds it
+      def render(template, args={})
+        file = get_load_path template
+        if not file
+          raise 'template not found: ' + template
+        end
+
+        tmpl = ERB.new(IO.read(file))
+        ns = OpenStruct.new(args)
+        body = tmpl.result(ns.instance_eval { binding })
+        send_html(body, 200)
+      end
     end
 
     # works similar to a message mapper but for url paths
@@ -216,7 +243,7 @@ class Bot
         tmpl = @templates[index]
         raise "Botmodule #{botmodule.name} tried to unmap #{tmpl.inspect} that was handled by #{tmpl.botmodule}" unless tmpl.botmodule == botmodule.name
         debug "Unmapping #{tmpl.inspect}"
-        @templates[handle] = nil
+        @templates[index] = nil
         @templates.clear unless @templates.compact.size > 0
       end
 
@@ -351,6 +378,11 @@ class DispatchServlet < WEBrick::HTTPServlet::AbstractServlet
     begin
       m = WebMessage.new(@bot, req, res)
       @bot.web_dispatcher.handle m
+    rescue WEBrick::HTTPStatus::Unauthorized
+      res.status = 401
+      res['Content-Type'] = 'text/plain'
+      res.body = 'Authentication Required!'
+      error 'authentication error (wrong password)'
     rescue
       res.status = 500
       res['Content-Type'] = 'text/plain'
@@ -388,6 +420,10 @@ class WebServiceModule < CoreBotModule
     :requires_rescan => true,
     :desc => 'Host the web service will bind on')
 
+  Config.register Config::StringValue.new('webservice.url',
+    :default => 'http://127.0.0.1:7268',
+    :desc => 'The public URL of the web service.')
+
   Config.register Config::BooleanValue.new('webservice.ssl',
     :default => false,
     :requires_rescan => true,
@@ -495,10 +531,15 @@ class WebServiceModule < CoreBotModule
     end
 
     command = m.post['command']
+    if command.empty?
+      m.send_plaintext('wrong syntax', 400)
+      return
+    end
+
     if not m.source
       botuser = Auth::defaultbotuser
     else
-      botuser = m.source.botuser
+      botuser = m.source
     end
     netmask = '%s!%s@%s' % [botuser.username, botuser.username, m.client]
 
@@ -508,6 +549,8 @@ class WebServiceModule < CoreBotModule
     message = Irc::PrivMessage.new(@bot, nil, user, @bot.myself, command)
 
     res = @bot.plugins.irc_delegate('privmsg', message)
+    # TODO if delegation failed due to wrong auth, it should be reported
+    # as an error, not 200 OK
 
     if m.req['Accept'] == 'application/json'
       { :reply => user.response }