egalite 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/README.md +91 -0
- data/auth/basic.rb +32 -0
- data/blank.rb +53 -0
- data/egalite.rb +742 -0
- data/errorconsole.rb +77 -0
- data/examples/simple/example.rb +39 -0
- data/examples/simple/pages/test.html +15 -0
- data/examples/simple_db/example_db.rb +103 -0
- data/examples/simple_db/pages/edit.html +6 -0
- data/helper.rb +251 -0
- data/keitai/keitai.rb +107 -0
- data/keitai/ketai.rb +11 -0
- data/keitai/rack/ketai/carrier/abstract.rb +131 -0
- data/keitai/rack/ketai/carrier/au.rb +78 -0
- data/keitai/rack/ketai/carrier/docomo.rb +80 -0
- data/keitai/rack/ketai/carrier/emoji/ausjisstrtoemojiid.rb +1391 -0
- data/keitai/rack/ketai/carrier/emoji/docomosjisstrtoemojiid.rb +759 -0
- data/keitai/rack/ketai/carrier/emoji/emojidata.rb +836 -0
- data/keitai/rack/ketai/carrier/emoji/softbankutf8strtoemojiid.rb +1119 -0
- data/keitai/rack/ketai/carrier/emoji/softbankwebcodetoutf8str.rb +499 -0
- data/keitai/rack/ketai/carrier/iphone.rb +8 -0
- data/keitai/rack/ketai/carrier/softbank.rb +82 -0
- data/keitai/rack/ketai/carrier.rb +17 -0
- data/keitai/rack/ketai/middleware.rb +24 -0
- data/m17n.rb +193 -0
- data/rack/auth/abstract/handler.rb +37 -0
- data/rack/auth/abstract/request.rb +37 -0
- data/rack/auth/basic.rb +58 -0
- data/rack/auth/digest/md5.rb +124 -0
- data/rack/auth/digest/nonce.rb +51 -0
- data/rack/auth/digest/params.rb +55 -0
- data/rack/auth/digest/request.rb +40 -0
- data/rack/builder.rb +80 -0
- data/rack/cascade.rb +41 -0
- data/rack/chunked.rb +49 -0
- data/rack/commonlogger.rb +49 -0
- data/rack/conditionalget.rb +47 -0
- data/rack/config.rb +15 -0
- data/rack/content_length.rb +29 -0
- data/rack/content_type.rb +23 -0
- data/rack/deflater.rb +96 -0
- data/rack/directory.rb +157 -0
- data/rack/etag.rb +32 -0
- data/rack/file.rb +92 -0
- data/rack/handler/cgi.rb +62 -0
- data/rack/handler/evented_mongrel.rb +8 -0
- data/rack/handler/fastcgi.rb +89 -0
- data/rack/handler/lsws.rb +63 -0
- data/rack/handler/mongrel.rb +90 -0
- data/rack/handler/scgi.rb +59 -0
- data/rack/handler/swiftiplied_mongrel.rb +8 -0
- data/rack/handler/thin.rb +18 -0
- data/rack/handler/webrick.rb +73 -0
- data/rack/handler.rb +88 -0
- data/rack/head.rb +19 -0
- data/rack/lint.rb +567 -0
- data/rack/lobster.rb +65 -0
- data/rack/lock.rb +16 -0
- data/rack/logger.rb +20 -0
- data/rack/methodoverride.rb +27 -0
- data/rack/mime.rb +208 -0
- data/rack/mock.rb +190 -0
- data/rack/nulllogger.rb +18 -0
- data/rack/recursive.rb +61 -0
- data/rack/reloader.rb +109 -0
- data/rack/request.rb +273 -0
- data/rack/response.rb +150 -0
- data/rack/rewindable_input.rb +103 -0
- data/rack/runtime.rb +27 -0
- data/rack/sendfile.rb +144 -0
- data/rack/server.rb +271 -0
- data/rack/session/abstract/id.rb +140 -0
- data/rack/session/cookie.rb +90 -0
- data/rack/session/memcache.rb +119 -0
- data/rack/session/pool.rb +100 -0
- data/rack/showexceptions.rb +349 -0
- data/rack/showstatus.rb +106 -0
- data/rack/static.rb +38 -0
- data/rack/urlmap.rb +55 -0
- data/rack/utils.rb +662 -0
- data/rack.rb +81 -0
- data/route.rb +231 -0
- data/sendmail.rb +222 -0
- data/sequel_helper.rb +20 -0
- data/session.rb +132 -0
- data/stringify_hash.rb +63 -0
- data/support.rb +35 -0
- data/template.rb +287 -0
- data/test/french.html +13 -0
- data/test/french_msg.html +3 -0
- data/test/m17n.txt +30 -0
- data/test/mobile.html +15 -0
- data/test/setup.rb +8 -0
- data/test/static/test.txt +1 -0
- data/test/template.html +58 -0
- data/test/template_inner.html +1 -0
- data/test/template_innerparam.html +1 -0
- data/test/test_auth.rb +43 -0
- data/test/test_blank.rb +44 -0
- data/test/test_csrf.rb +87 -0
- data/test/test_errorconsole.rb +91 -0
- data/test/test_handler.rb +155 -0
- data/test/test_helper.rb +296 -0
- data/test/test_keitai.rb +107 -0
- data/test/test_m17n.rb +129 -0
- data/test/test_route.rb +192 -0
- data/test/test_sendmail.rb +146 -0
- data/test/test_session.rb +83 -0
- data/test/test_stringify_hash.rb +67 -0
- data/test/test_template.rb +114 -0
- data/test.bat +2 -0
- metadata +240 -0
data/errorconsole.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
|
2
|
+
class EgaliteErrorController < Egalite::Controller
|
3
|
+
def self.password=(pass)
|
4
|
+
@@password=pass
|
5
|
+
end
|
6
|
+
def self.database=(db)
|
7
|
+
@@database=db
|
8
|
+
end
|
9
|
+
def before_filter
|
10
|
+
return false unless @@password
|
11
|
+
Egalite::Auth::Basic.authorize(req, 'EgaliteError') { |username,password|
|
12
|
+
username == 'admin' and password == @@password
|
13
|
+
}
|
14
|
+
end
|
15
|
+
def get
|
16
|
+
hb = Egalite::HTMLTagBuilder
|
17
|
+
raw("<html><body>" +
|
18
|
+
hb.ol([ hb.a('latest','�ŐV�G���[�ꗗ'),
|
19
|
+
hb.a('frequent','���p�x�G���[�ꗗ'),
|
20
|
+
hb.a('security','�Z�L�����e�B�G���[�ꗗ'),
|
21
|
+
"<form action='detail'>�G���[�ԍ�: <input type='text' name='id'><input type='submit'></form>",
|
22
|
+
]) + "</body></html>")
|
23
|
+
end
|
24
|
+
def display(recs)
|
25
|
+
hb = Egalite::HTMLTagBuilder
|
26
|
+
raw("<body><html>" +
|
27
|
+
table_by_array(
|
28
|
+
['��ʔԍ�(�ڍ�)', '������', '���e', 'URL', '�폜'],
|
29
|
+
recs.map { |rec|
|
30
|
+
[hb.a(url_for(:action => :group, :id => rec[:md5]),rec[:md5]),
|
31
|
+
rec[:count],
|
32
|
+
rec[:text][0..50],
|
33
|
+
rec[:url][0..50],
|
34
|
+
hb.a(url_for(:action => :delete, :id => rec[:md5]),'�폜'),
|
35
|
+
]
|
36
|
+
}
|
37
|
+
) + "</body></html>")
|
38
|
+
end
|
39
|
+
def latest(lim)
|
40
|
+
lim ||= 100
|
41
|
+
display(@@database.fetch("SELECT md5, text, url, count(*) as count FROM logs WHERE checked_at is null AND severity != 'security' GROUP BY md5, text, url ORDER BY max(created_at) DESC LIMIT ?",lim.to_i))
|
42
|
+
end
|
43
|
+
def frequent(lim)
|
44
|
+
lim ||= 100
|
45
|
+
display(@@database.fetch("SELECT md5, text, url, count(*) as count FROM logs WHERE checked_at is null AND severity != 'security' GROUP BY md5, text, url ORDER BY count(*) DESC LIMIT ?",lim.to_i))
|
46
|
+
end
|
47
|
+
def security(lim)
|
48
|
+
lim ||= 100
|
49
|
+
display(@@database.fetch("SELECT md5, text, url, count(*) as count FROM logs WHERE checked_at is null AND severity == 'security' GROUP BY md5, text, url ORDER BY count(*) DESC LIMIT ?",lim.to_i))
|
50
|
+
end
|
51
|
+
def group(md5)
|
52
|
+
rec = @@database[:logs].filter(:md5 => md5).first
|
53
|
+
raw("<html><body>"+Egalite::HTMLTagBuilder.ul([
|
54
|
+
rec[:md5],
|
55
|
+
rec[:url],
|
56
|
+
rec[:text],
|
57
|
+
]) +"</body></html>")
|
58
|
+
end
|
59
|
+
def delete(md5)
|
60
|
+
@@database[:logs].filter(:md5 => md5).update(:checked_at => Time.now)
|
61
|
+
redirect :action => nil
|
62
|
+
end
|
63
|
+
def detail(id)
|
64
|
+
rec = @@database[:logs].filter(:id => id.to_i).first
|
65
|
+
return "no record found." unless rec
|
66
|
+
raw("<html><body>"+Egalite::HTMLTagBuilder.ul([
|
67
|
+
rec[:id],
|
68
|
+
rec[:severity],
|
69
|
+
rec[:created_at],
|
70
|
+
rec[:md5],
|
71
|
+
rec[:ipaddress],
|
72
|
+
rec[:url],
|
73
|
+
rec[:text],
|
74
|
+
]) +"</body></html>")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require '../../egalite/egalite'
|
2
|
+
|
3
|
+
class DefaultController < Egalite::Controller
|
4
|
+
def get(name = 'egalite')
|
5
|
+
[
|
6
|
+
"hello #{name}.",
|
7
|
+
"cookies = #{cookies.inspect}",
|
8
|
+
"#{url_for(:action => :bar, :params => [:a,:b])}",
|
9
|
+
"<a href='test'>template test</a>",
|
10
|
+
link_to('params test',:action => :test2, :hoge => "p i y o", "foo[bar][1]" => 1, "foo[bar][2]" => :two),
|
11
|
+
link_to('add cookie', :action => :set_cookie, :id => :piyopiyo),
|
12
|
+
link_to('del cookie', :action => :delete_cookie),
|
13
|
+
].join('<br/>')
|
14
|
+
end
|
15
|
+
def test
|
16
|
+
{:posts => [
|
17
|
+
{:title => 'piyo', :content => 'hiyoko.'},
|
18
|
+
{:title => 'foo', :content => 'bar.'},
|
19
|
+
]}
|
20
|
+
end
|
21
|
+
def test2
|
22
|
+
params.inspect
|
23
|
+
end
|
24
|
+
def set_cookie(s)
|
25
|
+
cookies['test'] = s
|
26
|
+
redirect_to('/')
|
27
|
+
end
|
28
|
+
def delete_cookie
|
29
|
+
cookies['test'] = {:expires => Time.now - 3600, :value => nil}
|
30
|
+
redirect_to('/')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
ShowException = true
|
35
|
+
RouteDebug = false
|
36
|
+
egalite = Egalite::Handler.new
|
37
|
+
|
38
|
+
Rack::Handler::WEBrick.run(egalite, :Port => 4000)
|
39
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Egalite - A next web application framework on Ruby</title>
|
4
|
+
</head>
|
5
|
+
<body>
|
6
|
+
<h1>Welcome to Egalite</h1>
|
7
|
+
<group name='posts'>
|
8
|
+
<h2>&=title;</h2>
|
9
|
+
<p>&=content;</p>
|
10
|
+
</group>
|
11
|
+
<form action='&=urla(new);' method='post'>
|
12
|
+
|
13
|
+
</form>
|
14
|
+
</body>
|
15
|
+
</html>
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'sequel'
|
3
|
+
require '../../egalite/egalite'
|
4
|
+
require 'digest/md5'
|
5
|
+
|
6
|
+
class User < Sequel::Model
|
7
|
+
def User.digest(pw)
|
8
|
+
Digest::MD5.hexdigest("#{pw}piyopiyo")
|
9
|
+
end
|
10
|
+
def password=(password)
|
11
|
+
self.hashed_password = User.digest(password) if password and password.size > 0
|
12
|
+
end
|
13
|
+
def password
|
14
|
+
""
|
15
|
+
end
|
16
|
+
def User.lookup(email,password)
|
17
|
+
User.filter(:email => email, :hashed_password => User.digest(password)).first
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class DefaultController < Egalite::Controller
|
22
|
+
def get
|
23
|
+
[
|
24
|
+
link_to('list', :action => :list),
|
25
|
+
link_to('create_tables', :action => :create_tables),
|
26
|
+
].flatten.join('<br/>')
|
27
|
+
end
|
28
|
+
def list
|
29
|
+
[
|
30
|
+
"Welcome #{session[:user_id] ? User[session[:user_id]].name : 'guest'}",
|
31
|
+
session[:user_id] ? link_to('logout', :action => :logout) : '',
|
32
|
+
|
33
|
+
"<form action='login' method='post'/>",
|
34
|
+
"Email: <input type='text' name='email'/>",
|
35
|
+
"Password: <input type='password' name='password'/>",
|
36
|
+
"<input type='submit' value='login'/>",
|
37
|
+
"</form>",
|
38
|
+
link_to('new user', :action => :edit),
|
39
|
+
"** username / email / hashed_password **",
|
40
|
+
User.map { |user|
|
41
|
+
link_to(user.name, :action => :edit, :id => user.id) +
|
42
|
+
" / #{user.email} / #{user.hashed_password} / " +
|
43
|
+
link_to('destroy', :action => :destroy, :id => user.id)
|
44
|
+
}
|
45
|
+
].flatten.join('<br/>')
|
46
|
+
end
|
47
|
+
def login
|
48
|
+
user = User.lookup(params[:email],params[:password])
|
49
|
+
return "email and/or password is not correct." unless user
|
50
|
+
|
51
|
+
session.create(:user_id => user.id)
|
52
|
+
redirect :action => :list
|
53
|
+
end
|
54
|
+
def logout
|
55
|
+
session.delete
|
56
|
+
redirect :action => :list
|
57
|
+
end
|
58
|
+
def edit_get(id)
|
59
|
+
id ? User[id] : {}
|
60
|
+
end
|
61
|
+
def edit_post(id)
|
62
|
+
user = id ? User[id] : User.new
|
63
|
+
user.update_with_params(params)
|
64
|
+
user.save
|
65
|
+
redirect :action => :list
|
66
|
+
end
|
67
|
+
def destroy(id)
|
68
|
+
User[id].destroy
|
69
|
+
redirect :action => :list
|
70
|
+
end
|
71
|
+
def create_tables
|
72
|
+
db.create_table!(:sessions) {
|
73
|
+
primary_key :id, :serial
|
74
|
+
column :mac, :varchar
|
75
|
+
column :updated_at, :timestamp
|
76
|
+
column :user_id, :integer
|
77
|
+
}
|
78
|
+
db.create_table!(:users) {
|
79
|
+
primary_key :id, :serial
|
80
|
+
column :name, :varchar
|
81
|
+
column :email, :varchar
|
82
|
+
column :hashed_password, :varchar
|
83
|
+
}
|
84
|
+
redirect '/'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
ShowException = true
|
89
|
+
RouteDebug = false
|
90
|
+
|
91
|
+
begin
|
92
|
+
db = Sequel.connect('postgres://test:test@localhost/egalite')
|
93
|
+
User.set_dataset(db[:users])
|
94
|
+
|
95
|
+
egalite = Egalite::Handler.new(
|
96
|
+
:db => db,
|
97
|
+
:session_handler => Egalite::SessionSequel
|
98
|
+
)
|
99
|
+
Rack::Handler::WEBrick.run(egalite, :Port => 4000)
|
100
|
+
ensure
|
101
|
+
db.disconnect
|
102
|
+
end
|
103
|
+
|
data/helper.rb
ADDED
@@ -0,0 +1,251 @@
|
|
1
|
+
|
2
|
+
module Egalite
|
3
|
+
|
4
|
+
module HTMLTagBuilder
|
5
|
+
def escape_html(s)
|
6
|
+
s.is_a?(NonEscapeString) ? s : NonEscapeString.new(Rack::Utils.escape_html(s))
|
7
|
+
end
|
8
|
+
def _tag(name , soc, attributes)
|
9
|
+
close = soc == :close ? '/' : ''
|
10
|
+
solo = soc == :solo ? '/' : ''
|
11
|
+
|
12
|
+
atr = if attributes and not attributes.empty?
|
13
|
+
s = attributes.map { |k,v| "#{escape_html(k)}='#{escape_html(v)}'" }.join(' ')
|
14
|
+
" #{s}"
|
15
|
+
else
|
16
|
+
""
|
17
|
+
end
|
18
|
+
NonEscapeString.new("<#{close}#{escape_html(name)}#{atr}#{solo}>")
|
19
|
+
end
|
20
|
+
def tag_solo(name, attributes = {})
|
21
|
+
_tag(name, :solo, attributes)
|
22
|
+
end
|
23
|
+
def tag_open(name, attributes = {})
|
24
|
+
_tag(name, :open, attributes)
|
25
|
+
end
|
26
|
+
def tag_close(name, attributes = {})
|
27
|
+
_tag(name, :close, attributes)
|
28
|
+
end
|
29
|
+
class <<self
|
30
|
+
include Egalite::HTMLTagBuilder
|
31
|
+
def tag(tag, s, attributes = {})
|
32
|
+
tag_open(tag, attributes) + escape_html(s) + tag_close(tag, {})
|
33
|
+
end
|
34
|
+
%w[br hr].each { |t|
|
35
|
+
define_method(t) { tag_solo(t) }
|
36
|
+
}
|
37
|
+
%w[h1 h2 h3 h4 b i p html body].each { |t|
|
38
|
+
define_method(t) { |s|
|
39
|
+
tag(t, s)
|
40
|
+
}
|
41
|
+
}
|
42
|
+
def a(url, s)
|
43
|
+
tag('a', s, :href=>url)
|
44
|
+
end
|
45
|
+
def li(array)
|
46
|
+
array.map{ |s| "<li>#{escape_html(s)}</li>" }.join("\n")
|
47
|
+
end
|
48
|
+
def ol(array)
|
49
|
+
"<ol>#{li(array)}</ol>"
|
50
|
+
end
|
51
|
+
def ul(array)
|
52
|
+
"<ul>#{li(array)}</ul>"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class TableHelper
|
58
|
+
private
|
59
|
+
def self.opt(opts)
|
60
|
+
opts.map { |k,v| " #{escape_html(k)}='#{escape_html(v)}'" }.join
|
61
|
+
end
|
62
|
+
def self.escape_html(s)
|
63
|
+
s.is_a?(NonEscapeString) ? s : Rack::Utils.escape_html(s)
|
64
|
+
end
|
65
|
+
def self._table(header, content, table_opts)
|
66
|
+
head = ""
|
67
|
+
if header
|
68
|
+
head = header.map {|s| "<th>#{escape_html(s)}</th>" }.join
|
69
|
+
head = " <tr>#{head}</tr>\n"
|
70
|
+
end
|
71
|
+
body = content.map { |line| " <tr>#{yield(line)}</tr>\n" }
|
72
|
+
NonEscapeString.new("<table#{opt(table_opts)}>\n#{head}#{body}</table>")
|
73
|
+
end
|
74
|
+
public
|
75
|
+
def self.table_by_hash(keys, header, content, table_opts = {})
|
76
|
+
unless keys.size == header.size
|
77
|
+
raise ArgumentError, "key and header count mismatch"
|
78
|
+
end
|
79
|
+
|
80
|
+
_table(header, content, table_opts) { |line|
|
81
|
+
keys.map { |key| "<td>#{escape_html(line[key])}</td>"}.join
|
82
|
+
}
|
83
|
+
end
|
84
|
+
def self.table_by_array(header, content, table_opts = {})
|
85
|
+
_table(header, content, table_opts) { |line|
|
86
|
+
line.map { |s| "<td>#{escape_html(s)}</td>" }.join
|
87
|
+
}
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class FormHelper
|
92
|
+
include HTMLTagBuilder
|
93
|
+
|
94
|
+
private
|
95
|
+
def expand_name(s)
|
96
|
+
s = "#{@param_name}[#{s}]" if @param_name
|
97
|
+
escape_html(s)
|
98
|
+
end
|
99
|
+
def raw(s)
|
100
|
+
NonEscapeString.new(s)
|
101
|
+
end
|
102
|
+
|
103
|
+
public # export just for testing
|
104
|
+
|
105
|
+
def opt(opts)
|
106
|
+
opts.map { |k,v|
|
107
|
+
next "" if [:default,:checked,:selected, :nil].member?(k)
|
108
|
+
" #{escape_html(k)}='#{escape_html(v)}'"
|
109
|
+
}.join
|
110
|
+
end
|
111
|
+
def opt_as_hash(opts)
|
112
|
+
o = opts.dup
|
113
|
+
o.each_key { |k|
|
114
|
+
o.delete(k) if [:default,:checked,:selected, :nil].member?(k)
|
115
|
+
}
|
116
|
+
o
|
117
|
+
end
|
118
|
+
|
119
|
+
public
|
120
|
+
|
121
|
+
def initialize(data = {}, param_name = nil, opts = {})
|
122
|
+
@data = lambda { |k|
|
123
|
+
if data.respond_to?(k)
|
124
|
+
data.send(k)
|
125
|
+
elsif data.respond_to?(:[])
|
126
|
+
data[k]
|
127
|
+
end
|
128
|
+
}
|
129
|
+
|
130
|
+
@param_name = param_name
|
131
|
+
@form_opts = opts
|
132
|
+
end
|
133
|
+
def form(method, url=nil)
|
134
|
+
attrs = opt_as_hash(@form_opts)
|
135
|
+
attrs[:method] = method.to_s.upcase
|
136
|
+
attrs[:action] = url if url
|
137
|
+
tag_open(:form,attrs)
|
138
|
+
end
|
139
|
+
def close
|
140
|
+
tag_close(:form,nil)
|
141
|
+
end
|
142
|
+
def _text(value, name, opts)
|
143
|
+
attrs = opt_as_hash(opts)
|
144
|
+
attrs[:value] = value if value
|
145
|
+
attrs[:size] ||= 30
|
146
|
+
attrs[:type] = 'text'
|
147
|
+
attrs[:name] = expand_name(name)
|
148
|
+
tag_solo(:input, attrs)
|
149
|
+
end
|
150
|
+
def text(name, opts = {})
|
151
|
+
_text(@data[name] || opts[:default], name, opts)
|
152
|
+
end
|
153
|
+
def timestamp_text(name, opts = {})
|
154
|
+
# todo: enable locale
|
155
|
+
# todo: could unify to text()
|
156
|
+
value = @data[name] || opts[:default]
|
157
|
+
value = value.strftime('%Y-%m-%d %H:%M:%S')
|
158
|
+
_text(value,name,opts)
|
159
|
+
end
|
160
|
+
def password(name, opts = {})
|
161
|
+
value = @data[name] || opts[:default]
|
162
|
+
attrs = opt_as_hash(opts)
|
163
|
+
attrs[:value] = value if value
|
164
|
+
attrs[:type] = "password"
|
165
|
+
attrs[:name] = expand_name(name)
|
166
|
+
tag_solo(:input,attrs)
|
167
|
+
end
|
168
|
+
def hidden(name, opts = {})
|
169
|
+
value = @data[name] || opts[:default]
|
170
|
+
attrs = opt_as_hash(opts)
|
171
|
+
attrs[:value] = value if value
|
172
|
+
attrs[:type] = "hidden"
|
173
|
+
attrs[:name] = expand_name(name)
|
174
|
+
tag_solo(:input,attrs)
|
175
|
+
end
|
176
|
+
def checkbox(name, value="true", opts = {})
|
177
|
+
checked = (@data[name] || opts[:default] || opts[:checked])
|
178
|
+
checked = false if @data[name] == false
|
179
|
+
|
180
|
+
attr_cb = opt_as_hash(opts)
|
181
|
+
attr_cb[:type] = 'checkbox'
|
182
|
+
attr_cb[:name] = expand_name(name)
|
183
|
+
attr_cb[:value] = value
|
184
|
+
attr_cb[:checked] = "checked" if checked
|
185
|
+
|
186
|
+
ucv = opts[:uncheckedvalue] || 'false'
|
187
|
+
attr_h = {:type => 'hidden', :name => expand_name(name), :value => ucv}
|
188
|
+
hidden = opts[:nohidden] ? '' : tag_solo(:input, attr_h)
|
189
|
+
|
190
|
+
raw "#{hidden}#{tag_solo(:input, attr_cb)}"
|
191
|
+
end
|
192
|
+
def radio(name, choice, opts = {})
|
193
|
+
selected = (@data[name] == choice)
|
194
|
+
selected = (opts[:default] == choice) || opts[:selected] if @data[name] == nil
|
195
|
+
|
196
|
+
attrs = opt_as_hash(opts)
|
197
|
+
attrs[:selected] = 'selected' if selected
|
198
|
+
attrs[:name] = expand_name(name)
|
199
|
+
attrs[:value] = choice
|
200
|
+
attrs[:type] = 'radio'
|
201
|
+
|
202
|
+
tag_solo(:input, attrs)
|
203
|
+
end
|
204
|
+
def textarea(name, opts = {})
|
205
|
+
value = escape_html(@data[name] || opts[:default])
|
206
|
+
raw "<textarea name='#{expand_name(name)}'#{opt(opts)}>#{value}</textarea>"
|
207
|
+
end
|
208
|
+
def file(name, opts = {})
|
209
|
+
attrs = opt_as_hash(opts)
|
210
|
+
attrs[:name] = expand_name(name)
|
211
|
+
attrs[:type] = 'file'
|
212
|
+
tag_solo(:input, attrs)
|
213
|
+
end
|
214
|
+
def submit(value = nil, name = nil, opts = {})
|
215
|
+
attrs = opt_as_hash(opts)
|
216
|
+
attrs[:name] = expand_name(name) if name
|
217
|
+
attrs[:value] = value if value
|
218
|
+
attrs[:type] = 'submit'
|
219
|
+
tag_solo(:input, attrs)
|
220
|
+
end
|
221
|
+
def image
|
222
|
+
end
|
223
|
+
def select_by_array(name, options, opts = {})
|
224
|
+
optionstr = options.map {|o|
|
225
|
+
flag = o[0] == @data[name]
|
226
|
+
a = {:value => o[0]}
|
227
|
+
a[:selected] = 'selected' if flag
|
228
|
+
"#{tag_open(:option, a)}#{escape_html(o[1])}</option>"
|
229
|
+
}.join('')
|
230
|
+
|
231
|
+
raw "<select name='#{expand_name(name)}'#{opt(opts)}>#{optionstr}</select>"
|
232
|
+
end
|
233
|
+
def select_by_association(name, options, optname, opts = {})
|
234
|
+
idname = (opts[:idname] || "id").to_sym
|
235
|
+
optionstr = options.map {|o|
|
236
|
+
flag = o[idname] == @data[name]
|
237
|
+
a = {:value => o[idname]}
|
238
|
+
a[:selected] = 'selected' if flag
|
239
|
+
"#{tag_open(:option, a)}#{escape_html(o[optname])}</option>"
|
240
|
+
}.join('')
|
241
|
+
|
242
|
+
if opts[:nil]
|
243
|
+
selected = (@data[name] == nil) ? "selected='selected'" : ''
|
244
|
+
optionstr = "<option value='' #{selected}>#{escape_html(opts[:nil])}</option>" + optionstr
|
245
|
+
end
|
246
|
+
|
247
|
+
raw "<select name='#{expand_name(name)}'#{opt(opts)}>#{optionstr}</select>"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
end
|
data/keitai/keitai.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
|
2
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'ketai'
|
5
|
+
require 'uri'
|
6
|
+
require 'openssl'
|
7
|
+
require 'base64'
|
8
|
+
|
9
|
+
module Egalite
|
10
|
+
module Keitai
|
11
|
+
class URLSession
|
12
|
+
def self.encrypt(s,key)
|
13
|
+
cipher = OpenSSL::Cipher.new("bf-cbc")
|
14
|
+
cipher.pkcs5_keyivgen(key)
|
15
|
+
cipher.encrypt
|
16
|
+
e = cipher.update(s) + cipher.final
|
17
|
+
Base64.encode64(e).tr('+/=','_.-').gsub!("\n","")
|
18
|
+
end
|
19
|
+
def self.decrypt(s,key)
|
20
|
+
cipher = OpenSSL::Cipher.new("bf-cbc")
|
21
|
+
cipher.pkcs5_keyivgen(key)
|
22
|
+
cipher.decrypt
|
23
|
+
e = s.tr('_.-','+/=')
|
24
|
+
e = Base64.decode64(e)
|
25
|
+
d = cipher.update(e) + cipher.final
|
26
|
+
d
|
27
|
+
end
|
28
|
+
end
|
29
|
+
module Session
|
30
|
+
def load_keitai_session(sessionid)
|
31
|
+
session.load_from_param(sessionid)
|
32
|
+
end
|
33
|
+
def modify_url_for_keitai(url,sstr)
|
34
|
+
uri = URI.parse(URI.escape(URI.unescape(url)))
|
35
|
+
return url if not uri.scheme.blank? and uri.scheme !~ /(http|https)/
|
36
|
+
if uri.host and uri.host !~ my_host
|
37
|
+
crypted_url = URLSession.encrypt(url,redirector_crypt_key)
|
38
|
+
File.join(redirector_url,crypted_url)
|
39
|
+
else
|
40
|
+
array = uri.query.to_s.split('&')
|
41
|
+
qhash = array.inject({}) { |a,s| (k,v) = s.split('=',2); a[k] = v; a }
|
42
|
+
qhash['sessionid']=sstr
|
43
|
+
uri.query = qhash.map {|k,v| "#{k}=#{v}"}.join('&')
|
44
|
+
uri.to_s
|
45
|
+
end
|
46
|
+
end
|
47
|
+
def replace_url_for_keitai(body,sstr)
|
48
|
+
body.gsub!(/<a.+?href=(?:'(.+?)'|"(.+?)").+?>/) { |s|
|
49
|
+
url = ($1 || $2)
|
50
|
+
url_after = modify_url_for_keitai(url,sstr)
|
51
|
+
s.sub(url,url_after)
|
52
|
+
}
|
53
|
+
body.gsub!(/(<form.+?>)/) { |s|
|
54
|
+
s + "\n<input type='hidden' name='sessionid' value='#{sstr}'/>\n"
|
55
|
+
}
|
56
|
+
end
|
57
|
+
def redirector_url
|
58
|
+
"/redirector"
|
59
|
+
end
|
60
|
+
def do_after_filter_for_keitai(response,session)
|
61
|
+
code = response[0]
|
62
|
+
headers = response[1]
|
63
|
+
body = response[2].join
|
64
|
+
|
65
|
+
if session and session.sstr
|
66
|
+
sstr = session.sstr
|
67
|
+
if headers['Location']
|
68
|
+
headers['Location'] = modify_url_for_keitai(headers['Location'],sstr)
|
69
|
+
end
|
70
|
+
replace_url_for_keitai(body,sstr)
|
71
|
+
response[2] = [body]
|
72
|
+
end
|
73
|
+
response
|
74
|
+
end
|
75
|
+
end
|
76
|
+
class Controller < Egalite::Controller
|
77
|
+
include Session
|
78
|
+
|
79
|
+
def before_filter
|
80
|
+
load_keitai_session(params[:sessionid])
|
81
|
+
super
|
82
|
+
end
|
83
|
+
def redirector_crypt_key
|
84
|
+
"Example1"
|
85
|
+
end
|
86
|
+
def my_host
|
87
|
+
/^www.example.com$/
|
88
|
+
end
|
89
|
+
def after_filter(response)
|
90
|
+
do_after_filter_for_keitai(response,session)
|
91
|
+
super(response)
|
92
|
+
response
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
class Redirector < Egalite::Controller
|
97
|
+
def get(crypted_url)
|
98
|
+
url = URLSession.decrypt(crypted_url, redirector_crypt_key)
|
99
|
+
"<html><body>外部サイトへ移動しようとしています。以下のリンクをクリックしてください。<br/><br/><a href='#{URI.escape(url)}'>リンク</a></body></html>"
|
100
|
+
end
|
101
|
+
def redirector_crypt_key
|
102
|
+
"Example1"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|