fcid 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/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +22 -0
- data/app/controllers/fcid/feeds_controller.rb +22 -0
- data/app/controllers/fcid/friendships_controller.rb +74 -0
- data/app/controllers/fcid/messages_controller.rb +24 -0
- data/app/controllers/fcid/session_controller.rb +80 -0
- data/app/controllers/fcid/users_controller.rb +25 -0
- data/app/views/fcid/_ajax_new.html.erb +3 -0
- data/app/views/fcid/_announce.html.erb +5 -0
- data/app/views/fcid/_footer.html.erb +0 -0
- data/app/views/fcid/_navigation.html.erb +0 -0
- data/app/views/fcid/create.html.erb +6 -0
- data/app/views/fcid/feeds/_feed.html.erb +29 -0
- data/app/views/fcid/feeds/index.html.erb +4 -0
- data/app/views/fcid/feeds/show.html.erb +0 -0
- data/app/views/fcid/friendships/index.html.erb +5 -0
- data/app/views/fcid/friendships/new.html.erb +22 -0
- data/app/views/fcid/messages/_message.html.erb +0 -0
- data/app/views/fcid/messages/_message_tr.html.erb +8 -0
- data/app/views/fcid/messages/index.html.erb +20 -0
- data/app/views/fcid/new.html.erb +30 -0
- data/app/views/fcid/session/new.html.erb +40 -0
- data/app/views/fcid/users/_ajax_new.html.erb +3 -0
- data/app/views/fcid/users/create.html.erb +6 -0
- data/app/views/fcid/users/new.html.erb +33 -0
- data/app/views/friendships/new.html.erb +22 -0
- data/app/views/session/new.html.erb +20 -0
- data/config/routes.rb +29 -0
- data/lib/fcid/active_resource/exceptions.rb +7 -0
- data/lib/fcid/active_resource/extra_params.rb +66 -0
- data/lib/fcid/active_resource/session.rb +45 -0
- data/lib/fcid/base.rb +7 -0
- data/lib/fcid/config.rb +88 -0
- data/lib/fcid/consumer.rb +51 -0
- data/lib/fcid/controller.rb +46 -0
- data/lib/fcid/email.rb +9 -0
- data/lib/fcid/engine.rb +5 -0
- data/lib/fcid/feed.rb +17 -0
- data/lib/fcid/friendship.rb +5 -0
- data/lib/fcid/helpers.rb +49 -0
- data/lib/fcid/message.rb +5 -0
- data/lib/fcid/notification.rb +5 -0
- data/lib/fcid/publisher/base.rb +398 -0
- data/lib/fcid/session.rb +5 -0
- data/lib/fcid/user.rb +50 -0
- data/lib/fcid/user_methods.rb +39 -0
- data/lib/fcid/version.rb +3 -0
- data/lib/fcid.rb +12 -0
- data/lib/fcid_client.rb +14 -0
- data/lib/tasks/fcid_tasks.rake +4 -0
- data/lib/vendor/authenticated_system.rb +153 -0
- data/lib/vendor/authenticated_test_helper.rb +11 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/fcid_test.rb +9 -0
- data/test/test_helper.rb +15 -0
- metadata +169 -0
@@ -0,0 +1,398 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'action_mailer/adv_attr_accessor'
|
3
|
+
module Fcid
|
4
|
+
module Publisher #:nodoc:
|
5
|
+
class Base
|
6
|
+
class Controller #:nodoc: we need this let the url helpers to work
|
7
|
+
include ActionController::UrlWriter
|
8
|
+
def self.default_url_options
|
9
|
+
#ActionMailer::Base.default_url_options
|
10
|
+
Fcid::Publisher::Base.default_url_options
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
include ActionMailer::AdvAttrAccessor
|
15
|
+
cattr_accessor :default_url_options
|
16
|
+
if Object.const_defined?(:ActionController)
|
17
|
+
include ActionController::UrlWriter
|
18
|
+
include ActionController::Layout
|
19
|
+
end
|
20
|
+
include ActionView::Helpers
|
21
|
+
|
22
|
+
# setting for host
|
23
|
+
=begin
|
24
|
+
def self.default_url_options
|
25
|
+
{:host=>"uc.powerapple.com",:only_path=>false}
|
26
|
+
end
|
27
|
+
=end
|
28
|
+
|
29
|
+
private_class_method :new #:nodoc:
|
30
|
+
|
31
|
+
class_inheritable_accessor :view_paths
|
32
|
+
cattr_accessor :logger
|
33
|
+
self.logger = Rails.logger
|
34
|
+
|
35
|
+
@@raise_delivery_errors = true
|
36
|
+
cattr_accessor :raise_delivery_errors
|
37
|
+
|
38
|
+
|
39
|
+
@@perform_deliveries = true
|
40
|
+
cattr_accessor :perform_deliveries
|
41
|
+
|
42
|
+
@@deliveries = []
|
43
|
+
cattr_accessor :deliveries
|
44
|
+
|
45
|
+
@@default_charset = "utf-8"
|
46
|
+
cattr_accessor :default_charset
|
47
|
+
|
48
|
+
|
49
|
+
cattr_reader :protected_instance_variables
|
50
|
+
@@protected_instance_variables = %w(@body)
|
51
|
+
|
52
|
+
adv_attr_accessor :delivery_method
|
53
|
+
|
54
|
+
# Define the body of the message. This is either a Hash (in which case it
|
55
|
+
# specifies the variables to pass to the template when it is rendered),
|
56
|
+
# or a string, in which case it specifies the actual text of the message.
|
57
|
+
adv_attr_accessor :body
|
58
|
+
|
59
|
+
# Specify the from address for the message.
|
60
|
+
adv_attr_accessor :from
|
61
|
+
|
62
|
+
# The recipient addresses for the message, either as a string (for a single
|
63
|
+
# address) or an array (for multiple addresses).
|
64
|
+
adv_attr_accessor :recipients
|
65
|
+
|
66
|
+
# The date on which the message was sent. If not set (the default), the
|
67
|
+
# header will be set by the delivery agent.
|
68
|
+
adv_attr_accessor :sent_on
|
69
|
+
|
70
|
+
# Specify the subject of the message.
|
71
|
+
adv_attr_accessor :subject
|
72
|
+
|
73
|
+
# Specify the template name to use for current message. This is the "base"
|
74
|
+
# template name, without the extension or directory, and may be used to
|
75
|
+
# have multiple publisher methods share the same template.
|
76
|
+
adv_attr_accessor :template
|
77
|
+
|
78
|
+
# we use this to show an image in activities
|
79
|
+
adv_attr_accessor :activitable
|
80
|
+
|
81
|
+
adv_attr_accessor :feed_type
|
82
|
+
|
83
|
+
|
84
|
+
adv_attr_accessor :body_data
|
85
|
+
adv_attr_accessor :title_data
|
86
|
+
|
87
|
+
adv_attr_accessor :title_template
|
88
|
+
adv_attr_accessor :body_template
|
89
|
+
|
90
|
+
# popup text
|
91
|
+
adv_attr_accessor :popup_text
|
92
|
+
|
93
|
+
# popup url
|
94
|
+
adv_attr_accessor :popup_url
|
95
|
+
|
96
|
+
# for notification
|
97
|
+
adv_attr_accessor :buttons
|
98
|
+
|
99
|
+
# Override the publisher name, which defaults to an inflected version of the
|
100
|
+
# publisher's class name. If you want to use a template in a non-standard
|
101
|
+
# location, you can use this to specify that location.
|
102
|
+
def publisher_name(value = nil)
|
103
|
+
if value
|
104
|
+
self.publisher_name = value
|
105
|
+
else
|
106
|
+
self.class.publisher_name
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def publisher_name=(value)
|
111
|
+
self.class.publisher_name = value
|
112
|
+
end
|
113
|
+
|
114
|
+
# The mail object instance referenced by this publisher.
|
115
|
+
attr_reader :feed
|
116
|
+
attr_reader :template_name, :default_template_name, :action_name
|
117
|
+
|
118
|
+
class << self
|
119
|
+
attr_writer :publisher_name
|
120
|
+
|
121
|
+
def publisher_name
|
122
|
+
@publisher_name ||= name.underscore
|
123
|
+
end
|
124
|
+
|
125
|
+
# for ActionView compatibility
|
126
|
+
alias_method :controller_name, :publisher_name
|
127
|
+
alias_method :controller_path, :publisher_name
|
128
|
+
|
129
|
+
def respond_to?(method_symbol, include_private = false) #:nodoc:
|
130
|
+
matches_dynamic_method?(method_symbol) || super
|
131
|
+
end
|
132
|
+
|
133
|
+
def method_missing(method_symbol, *parameters) #:nodoc:
|
134
|
+
match = matches_dynamic_method?(method_symbol)
|
135
|
+
case match[1]
|
136
|
+
when 'create' then new(match[2], *parameters).feed
|
137
|
+
when 'deliver' then new(match[2], *parameters).deliver!
|
138
|
+
when 'register' then new(match[2], *parameters).register!
|
139
|
+
when 'new' then nil
|
140
|
+
else super
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
def register(name)
|
147
|
+
logger.debug "registering template: #{name}" if logger
|
148
|
+
content = new.send(name + "_template")
|
149
|
+
oneline = story = ""
|
150
|
+
case content
|
151
|
+
when String
|
152
|
+
oneline = content
|
153
|
+
when Array
|
154
|
+
oneline,story = content.first,content.last
|
155
|
+
when Hash
|
156
|
+
oneline = content[:oneline]
|
157
|
+
stroy = content[:story]
|
158
|
+
end
|
159
|
+
ActivityTemplate.register("#{self.name}.#{name}",oneline,story)
|
160
|
+
end
|
161
|
+
|
162
|
+
def register_all
|
163
|
+
publisher_instance_methods = self.public_instance_methods - UC::Publisher::Base.public_instance_methods
|
164
|
+
publisher_instance_methods.grep(/_action$/).each do |action|
|
165
|
+
register(action)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def deliver(feed)
|
170
|
+
new.deliver!(feed)
|
171
|
+
end
|
172
|
+
|
173
|
+
def template_root
|
174
|
+
self.view_paths && self.view_paths.first
|
175
|
+
end
|
176
|
+
|
177
|
+
def template_root=(root)
|
178
|
+
self.view_paths = ActionView::Base.process_view_paths(root)
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
|
183
|
+
private
|
184
|
+
def matches_dynamic_method?(method_name) #:nodoc:
|
185
|
+
method_name = method_name.to_s
|
186
|
+
/(create|deliver|register)_([_a-z]\w*)/.match(method_name) || /^(new)$/.match(method_name)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# Instantiate a new publisher object. If +method_name+ is not +nil+, the publisher
|
191
|
+
# will be initialized according to the named method. If not, the publisher will
|
192
|
+
# remain uninitialized (useful when you only need to invoke the "receive"
|
193
|
+
# method, for instance).
|
194
|
+
def initialize(method_name=nil, *parameters) #:nodoc:
|
195
|
+
@controller = Controller.new
|
196
|
+
create!(method_name, *parameters) if method_name
|
197
|
+
end
|
198
|
+
|
199
|
+
def images(src,url=nil)
|
200
|
+
@images << [src,url]
|
201
|
+
end
|
202
|
+
|
203
|
+
|
204
|
+
def create!(method_name, *parameters) #:nodoc:
|
205
|
+
initialize_defaults(method_name)
|
206
|
+
__send__(method_name, *parameters)
|
207
|
+
|
208
|
+
delivery_method case method_name
|
209
|
+
when /_action$/,/_feed$/
|
210
|
+
:action
|
211
|
+
when /_notification$/
|
212
|
+
:notification
|
213
|
+
when /_email$/
|
214
|
+
:email
|
215
|
+
when /_activity$/
|
216
|
+
:activity
|
217
|
+
when /_popup$/
|
218
|
+
:popup
|
219
|
+
else
|
220
|
+
raise "unknow delivery method"
|
221
|
+
end if delivery_method.nil?
|
222
|
+
|
223
|
+
# notification will be sent
|
224
|
+
delivery_method :test if Rails.env == "test" && delivery_method != :notification
|
225
|
+
|
226
|
+
# If an explicit, textual body has not been set, we check assumptions.
|
227
|
+
unless String === @body_template
|
228
|
+
template_exists ||= template_root["#{publisher_name}/#{@template}"]
|
229
|
+
@body_template = render_message(@template, @body_data.merge(@body)) if template_exists
|
230
|
+
end
|
231
|
+
|
232
|
+
# build the feed object itself
|
233
|
+
@feed = create_feed
|
234
|
+
end
|
235
|
+
|
236
|
+
def deliver!(feed = @feed)
|
237
|
+
raise "no feed object available for delivery!" unless feed
|
238
|
+
unless logger.nil?
|
239
|
+
logger.info "Sent feed to #{Array(recipients).join(', ')}"
|
240
|
+
logger.debug "\n#{feed.inspect}"
|
241
|
+
end
|
242
|
+
|
243
|
+
begin
|
244
|
+
m = "perform_delivery_#{delivery_method}"
|
245
|
+
# raise m
|
246
|
+
__send__(m, feed) if perform_deliveries
|
247
|
+
rescue Exception => e # Net::SMTP errors or sendmail pipe errors
|
248
|
+
raise e if raise_delivery_errors
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
private
|
253
|
+
# Set up the default values for the various instance variables of this
|
254
|
+
# publisher. Subclasses may override this method to provide different
|
255
|
+
# defaults.
|
256
|
+
def initialize_defaults(method_name)
|
257
|
+
@charset ||= @@default_charset.dup
|
258
|
+
@template ||= method_name
|
259
|
+
@default_template_name = @action_name = @template
|
260
|
+
@template = @template + ".html" if @template # set default extension name
|
261
|
+
@publisher_name ||= self.class.name.underscore
|
262
|
+
@body_template = nil
|
263
|
+
@title_template = nil
|
264
|
+
@body_data ||= {}
|
265
|
+
@body ||= {}
|
266
|
+
@title_data ||= {}
|
267
|
+
@images = []
|
268
|
+
end
|
269
|
+
|
270
|
+
def render_message(method_name, body)
|
271
|
+
render :file => method_name, :body => body
|
272
|
+
end
|
273
|
+
|
274
|
+
def render(opts)
|
275
|
+
body = opts.delete(:body)
|
276
|
+
if opts[:file] && (opts[:file] !~ /\// && !opts[:file].respond_to?(:render))
|
277
|
+
opts[:file] = "#{publisher_name}/#{opts[:file]}"
|
278
|
+
end
|
279
|
+
|
280
|
+
begin
|
281
|
+
old_template, @template = @template, initialize_template_class(body)
|
282
|
+
layout = respond_to?(:pick_layout, true) ? pick_layout(opts) : false
|
283
|
+
@template.render(opts.merge(:layout => layout))
|
284
|
+
ensure
|
285
|
+
@template = old_template
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def default_template_format
|
290
|
+
:html
|
291
|
+
end
|
292
|
+
|
293
|
+
def default_template(action)
|
294
|
+
|
295
|
+
end
|
296
|
+
=begin
|
297
|
+
def candidate_for_layout?(options)
|
298
|
+
!@template.send(:exempt_from_layout?, default_template_name)
|
299
|
+
end
|
300
|
+
=end
|
301
|
+
|
302
|
+
def template_root
|
303
|
+
self.class.template_root
|
304
|
+
end
|
305
|
+
|
306
|
+
def template_root=(root)
|
307
|
+
self.class.template_root = root
|
308
|
+
end
|
309
|
+
|
310
|
+
def template_path
|
311
|
+
"#{template_root}/#{publisher_name}"
|
312
|
+
end
|
313
|
+
|
314
|
+
def initialize_template_class(assigns)
|
315
|
+
ActionView::Base.new(view_paths, assigns, self)
|
316
|
+
end
|
317
|
+
|
318
|
+
def create_feed
|
319
|
+
return self
|
320
|
+
feed = Feed.new
|
321
|
+
feed.popup_text = popup_text
|
322
|
+
feed.popup_url = popup_url
|
323
|
+
feed.user_id = from
|
324
|
+
feed.feed_type = feed_type
|
325
|
+
feed.title_data = title_data
|
326
|
+
feed.body_data = body_data
|
327
|
+
feed.title_template = title_template
|
328
|
+
feed.body_template = body_template
|
329
|
+
@images.each_with_index do |image,index|
|
330
|
+
feed.send("image_#{index + 1}=",image.first)
|
331
|
+
feed.send("image_#{index + 1}_link=",image.last) if image.last
|
332
|
+
end
|
333
|
+
feed
|
334
|
+
end
|
335
|
+
|
336
|
+
|
337
|
+
# 发送为action
|
338
|
+
def perform_delivery_action(feed)
|
339
|
+
logger.debug "send as action: #{feed.inspect}" if logger
|
340
|
+
logger.debug "from #{from.inspect}" if logger
|
341
|
+
Fcid::Feed.with_session feed.recipients do
|
342
|
+
fcid_feed = Fcid::Feed.new
|
343
|
+
fcid_feed.title_template = feed.title_template
|
344
|
+
fcid_feed.title_data = feed.title_data
|
345
|
+
fcid_feed.body_template = feed.body_template
|
346
|
+
fcid_feed.body_data = feed.body_data
|
347
|
+
images = feed.instance_variable_get(:@images)
|
348
|
+
images.each_with_index do |image,index|
|
349
|
+
fcid_feed.send(:"picture#{index + 1}_url=",image[0])
|
350
|
+
fcid_feed.send(:"picture#{index + 1}_link=",image[1])
|
351
|
+
end
|
352
|
+
fcid_feed.save
|
353
|
+
fcid_feed
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
def perform_delivery_email(feed)
|
358
|
+
email = Fcid::Email.new :user_id=>recipients,:body=>body_template,:subject=>subject
|
359
|
+
email.save
|
360
|
+
end
|
361
|
+
|
362
|
+
# 发送为notification
|
363
|
+
def perform_delivery_notification(feed)
|
364
|
+
logger.debug "send as notification: #{feed.inspect}" if logger
|
365
|
+
# replace as real send notfication
|
366
|
+
notification = Notification.new :type=>feed.feed_type
|
367
|
+
notification.user_id = feed.user_id || recipients
|
368
|
+
notification.message = feed.body_template
|
369
|
+
notification.buttons = [buttons].flatten.compact
|
370
|
+
notification.save!
|
371
|
+
end
|
372
|
+
|
373
|
+
def perform_delivery_popup(feed)
|
374
|
+
if feed.popup_text
|
375
|
+
SessionClient.instance.drb.popup(feed.recipients,feed.popup_text,feed.popup_url,:to=>:self)
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
|
380
|
+
def perform_delivery_test(feed)
|
381
|
+
deliveries << feed
|
382
|
+
end
|
383
|
+
|
384
|
+
|
385
|
+
include ActionMailer::Helpers
|
386
|
+
Dir.glob(File.join(RAILS_ROOT,"app","helpers","*_helper.rb")) do |file|
|
387
|
+
# load all helpers
|
388
|
+
helper_name = File.basename(file).gsub(/_helper.rb$/,'')
|
389
|
+
helper helper_name.to_sym
|
390
|
+
include ActionView::Helpers
|
391
|
+
include "#{helper_name}_helper".classify.constantize
|
392
|
+
end
|
393
|
+
|
394
|
+
self.template_root = [File.join(RAILS_ROOT,"app","views")]
|
395
|
+
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
data/lib/fcid/session.rb
ADDED
data/lib/fcid/user.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#这里似乎有个奇怪的问题 指定model的功能将被禁用
|
3
|
+
module Fcid
|
4
|
+
class User < Base
|
5
|
+
|
6
|
+
def self.sub_domain?(domain)
|
7
|
+
a = domain.split(".").reverse[0,2]
|
8
|
+
b = Fcid.host.split(".").reverse[0,2]
|
9
|
+
return b == a
|
10
|
+
rescue
|
11
|
+
false
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.config
|
15
|
+
Fcid.config
|
16
|
+
end
|
17
|
+
|
18
|
+
#通过auto_token来验证用户,成功返回用户,失败返回 false
|
19
|
+
def self.authenticate_by_auth_token(token)
|
20
|
+
user = get(:info,:token=>token)
|
21
|
+
rsync(user['username'])
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.authenticate(username_or_email,password)
|
25
|
+
get(:authenticate,:email=>username_or_email,:password=>password)
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def self.columns
|
30
|
+
Fcid.columns
|
31
|
+
end
|
32
|
+
|
33
|
+
def avatar(style = "thumb")
|
34
|
+
avatar_url
|
35
|
+
end
|
36
|
+
|
37
|
+
[:username,:email,:password,:password_confirmation].each do |column|
|
38
|
+
define_method "#{column}" do
|
39
|
+
attributes[column.to_s]
|
40
|
+
end
|
41
|
+
|
42
|
+
define_method "#{column}=" do
|
43
|
+
attributes[column.to_s] = column
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
alias_method :name,:username
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Fcid
|
3
|
+
module UserMethods
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
end
|
7
|
+
base.send(:include,InstanceMethods)
|
8
|
+
base.send(:extend,ClassMethods)
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
module InstanceMethods
|
13
|
+
def avatar
|
14
|
+
read_attribute(:avatar).blank? ? "/assets/avatar.gif" : read_attribute(:avatar)
|
15
|
+
end
|
16
|
+
|
17
|
+
def sync
|
18
|
+
self.class.sync id
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
module ClassMethods
|
24
|
+
|
25
|
+
def sync(id)
|
26
|
+
user_res = Fcid::User.find(id)
|
27
|
+
user = find_or_initialize_by_id(id)
|
28
|
+
Fcid.columns.each do |key,value|
|
29
|
+
user.send(:write_attribute,key,user_res.send(value))
|
30
|
+
end
|
31
|
+
user.after_sync if user.respond_to?(:after_sync) # can add other initialize code
|
32
|
+
user.save!
|
33
|
+
user
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
data/lib/fcid/version.rb
ADDED
data/lib/fcid.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "fcid/engine"
|
3
|
+
require "fcid/config"
|
4
|
+
require "fcid/controller"
|
5
|
+
require "fcid/helpers"
|
6
|
+
|
7
|
+
ActionController::Base.send(:include,Fcid::Controller)
|
8
|
+
|
9
|
+
ActionView::Base.send(:include,Fcid::Helpers)
|
10
|
+
|
11
|
+
require "fcid/user"
|
12
|
+
require "fcid/session"
|
data/lib/fcid_client.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "oauth_active_resource"
|
3
|
+
module FcidClient
|
4
|
+
|
5
|
+
def self.register(options = {})
|
6
|
+
OAuthActiveResource.register(self.ancestors.first,self.ancestors.first.const_get('Models'),options)
|
7
|
+
end
|
8
|
+
|
9
|
+
module Models
|
10
|
+
class User < OAuthActiveResource::Resource
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module AuthenticatedSystem
|
3
|
+
protected
|
4
|
+
# Returns true or false if the user is logged in.
|
5
|
+
# Preloads @current_user with the user model if they're logged in.
|
6
|
+
def logged_in?
|
7
|
+
!!current_user
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
# Accesses the current user from the session. Set it to :false if login fails
|
13
|
+
# so that future calls do not hit the database.
|
14
|
+
def current_user
|
15
|
+
#@current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie || login_from_url )
|
16
|
+
@current_user ||= (login_from_session || login_from_basic_auth || login_from_url )
|
17
|
+
end
|
18
|
+
|
19
|
+
# Store the given user in the session.
|
20
|
+
def current_user=(new_user)
|
21
|
+
session[:user] = (new_user.nil? || new_user.is_a?(Symbol)) ? nil : new_user.id
|
22
|
+
@current_user = new_user
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check if the user is authorized
|
26
|
+
#
|
27
|
+
# Override this method in your controllers if you want to restrict access
|
28
|
+
# to only a few actions or if you want to check if the user
|
29
|
+
# has the correct rights.
|
30
|
+
#
|
31
|
+
# Example:
|
32
|
+
#
|
33
|
+
# # only allow nonbobs
|
34
|
+
# def authorized?
|
35
|
+
# current_user.login != "bob"
|
36
|
+
# end
|
37
|
+
def authorized?
|
38
|
+
logged_in?
|
39
|
+
end
|
40
|
+
|
41
|
+
# Filter method to enforce a login requirement.
|
42
|
+
#
|
43
|
+
# To require logins for all actions, use this in your controllers:
|
44
|
+
#
|
45
|
+
# before_filter :login_required
|
46
|
+
#
|
47
|
+
# To require logins for specific actions, use this in your controllers:
|
48
|
+
#
|
49
|
+
# before_filter :login_required, :only => [ :edit, :update ]
|
50
|
+
#
|
51
|
+
# To skip this in a subclassed controller:
|
52
|
+
#
|
53
|
+
# skip_before_filter :login_required
|
54
|
+
#
|
55
|
+
def login_required
|
56
|
+
authorized? || access_denied
|
57
|
+
end
|
58
|
+
|
59
|
+
# Redirect as appropriate when an access request fails.
|
60
|
+
#
|
61
|
+
# The default action is to redirect to the login screen.
|
62
|
+
#
|
63
|
+
# Override this method in your controllers if you want to have special
|
64
|
+
# behavior in case the user is not authorized
|
65
|
+
# to access the requested action. For example, a popup window might
|
66
|
+
# simply close itself.
|
67
|
+
def access_denied
|
68
|
+
respond_to do |accepts|
|
69
|
+
accepts.html do
|
70
|
+
store_location
|
71
|
+
redirect_to :controller => '/fcid/session', :action => 'new'
|
72
|
+
end
|
73
|
+
accepts.xml do
|
74
|
+
headers["Status"] = "Unauthorized"
|
75
|
+
headers["WWW-Authenticate"] = %(Basic realm="Web Password")
|
76
|
+
render :text => "Could't authenticate you", :status => '401 Unauthorized'
|
77
|
+
end
|
78
|
+
|
79
|
+
#added by aotianlong
|
80
|
+
accepts.js do
|
81
|
+
render :update do |page|
|
82
|
+
page << "try{"
|
83
|
+
page.login_dialog.show
|
84
|
+
page << "} catch(e){}"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
false
|
89
|
+
end
|
90
|
+
|
91
|
+
# Store the URI of the current request in the session.
|
92
|
+
#
|
93
|
+
# We can return to this location by calling #redirect_back_or_default.
|
94
|
+
def store_location
|
95
|
+
session[:return_to] = request.request_uri
|
96
|
+
end
|
97
|
+
|
98
|
+
# Redirect to the URI stored by the most recent store_location call or
|
99
|
+
# to the passed default.
|
100
|
+
def redirect_back_or_default(default)
|
101
|
+
redirect_to(session[:return_to] || default)
|
102
|
+
session[:return_to] = nil
|
103
|
+
end
|
104
|
+
|
105
|
+
# Inclusion hook to make #current_user and #logged_in?
|
106
|
+
# available as ActionView helper methods.
|
107
|
+
def self.included(base)
|
108
|
+
base.send :helper_method, :current_user, :logged_in?
|
109
|
+
end
|
110
|
+
|
111
|
+
# Called from #current_user. First attempt to login by the user id stored in the session.
|
112
|
+
def login_from_session
|
113
|
+
self.current_user = User.find_by_id(session[:user]) if session[:user]
|
114
|
+
end
|
115
|
+
|
116
|
+
# Called from #current_user. Now, attempt to login by basic authentication information.
|
117
|
+
def login_from_basic_auth
|
118
|
+
username, passwd = get_auth_data
|
119
|
+
self.current_user = User.authenticate(username, passwd) if username && passwd
|
120
|
+
end
|
121
|
+
|
122
|
+
# Called from #current_user. Finaly, attempt to login by an expiring token in the cookie.
|
123
|
+
def login_from_cookie
|
124
|
+
user = cookies[:auth_token] && User.find_by_remember_token(cookies[:auth_token])
|
125
|
+
if user && user.remember_token?
|
126
|
+
user.remember_me
|
127
|
+
cookies[:auth_token] = { :value => user.remember_token, :expires => user.remember_token_expires_at }
|
128
|
+
self.current_user = user
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def login_from_url
|
133
|
+
fcid_auth_token = params[:fcid_auth_token]
|
134
|
+
if fcid_auth_token
|
135
|
+
user = Fcid::User.get(:authenticate,:fcid_auth_token=>fcid_auth_token)
|
136
|
+
if user
|
137
|
+
user_id = user["id"]
|
138
|
+
User.sync(user_id)
|
139
|
+
self.current_user = User.find(user_id)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
@@http_auth_headers = %w(Authorization HTTP_AUTHORIZATION X-HTTP_AUTHORIZATION X_HTTP_AUTHORIZATION REDIRECT_X_HTTP_AUTHORIZATION)
|
146
|
+
|
147
|
+
# gets BASIC auth info
|
148
|
+
def get_auth_data
|
149
|
+
auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) }
|
150
|
+
auth_data = request.env[auth_key].to_s.split unless auth_key.blank?
|
151
|
+
return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil]
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module AuthenticatedTestHelper
|
3
|
+
# Sets the current user in the session from the user fixtures.
|
4
|
+
def login_as(user)
|
5
|
+
@request.session[:user] = user ? users(user).id : nil
|
6
|
+
end
|
7
|
+
|
8
|
+
def authorize_as(user)
|
9
|
+
@request.env["HTTP_AUTHORIZATION"] = user ? "Basic #{Base64.encode64("#{users(user).login}:test")}" : nil
|
10
|
+
end
|
11
|
+
end
|