# Copyright (C) 2003-2005 Kouichirou Eto, All rights reserved.

$LOAD_PATH << "../../lib" unless $LOAD_PATH.include?("../../lib")
begin
  require "qwik/typekey"
  $have_typekey = true
rescue LoadError
  $have_typekey = false
end

module Qwik
  class Action
    # ============================== show typekey
    def act_typekey
      if @req.query.length == 0
	return typekey_redirect_to_typekey
      end

      sitetoken = typekey_get_sitetoken
      return c_nerror(_("Can not use.")) if sitetoken.nil?
      
      tk = TypeKey.new(sitetoken, '1.1')
      key = typekey_get_publickey(tk)

      email = @req.query["email"]
      name  = @req.query["name"]
      nick  = @req.query["nick"]
      ts    = @req.query["ts"]    # time stamp
      sig   = @req.query["sig"]
      # <email>::<name>::<nick>::<ts>::<site-token>
      #qp email, name, nick, ts, sig
      begin
	tk.verify(email, name, nick, ts, sig)
      rescue VerifyFailed
	return typekey_page_verify_failed
      rescue TimeOutError
	return typekey_page_time_out
      end

      sid = session_store(email)
      @res.set_cookie("sid", sid) # Set Session id by cookie

      return typekey_page_login_succeed
    end

    def typekey_redirect_to_typekey
      sitetoken = typekey_get_sitetoken
      return c_nerror(_("Can not use.")) if sitetoken.nil?

      tk = TypeKey.new(sitetoken, '1.1')

      # http://example.com/test/.typekey
      ret_url = c_relative_to_full(".typekey")
      url = tk.get_login_url(ret_url, true)
      #qp url
      return c_nredirect("Go TypeKey", url) # Go TypeKey login page.
    end

    def typekey_get_sitetoken
      file = @config.etc_dir.path+"typekey-sitetoken.txt"
      return if !file.exist?
      return file.open {|f| f.gets }.chomp
    end

    def typekey_get_publickey(tk)
      # Make cache timeout to 100 years. This is only for test.
     #tk.key_cache_timeout = 60 * 60 * 24 * 365 * 100
      tk.key_cache_timeout = 60 * 60 * 24 * 365 # 1 year
      cache_path = @config.cache_dir.path+"typekey-publickey.txt"
      tk.key_cache_path = cache_path.to_s
      key = tk.get_key
      return key
    end

    def typekey_page_verify_failed
      c_notice(_("Verify failed.")){
	_("Verify failed.")
      }
    end

    def typekey_page_time_out
      c_notice(_("Time out.")){
	_("Time out.")
      }
    end

    def typekey_page_login_succeed
      c_notice(_("Login")+" "+_("succeed"), "FrontPage.html"){
	[:p,_("Go next")," : ",[:a,{:href=>"FrontPage.html"},"FrontPage"]]
      }
    end
  end
end

if $0 == __FILE__
  require "t/test"
  require "qwik/qp"
  $debug = true
end

if $debug
  class TC_ActTypekey < Test::Unit::TestCase
    include TestSession

    def test_act_typekey
      t_add_user
      t_site_open # OPEN site

      session

      # test_get_sitetoken
      sitetoken = @action.typekey_get_sitetoken
      assert_equal(20, sitetoken.length)

      # See the FrontPage.
      session("/test/")
      assert_text("FrontPage", "title")

      # See the Login page.
      session("/test/.login") {|req|
	req.cookies.clear
      }
      assert_text("Login", "title")
      #pw("//div[@class='msg']")

      # Jump to TypeKey login page.
      session("/test/.typekey")
      assert_equal(302, @res.status)
      assert_match(%r|\Ahttps://www.typekey.com/t/typekey/login|,
		   @res["Location"])
      meta = @res.body.get_path("//meta[2]")
      assert_match(%r|url=https://www.typekey.com/t/typekey/login|,
		   meta[1][:content])

      # And returned from TypeKey login page.
      begin
	session("/test/.typekey?&ts=1111111111&email=guest@example.com&name=guestexample&nick=guest&sig=ttttttttttttttttttttttttttt=:LLLLLLLLLLLLLLLLLLLLLLLLLLL=")
	assert_text("Verify failed.", "title")
      rescue => e
	qp "failed.", e
      end

      begin
	session("/test/.typekey?&ts=1110026410&email=2005@eto.com&name=etocom&nick=eto&sig=tRUcIO6haAHv/vQSguPk2EijTrc=:LCUvoHCXFLaeO8SoldCKmFr2Guo=")
	assert_text("Time out.", "title")
      rescue => e
	qp "failed.", e
      end
    end

    def typekey_get_sitetoken
      file = @config.etc_dir.path+"typekey-sitetoken.txt"
      return file.open {|f| f.gets }.chomp
    end

    def test_typekey
      session
      sitetoken = "t"
      tk = TypeKey.new(sitetoken, '1.1')
      tk.key_cache_timeout = 60 * 60 * 24 * 200 # for test
      cache_path = @config.cache_dir.path+"typekey-publickey.txt"
      tk.key_cache_path = cache_path.to_s
      
      return_url = "http://e.com/.typekey"
      assert_equal("https://www.typekey.com/t/typekey/login?t=t&_return=http://e.com/.typekey&v=1.1", tk.get_login_url(return_url))
      assert_equal("https://www.typekey.com/t/typekey/login?t=t&need_email=1&_return=http://e.com/.typekey&v=1.1", tk.get_login_url(return_url, true))
      assert_equal("https://www.typekey.com/t/typekey/logout?_return=http://e.com/.typekey", tk.get_logout_url(return_url))

      begin
	key = tk.get_key
	assert_equal(["p", "q", "pub_key", "g"], key.keys)
      rescue
	qp "failed"
      end
    end

    def test_verify
      session
      sitetoken = @action.typekey_get_sitetoken
      tk = TypeKey.new(sitetoken, '1.1')
      tk.key_cache_timeout = 60 * 60 * 24 * 200 # for test
      cache_path = @config.cache_dir.path+"typekey-publickey.txt"
      tk.key_cache_path = cache_path.to_s

      ts = "1111111111"
      email = "guest@example.com"
      name = "guestexample"
      nick = "guest"
      sig = "ttttttttttttttttttttttttttt=:LLLLLLLLLLLLLLLLLLLLLLLLLLL="

      begin
	assert_raise(VerifyFailed){
	  result = tk.verify(email, name, nick, ts, sig)
	}
      rescue => e
	qp "failed", e
      end
    end
  end
end




