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

module Qwik
  class Action
    def getpass_form
      [
	[:h2, _("You will get the password by e-mail.")],
	[:p, _("Please input your mail address.")],
	[:form, {:action=>".getpass",
	    :style=>"text-align: center; margin: 32px 0 48px;"},
	  [:div, {:style=>"margin: 16px 0 8px"},
	    [:em, _("Mail address"), ": "], 
	    [:input, {:name=>"mail", :size=>"40", :istyle=>"3"}]],
	  [:div, {:class=>"rightbutton"},
	    [:input, {:type=>"submit", :value=>_("Send")}]]],
	[:p, [:a, {:href=>".login"}, _("Go back to Login")]],
      ]
    end

    def getpass_not_member(user)
      c_nerror(_("Member Only")) {[
	  [:p, _("You input this e-mail address as user id."), [:br],
	    [:strong, user]],
	  [:p, _("This user id is not a member of this group."), [:br],
	    [:strong, @site.ml]],
	  [:p, _("Only the member of this group can get password.")],
	  [:p, [:a, {:href=>".getpass"}, _("Go back")]],
	]}
    end

    def act_getpass # send pass by e-mail
      mail = @req.query["mail"]

      if mail.nil?
	user = @req.user
	if !@site.is_open? && user && !@site.member.exist?(user)
	  raise RequireMember
	end

	return c_notice(_("Get Password")){
	  getpass_form
	}
      end

      if !MailAddress.new(mail).valid?
	return c_nerror("invalid mail address"){[
	    [:p, [:em, mail], " : ", _("The mail address format is wrong."),
	      [:br], _("Please confirm the input again.")],
	    [:p, [:a, {:href=>".getpass"}, _("Get Password")], ": ",
	      _("Please access again.")]
	  ]}
      end

      if !@site.is_open? && !@site.member.exist?(mail)
	return getpass_not_member(mail)
      end

      passmail = generate_password_mail(mail)
      sendmail = Sendmail.new(@config)
      begin
	sendmail.sendmail(passmail)
      rescue
	return c_nerror("Send Password Error"){[
	    [:p, _("Send failed for system error.")],
	    [:p, _("Please contact administrator.")],
	    [:hr],
	    [:p, [:a, {:href=>".login"}, _("Go back to Login")]],
	  ]}
      end

      return c_notice(_("Send Password done")){[
	  [:p, {:style=>"margin: 1.5em 0"},
	    _("I send the password to this mail address."), [:br],
	    _("Please check your mailbox.")],
	  [:p, {:style=>"margin: 1.5em 0"}, [:em, mail]],
	  [:hr],
	  [:p, [:a, {:href=>".login"}, _("Go back to Login")]],
	]}
    end

    def generate_password_mail(user)
      user = user.to_s
      domainurl = @site.domainurl
      siteurl = @site.url
      gen = @memory.passgen
      password = gen.generate(user)

      mail = Mail.new
      mail.from = @site.ml
      mail.to = user
      mail.subject = domainurl+" におけるパスワード"
      msg = ""
      msg << "#{domainurl} におけるユーザー名とパスワードは、下記の通りです。\n"
      msg << "\n"
      msg << "ユーザー名:	#{user}\n"
      msg << "パスワード:	#{password}\n"
      msg << "\n"
      msg << "#{siteurl}.login に再度アクセスしてみてください。\n"
      msg << "\n"
      msg << "下記URLにアクセスすると、自動的にユーザー名とパスワードを入力します。\n"
      msg << "#{siteurl}.login?user=#{user}&pass=#{password}\n"
      mail.content = msg
      mail
    end
  end
end

if $0 == __FILE__
  $LOAD_PATH << "../../lib" unless $LOAD_PATH.include?("../../lib")
  require "t/test"
  $debug = true
end

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

    def test_private_site
      # See a page to get password, but in vain.
      session("/test/.getpass")
      assert_text("Member Only", "title")

      # But you can see the page without login.
      session("/test/.getpass") {|req|
	req.cookies.clear
      }
      assert_text("Get Password", "title")

      t_add_user
      assert_equal(",user@e.com,\n", @site["_SiteMember"].load)
      assert_equal(false, @site.is_open?)

      # See a page to get password.
      session("/test/.getpass")
      assert_text("Get Password", "title")
      assert_text("Get Password", "h1")
      assert_attr({"name"=>"mail", "istyle"=>"3", "size"=>"40"}, "input")
      assert_attr({"type"=>"submit", "value"=>"Send"}, "input[2]")

      # Check obsolete format.
      session("/test/GetPass.html")
      assert_text("Get Password", "title")

      # Invalid mail address
      session("/test/.getpass?mail=wrong@mail@address")
      assert_text("invalid mail address", "title")

      # You can not get pass if you are not a member.
      session("/test/.getpass?mail=guest@example.com")
      assert_text("Member Only", "title")

      # Input your mail address
      session("/test/.getpass?mail=user@e.com")
      assert_text("Send Password done", "title")
      assert_text("user@e.com", "em")
      assert_equal(["test@example.com", "user@e.com"], $smtp_sendmail[2..3])
      assert_match(/user@e.com/, $smtp_sendmail[4])
      assert_match(/95988593/, $smtp_sendmail[4])
      str = <<"EOS"
From: test@example.com
To: user@e.com
Subject: http://example.com/ =?iso-2022-jp?B?GyRCJEskKiQxJGslUSU5JW8hPCVJGyhC?=
Content-Type: text/plain; charset="ISO-2022-JP"

http://example.com/ におけるユーザー名とパスワードは、下記の通りです。

ユーザー名:	user@e.com
パスワード:	95988593

http://example.com/test/.login に再度アクセスしてみてください。

下記URLにアクセスすると、自動的にユーザー名とパスワードを入力します。
http://example.com/test/.login?user=user@e.com&pass=95988593

EOS
      assert_equal(str.sjistojis, $smtp_sendmail[4])
    end

    def test_open_site
      t_site_open

      # You can see the page.
      session("/test/.getpass")
      assert_text("Get Password", "title")

      # You can get any pass.
      session("/test/.getpass?mail=user@e.com")
      assert_text("Send Password done", "title")

      session("/test/.getpass?mail=guest@example.com")
      assert_text("Send Password done", "title")
    end
  end

  class TC_PasswordMailGenerator < Test::Unit::TestCase
    include TestSession

    def with_dir(sitename)
      dir = ("./"+sitename+"/").path
      dir.setup
      yield
      dir.teardown
    end

    def test_getpass_mail
      session("/test/")

      mail = @action.generate_password_mail("user@e.com")
      assert_equal("test@example.com", mail.from)
      assert_equal("user@e.com", mail.to)
      assert_equal("http://example.com/ におけるパスワード", mail.subject)
      str = <<"EOT"
http://example.com/ におけるユーザー名とパスワードは、下記の通りです。

ユーザー名:	user@e.com
パスワード:	95988593

http://example.com/test/.login に再度アクセスしてみてください。

下記URLにアクセスすると、自動的にユーザー名とパスワードを入力します。
http://example.com/test/.login?user=user@e.com&pass=95988593
EOT
      assert_equal(str, mail.content)

      with_dir("e.com"){
	session("/e.com/")
	assert_text("Member Only", "title")

	site = @memory.farm.get_site("e.com")
	site.member.add(DEFAULT_USER)

	session("/e.com/")
	assert_text("FrontPage", "title")

        @action.instance_eval { @site = site }
        mail = @action.generate_password_mail("user@e.com")
        assert_equal("info@e.com", mail.from)
        assert_equal("user@e.com", mail.to)
        assert_equal("http://e.com/ におけるパスワード", mail.subject)
        str = <<"EOT"
http://e.com/ におけるユーザー名とパスワードは、下記の通りです。

ユーザー名:	user@e.com
パスワード:	95988593

http://e.com/.login に再度アクセスしてみてください。

下記URLにアクセスすると、自動的にユーザー名とパスワードを入力します。
http://e.com/.login?user=user@e.com&pass=95988593
EOT
        assert_equal(str, mail.content)
      }
    end
  end
end
