diff --git a/lib/tapatalker.rb b/lib/tapatalker.rb index 9001d2d..18904f5 100644 --- a/lib/tapatalker.rb +++ b/lib/tapatalker.rb @@ -29,6 +29,12 @@ set :discourse_api_key, CONFIG.fetch( 'discourse_api_key' ) set :tapatalk_api, CONFIG.fetch( 'tapatalk_url', nil ) set :tapatalk_api_key, CONFIG.fetch( 'tapatalk_api_key', nil ) + +before do + # Pass through all cookies to the discourse instance + discourse( request.cookies ) +end + helpers do # Use this as our entry point @@ -43,7 +49,7 @@ helpers do method, arguments = XMLRPC::Marshal.load_call(xml) method = "xmlrpc_#{method.gsub(/([A-Z])/, '_ ').downcase}" - puts "method = #{method}, args = #{arguments.inspect}" + puts "method = #{method}, args = #{ method =~ /login/ ? "*REDACTED*" : arguments.inspect }" # Check if method exists if(respond_to?(method)) @@ -138,14 +144,13 @@ helpers do # Try to keep this instance around for as long as possible... # TODO: To keep it around, push into Rack::Session, or cookies? Some sort of # long-lived store. Can go away with process restarts, of course. - def discourse - uri = settings.discourse_api - uri = URI.parse(uri) unless uri.is_a?( URI::Generic ) + def discourse( cookies = {} ) @discourse ||= begin + uri = settings.discourse_api + uri = URI.parse(uri) unless uri.is_a?( URI::Generic ) client = DiscourseApi::Client.new( uri.host, uri.port, uri.scheme ) client.api_key = settings.discourse_api_key - # client.api_username = # session[:username] # ? - + client.cookies = cookies client end end @@ -200,7 +205,7 @@ helpers do # "ban_delete_type" => "none", # TODO "inappreg" => "0", # TODO - "inappsignin" => "0", # TODO - HIGH PRIORITY + "inappsignin" => "1", "ignore_user" => "0", # TODO # These are API level 4 items. Ignore for now. @@ -246,11 +251,69 @@ helpers do # "hide_forum_id" => "", # "reg_url" => "register.php", - # "sign_in" => "1", + "sign_in" => "0", # what does this do? # "stats" => {"user"=>320812, "topic"=>233040, "post"=>2389071} } respond_xmlrpc( result ) end + + # TODO! Very important + def xmlrpc_login( user = nil, pass = nil, anonymous = false, push = '1' ) + + return respond_xmlrpc( + 'result' => false, + 'result_text' => binary_xmlrpc( 'Anonymous login not supported' ) + ) if anonymous + + # We need to send on the cookies we received from discourse, and ensure they're + # passed in for future API requests + + # we need one of these to play with the session API + if discourse.csrf_token.nil? + discourse.csrf_token = discourse.session_csrf({}).fetch("csrf") + end + + # We raise if session creation fails + user_info = begin + rsp = discourse.session_create( :login => user, :password => pass ) + return respond_xmlrpc( 'result' => false, 'result_text' => binary_xmlrpc( rsp['error'] ) ) if rsp['error'] + + rsp + rescue => err + puts err.inspect + puts err.backtrace.join("\n") + return respond_xmlrpc( 'result' => false ) + end + + # We can just proxy the entire cookie over untouched + headers "Set-Cookie" => discourse.last_response['Set-Cookie'] + + # user = user_info.fetch("user") + + respond_xmlrpc( + 'result' => true, + # 'user_id' => user["id"], # api level 4 + # 'username' => binary_xmlrpc( "username" ), # api level 4 + # 'usergroup_id' => [], # api level 4 + # 'email' => binary_xmlrpc( "" ) # api level 4 # not sent by discourse + # 'icon_url' => make_avatar_url( user["avatar_template"] ), # api level 4 + # 'post_count' => , # api level 4 # discourse gives back stats with action_type and count members + 'can_pm' => false, # TODO! + 'can_send_pm' => false, # TODO! # can_send_private_message_to_user is always false...? + 'can_moderate' => false, # TODO! user["moderator"] + # can_search => true, # api level 4 + # can_whosonline => true, # api level 4 + # can_profile => true, # api level 4 + 'can_upload_avatar' => false, # TODO + # push_type ... + ) + end + + # also TODO + def xmlrpc_logout_user + discourse.session_destroy({}) + respond_xmlrpc( 'result' => true ) + end # Ignore forum_id for now. Naughty naughty. def xmlrpc_get_forum( return_description = nil, forum_id = nil) @@ -279,8 +342,6 @@ helpers do tmp } - - pp result respond_xmlrpc( result ) end @@ -329,8 +390,6 @@ helpers do # TODO: Need to respect pagination, restrict to just one category forum_info = discourse.category(:category_id => forum_id) - pp forum_info - categories = forum_info.fetch( "categories" ) users = forum_info["users"] @@ -370,8 +429,6 @@ helpers do build_tapatalk_topic( hsh, :users => users, :categories => categories ) } - pp result - respond_xmlrpc( result ) end @@ -428,16 +485,6 @@ helpers do respond_xmlrpc( result ) end - # TODO! Very important - def xmlrpc_login( user = nil, pass = nil, anonymous = false, push = '1' ) - respond_xmlrpc( 'result' => false, 'result_text' => "Login not implemented yet" ) - end - - # also TODO - def xmlrpc_logout_user - nil - end - # def get_smilies # TODO - not a priority # end