-
Notifications
You must be signed in to change notification settings - Fork 2
/
lila_shell.rb
138 lines (113 loc) · 3.17 KB
/
lila_shell.rb
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# frozen_string_literal: true
require_relative 'models'
require 'roda'
require 'json'
require 'message_bus'
require 'strscan' # Needed for Rack::Multipart::Parser
require 'tilt'
require 'tilt/erubi'
module LilaShell
class App < Roda
def self.freeze
Model.freeze_descendents
DB.freeze
super
end
opts[:root] = File.dirname(__FILE__)
opts[:check_dynamic_arity] = false
opts[:check_arity] = :warn
include LilaShell
plugin :sessions,
:secret=>ENV.delete('LILA_SHELL_SESSION_SECRET'),
:key=>'lila_shell.session'
MESSAGE_BUS = MessageBus::Instance.new
MESSAGE_BUS.configure(:backend=>:memory)
plugin :direct_call
plugin :render, :escape=>true, :template_opts=>{:chain_appends=>true, :freeze=>true, :skip_compiled_encoding_detection=>true}
plugin :forme_route_csrf
plugin :symbol_views
plugin :message_bus, :message_bus=>MESSAGE_BUS
plugin :request_aref, :raise
plugin :public
plugin :disallow_file_uploads
plugin :typecast_params_sized_integers, :sizes=>[64], :default_size=>64
plugin :Integer_matcher_max
alias tp typecast_params
logger = if ENV['RACK_ENV'] == "test"
Class.new{def write(_) end}.new
else
$stderr
end
plugin :common_logger, logger
Forme.register_config(:mine, :base=>:default, :labeler=>:explicit, :wrapper=>:div)
Forme.default_config = :mine
plugin :error_handler do |e|
puts e.class, e.message, e.backtrace
view :content=>'<p>Oops, an error occurred</p>'
end
plugin :content_security_policy do |csp|
csp.default_src :none
csp.style_src :self
csp.form_action :self
csp.script_src :self
csp.connect_src :self
csp.base_uri :none
csp.frame_ancestors :none
end
plugin :class_matchers
[User, Room].each do |klass|
class_matcher klass, Integer do |id|
klass[id]
end
end
route do |r|
r.public
r.root do
:manage
end
r.post 'user' do
check_csrf!
User.create(:name=>tp.nonempty_str!('name'))
request.redirect '/'
end
r.on 'room' do
r.is do
r.get do
r.redirect "/room/#{tp.pos_int!('room_id')}/#{tp.pos_int!('user_id')}"
end
r.post do
check_csrf!
Room.create(:name=>tp.nonempty_str!('name'))
r.redirect '/'
end
end
r.on Room, User do |room, user|
channel = "/room/#{room.id}"
next "No access" if user.name == room.name
r.message_bus(channel)
r.get true do
@user = user
@room = room
@channel = channel
:room
end
r.post do
check_csrf!
r.is %w"join leave" do |type|
MESSAGE_BUS.publish(channel, {type.to_sym=>user.name, :at=>Time.now.strftime('%H:%M:%S')}.to_json)
''
end
r.is "message" do
post = tp.str!('post').strip
unless post.empty?
m = Message.create(:user_id=>user.id, :room_id=>room.id, :message=>post)
MESSAGE_BUS.publish(channel, {:user=>user.name, :room_id=>room.id, :message=>post, :at=>m.at.strftime('%H:%M:%S')}.to_json)
end
''
end
end
end
end
end
end
end