summaryrefslogtreecommitdiff
path: root/test/soap/header/server.cgi
blob: f9739d0d159ad1bda0a9cbfbf900a00eed481353 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
require 'pstore'
require 'soap/rpc/cgistub'
require 'soap/header/simplehandler'


class AuthHeaderPortServer < SOAP::RPC::CGIStub
  PortName = 'http://tempuri.org/authHeaderPort'
  SupportPortName = 'http://tempuri.org/authHeaderSupportPort'
  MyHeaderName = XSD::QName.new("http://tempuri.org/authHeader", "auth")
  SessionDB = File.join(File.expand_path(File.dirname(__FILE__)), 'session.pstoredb')

  class AuthHeaderService
    def self.create
      new
    end

    def deposit(amt)
      "deposit #{amt} OK"
    end

    def withdrawal(amt)
      "withdrawal #{amt} OK"
    end
  end

  class AuthHeaderSupportService
    def delete_sessiondb
      File.unlink(SessionDB) if File.file?(SessionDB)
      backup = SessionDB + "~"
      File.unlink(backup) if File.file?(backup)
    end
  end

  def initialize(*arg)
    super
    add_rpc_servant(AuthHeaderService.new, PortName)
    add_rpc_servant(AuthHeaderSupportService.new, SupportPortName)
    add_rpc_headerhandler(ServerAuthHeaderHandler.new)
  end

  class ServerAuthHeaderHandler < SOAP::Header::SimpleHandler
    Users = {
      'NaHi' => 'passwd',
      'HiNa' => 'wspass'
    }

    def initialize
      super(MyHeaderName)
      @db = PStore.new(SessionDB)
      @db.transaction do
	@db["root"] = {} unless @db.root?("root")
      end
      @userid = @sessionid = nil
    end

    def login(userid, passwd)
      userid and passwd and Users[userid] == passwd
    end

    def auth(sessionid)
      in_sessiondb do |root|
	root[sessionid][0]
      end
    end

    def create_session(userid)
      in_sessiondb do |root|
	while true
  	  key = create_sessionkey
  	  break unless root[key]
   	end
    	root[key] = [userid]
     	key
      end
    end

    def destroy_session(sessionkey)
      in_sessiondb do |root|
	root.delete(sessionkey)
      end
    end

    def on_simple_outbound
      { "sessionid" => @sessionid }
    end

    def on_simple_inbound(my_header, mu)
      auth = false
      userid = my_header["userid"]
      passwd = my_header["passwd"]
      if login(userid, passwd)
	auth = true
      elsif sessionid = my_header["sessionid"]
	if userid = auth(sessionid)
	  destroy_session(sessionid)
	  auth = true
	end
      end
      raise RuntimeError.new("authentication failed") unless auth
      @userid = userid
      @sessionid = create_session(userid)
    end

  private

    def create_sessionkey
      Time.now.usec.to_s
    end

    def in_sessiondb
      @db.transaction do
	yield(@db["root"])
      end
    end
  end
end


status = AuthHeaderPortServer.new('AuthHeaderPortServer', nil).start