Skip to content
Newer
Older
100644 496 lines (353 sloc) 16.4 KB
108b8f5 @kristianmandrup much better notification system :)
authored Aug 2, 2012
1 # Controll
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
2
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
3 Some nice and nifty utilities to help you manage complex controller logic.
4
5 ## Requirements
6
7 This gem is designed for Rails 3+ and currently only supports (has been tested with) Ruby 1.9+. The gem is under development but stable releases will be pushed to rubygems. Note that older versions may not support the same API described in the README. Go back in history and/or browse the code for that specific version.
8
9 Enjoy :)
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
10
189b657 @kristianmandrup updated readme and small fix
authored Dec 7, 2012
11 ## Install
12
13 in Gemfile:
14
15 ```ruby
16 gem 'imperator-ext'
17 gem 'controll'
18 ```
19
20 Bundle it!
21
22 `$ bundle`
23
24 Usage: See below, incl. the Generators section ;)
25
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
26 ## Background
27
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
28 This gem contains logic extracted from my [oauth_assist](https://github.com/kristianmandrup/oauth_assist) gem (and engine) which was a response to this article [oauth pure tutorial](http://www.communityguides.eu/articles/16).
29
30 Note that the *oauth_assist* gem is not yet fully functional and done, as it "awaits" a stable release of this gem. Please feel free to help out in this effort!
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
31
32 ## Justification
33
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
34 As you can see, the following `#create` REST action is a nightmare of complexity and flow control leading to various different flash messages and redirect/render depending on various outcomes...
35
36 Then I naturally thought: *There MUST be a better way!*
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
37
38 ```ruby
39 def create
40 # get the service parameter from the Rails router
41 params[:service] ? service_route = params[:service] : service_route = 'No service recognized (invalid callback)'
42
43 # get the full hash from omniauth
44 omniauth = request.env['omniauth.auth']
45
46 # continue only if hash and parameter exist
47 if omniauth and params[:service]
48
49 # map the returned hashes to our variables first - the hashes differs for every service
50
51 # create a new hash
52 @authhash = Hash.new
53
54 extract_auth_data!
55
56 if unknown_auth?
57 # debug to output the hash that has been returned when adding new services
58 render :text => omniauth.to_yaml
59 return
60 end
61
62 if @authhash[:uid] != '' and @authhash[:provider] != ''
63
64 auth = Service.find_by_provider_and_uid(@authhash[:provider], @authhash[:uid])
65
66 # if the user is currently signed in, he/she might want to add another account to signin
67 if user_signed_in?
68 if auth
69 flash[:notice] = 'Your account at ' + @authhash[:provider].capitalize + ' is already connected with this site.'
70 redirect_to services_path
71 else
72 current_user.services.create!(:provider => @authhash[:provider], :uid => @authhash[:uid], :uname => @authhash[:name], :uemail => @authhash[:email])
73 flash[:notice] = 'Your ' + @authhash[:provider].capitalize + ' account has been added for signing in at this site.'
74 redirect_to services_path
75 end
76 else
77 if auth
78 # signin existing user
79 # in the session his user id and the service id used for signing in is stored
80 session[:user_id] = auth.user.id
81 session[:service_id] = auth.id
82
83 flash[:notice] = 'Signed in successfully via ' + @authhash[:provider].capitalize + '.'
84 redirect_to root_url
85 else
86 # this is a new user; show signup; @authhash is available to the view and stored in the sesssion for creation of a new user
87 session[:authhash] = @authhash
88 render signup_services_path
89 end
90 end
91 else
92 flash[:error] = 'Error while authenticating via ' + service_route + '/' + @authhash[:provider].capitalize + '. The service returned invalid data for the user id.'
93 redirect_to signin_path
94 end
95 else
96 flash[:error] = 'Error while authenticating via ' + service_route.capitalize + '. The service did not return valid data.'
97 redirect_to signin_path
98 end
99 end
100 ```
101
102 Using the tools contained in `controll` the above logic can be encapsulated like this:
103
104 ```ruby
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
105 class ServicesController < ApplicationController
106 include Controll::Enabler
107
108 def create
109 execute # action.perform
110 end
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
111 end
112 ```
113
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 22, 2012
114 A `Flow` can use Executors to encapsulate execution logic, which again can execute Commands that encapsulate business logic related to the user Session or models (data).
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
115
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
116 The Flow takes the last event on the event stack and consults the ActionPaths registered, usually a Redirecter and Renderer. An ActionPath is a type of Action which can return a path. The Flow initiates an Executor which iterates the ActionPaths to find the first one which can match the event.
488e02e @kristianmandrup rename flowhandler actions
authored Aug 19, 2012
117
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
118 The first one with a match is returned as the Action, which the controller can then perform in order to either render or redirect.
119
488e02e @kristianmandrup rename flowhandler actions
authored Aug 19, 2012
120 If none of the ActionPaths can match the event, a Fallback Action is returned. The controller should then be configured to handle a Fallback Action appropriately.
121
122 Controll has built in Notification Management which work both for flash messages (or other types of notifications) and as return codes for use in flow-control logic.
123
124 All events in the event stack are processed and can fx be put on the flash hash according to event type, fx `flash[:error]` for an `:error` event etc.
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
125
488e02e @kristianmandrup rename flowhandler actions
authored Aug 19, 2012
126 The Notification system works by mapping events to messages in a central location, similar to mapping events to paths.
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
127
488e02e @kristianmandrup rename flowhandler actions
authored Aug 19, 2012
128 Using these Controll artifacts/systems, you can avoid the typical Rails anti-pattern of Thick controllers, without bloating your Models with unrelated model logic or pulling in various Helper modules which pollute the space of the Controller!
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
129
130 ## Usage
131
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
132 The recommended approach to handle complex Controller logic using Controll:
133
488e02e @kristianmandrup rename flowhandler actions
authored Aug 19, 2012
134 * Enable Controll on Controller
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
135 * Configure Controller with Flow, Commander and Notifier
488e02e @kristianmandrup rename flowhandler actions
authored Aug 19, 2012
136
137 * Create Commands for Commander
138 * Define events corresponding to commands
139 * Configure Commander with Command methods
140
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
141 * Create Flow
142 * Configure Flow with Render and Redirect event mappings
488e02e @kristianmandrup rename flowhandler actions
authored Aug 19, 2012
143
144 * Create Notifier
145 * Configure Notifier with Event handlers and event -> message mappings
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
146
147 ## Controll enabling a Controller
148
149 In your controller include the `Controll::Enabler` module.
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
150
151 ```ruby
152 class ServicesController < ApplicationController
153 before_filter :authenticate_user!, :except => accessible_actions
154 protect_from_forgery :except => :create
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
155
156 # see 'controll' gem
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
157 include Controll::Enabler
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
158 end
159 ```
160
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
161 Better yet, to make it available for all controllers, include it in your ApplicationController or any base controller of your choice.
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
162
163 ```ruby
164 class ApplicationController
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
165 include Controll::Enabler
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
166 end
167 ```
168
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
169 You can also include the `Controll::Macros` module in a base Controller class of your choosing, fx:
170
171 ```ruby
172 class ApplicationController
173 include Controll::Macros
174 end
175 ```
176
177 Then you can use the `#enable_controll` macro in any subclass Controller class:
178
179 ```ruby
180 class ServicesController < ApplicationController
181 enable_controll
182 end
183 ```
184
185 ## Controll configuration
186
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
187 In your Controller you should define a Notifier and Commander to be used.
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
188
189 ```ruby
190 class ServicesController < ApplicationController
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
191 enable_controll
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
192
193 ...
194
195 protected
196
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
197 notifier :services
b9f95f3 @kristianmandrup refactor big time
authored Aug 3, 2012
198 commander :services
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
199
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
200 # or simply (using naming convention)
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
201 controll :notifier, :commander
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
202
203 def create
204 create_action.perform
205 end
206
207 protected
208
209 def create_action
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
210 @create_action ||= Flows::CreateService.new(self)
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
211 end
212
213 fallback do |event|
214 event == :no_auth ? render(:text => omniauth.to_yaml) : fallback_action
215 end
216
217 def fallback_action
218 redirect_to root_url
219 end
220 end
221 ```
222
223 ### Focused Controller config
224
225 In case you use Focused Controller, this can be strutctured even better like this:
226
227 ```ruby
228 class ServicesController
229
230 # could be extracted into "global" namespace for reuse across controllers...
231 module ControllAction
232 extend ActiveSupport::Concern
233
234 included do
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
235 controll :notifier, :commander, :flow
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
236 end
237
238 def fallback_action
239 redirect_to root_url
240 end
241 end
242
243 class Create < FocusedAction
244 include ControllAction
245
246 run do
247 execute
248 end
249
250 protected
251
252 fallback do |event|
253 event == :no_auth ? render(:text => omniauth.to_yaml) : fallback_action
254 end
255 end
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
256 end
257 ```
258
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
259 *Wow! Now we're talking!!!!*
260
261 ## Creating a Commander
262
263 The Commander is your command center for a group of related commands. Typically you will want to define a Commander for a specific controller if the controller has more than 3 commands. If you put your Commander under the `Commanders` namespace (module) you get direct access to the Commander constant to be used as subclass.
264
265 The Commander should contain a group of command methods that are conceptually in the same "category", fx all the command for a particular controller.
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
266
267 ```ruby
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
268 module Commanders
269 class Services < Commander
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
270 # create basic command methods
271 command_methods :cancel_commit, :create_account, :signout
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
272
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
273 # create custom command method with custom argument hash
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
274 def sign_in_command
275 @sign_in_command ||= SignInCommand.new auth_hash: auth_hash, user_id: user_id, service_id: service_id, service_hash: service_hash, initiator: self
276 end
b9f95f3 @kristianmandrup refactor big time
authored Aug 3, 2012
277
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
278 command_method :sign_out do
279 @sign_out_command ||= SignOutCommand.new user_id: user_id, service_id: service_id, service_hash: service_hash, initiator: self
280 end
281
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
282 # delegations (alias for initiator_methods )
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
283 controller_methods :auth_hash, :user_id, :service_id, :service_hash
284 end
b9f95f3 @kristianmandrup refactor big time
authored Aug 3, 2012
285 end
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
286 ```
287
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
288 The `Commander class extends `Imperator::Command::MethodFactory` making `#command_method` and `#command_methods` available. These class macros can be used to create command methods that only take the initiator (in this case the controller) as argument.
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
289
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
290 For how to implement the Commands themselves, see the [imperator-ext](https://github.com/kristianmandrup/imperator-ext) gem.
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
291
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
292 ## Flows
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
293
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
294 For Controller actions that require complex flow control, use a Flow:
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
295
296 ```ruby
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
297 module Flows
08347f0 @kristianmandrup flow executor spec
authored Aug 22, 2012
298 class CreateService < Flow
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
299
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
300 # event method that returns the event to be processed by the flow handler
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
301 event do
302 Executors::Authenticator.new(controller).execute
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
303 end
304
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
305 # configuration of the Renderer ActionHandler
306 # will return a Renderer Action if it matches the event
566cb65 @kristianmandrup refactor to complex and simple slow mappers
authored Aug 20, 2012
307 renderer :simple do
308 events :signed_in_new_user, :signed_in do
309 signup_services_path
310 end
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
311 end
312
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
313 # configuration of the Redirecter ActionHandler
314 # will return a Redirecter Action if it matches the event
566cb65 @kristianmandrup refactor to complex and simple slow mappers
authored Aug 20, 2012
315 redirecter :complex do
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
316 # redirection mappings for :notice events
748df58 @kristianmandrup updated README with most recent flowhandler api
authored Aug 21, 2012
317 event_map :notice do
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
318 {
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
319 signup_services_path: :signed_in_new_user
320 services_path: [:signed_in_connect, :signed_in_new_connect]
321 root_url: [:signed_in_user, :other]
322 }
323 end
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
324
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
325 # redirection mappings for :error events
748df58 @kristianmandrup updated README with most recent flowhandler api
authored Aug 21, 2012
326 event_map :error, signin_path: [:error, :invalid, :auth_error]
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
327 end
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
328 end
329 end
330 ```
331
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
332 The `#renderer` and `#redirector` macros will each create a Class of the same name that inherit from Controll::Flow::ActionMapper::Simple or Controll::Flow::ActionMapper::Complex.
e81f2cd @kristianmandrup updated README for new flow handler structure
authored Aug 20, 2012
333 You can also define these classes directly yourself instead of using the macros.
334 The *simple* action mapper maps a list of events to a single path and otherwise falls back.
335 The complex action mapper maps the event to an event hash for each registered event type.
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
336
e81f2cd @kristianmandrup updated README for new flow handler structure
authored Aug 20, 2012
337 In the `Redirecter` class we are setting up a mapping for various paths, for each path specifying which events should cause a redirect to that path.
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
338
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
339 If you are rendering or redirecting to paths that take arguments, you can either extend the `#action` class method of your Redirect or Render class implementation or you can define a `#use_alternatives` method in your `Flow` that contains this particular flow logic.
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
340
e81f2cd @kristianmandrup updated README for new flow handler structure
authored Aug 20, 2012
341 Note: For mapping paths that take arguments, there should be an option to take a block (closure) to be late-evaluated on the controller context ;)
566cb65 @kristianmandrup refactor to complex and simple slow mappers
authored Aug 20, 2012
342
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
343 ## The Executor
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
344
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
345 The `Authenticator` class shown below inherits from `Executor::Notificator` which uses `#method_missing` in order to delegate any missing method back to the controller of the Executor. The Flow passed in the controller. This means that calls can be executed directly on the controller, such as making notifications etc.
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
346
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
347 The `#result` call at the end of `#execute` ensures that the last notification event is returned, to be used for deciding what to render or where to redirect (see Flow).
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
348
349 ```ruby
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
350 module Executors
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
351 class Authenticator < Controlled
352
353 # ensures pattern:
354 # - perform validations and only execute command if no error
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
355 def execute
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
356 super
357 result
358 end
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
359
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
360 protected
361
362 controller_methods :omniauth, :service, :auth_hash, :auth_valid?
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
363
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
364 def do_command
b9f95f3 @kristianmandrup refactor big time
authored Aug 3, 2012
365 command! :sign_in
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
366 end
367
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
368 def validations
369 # creates an error notification named :error
370 error and return unless valid_params?
371
372 # creates an error notification named :auth_invalid
373 error(:auth_invalid) and return unless auth_valid?
374 end
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
375
376 def valid_params?
377 omniauth and service and auth_hash
378 end
379 end
380 end
381 ```
382
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
383 Alternatively you can use the execute block macro to generate the `#execute` instance method and ensure that it ends by returning result.
384
385 ```ruby
386 execute do
387 # error/validation checks? ...
388 command! :sign_in
389 end
390 ```
391
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
392 To encapsulate more complex busines logic affecting the user Session or Model data, we execute an Imperator Command (see `imperator` gem) called :sign_in that we registered in the Commander of the Controller.
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
393
4a25895 @kristianmandrup major refactor
authored Aug 5, 2012
394 ## Notifier
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
395
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
396 Now we are finally ready to define the notifier to handle the different types of notification events.
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
397
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
398 The example below demonstrates several different ways you can define messages for events:
399
400 * using the `#messages` method to return a hash of mappings.
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
401 * define a method for the event name that returns a String (handles argument replacement)
402 * i18n locale mapping `[handler class path].[notification type].[event name]`.
0d8ab3f @kristianmandrup cleaned up messaging
authored Aug 3, 2012
403
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
404 ```ruby
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
405 module Notifiers
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
406 class Services < Typed
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
407 handler :error do
408 messages do
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
409 {
410 must_sign_in: 'You need to sign in before accessing this page!',
108b8f5 @kristianmandrup much better notification system :)
authored Aug 2, 2012
411
412 auth_service_error: %q{There was an error at the remote authentication service.
413 You have not been signed in.},
414
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
415 cant_delete_current_account: 'You are currently signed in with this account!',
416 user_save_error: 'This is embarrassing! There was an error while creating your account from which we were not able to recover.',
417 }
418 end
419
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
420 msg :auth_error! do
421 "Error while authenticating via #{service_name}. The service did not return valid data."
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
422 end
423
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
424 msg :auth_invalid! do
108b8f5 @kristianmandrup much better notification system :)
authored Aug 2, 2012
425 'Error while authenticating via {{full_route}}. The service returned invalid data for the user id.'
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
426 end
427 end
108b8f5 @kristianmandrup much better notification system :)
authored Aug 2, 2012
428
429
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
430 handler :notice do
108b8f5 @kristianmandrup much better notification system :)
authored Aug 2, 2012
431 # for :signed_in and :signed_out - defined in locale file under:
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
432 # notifiers:
433 # services:
434 # notice:
435 # signed_in: 'Your account has been created and you have been signed in!'
436 # signed_out: 'You have been signed out!'
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
437
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
438 msg :already_connected do
108b8f5 @kristianmandrup much better notification system :)
authored Aug 2, 2012
439 'Your account at {{provider_name}} is already connected with this site.'
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
440 end
441
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
442 msg :account_added do
108b8f5 @kristianmandrup much better notification system :)
authored Aug 2, 2012
443 'Your {{provider_name}} account has been added for signing in at this site.'
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
444 end
445
ff8594d @kristianmandrup major refactor again :)
authored Aug 16, 2012
446 msg :sign_in_success do
108b8f5 @kristianmandrup much better notification system :)
authored Aug 2, 2012
447 'Signed in successfully via {{provider_name}}.'
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
448 end
449 end
450 end
451 end
452 ```
453
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
454 ## Rails Generators
455
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
456 ### Setup generator
457
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
458 `$ rails g controll:setup`
459
460 Generate only specific controll folders
461
462 `$ rails g controll:setup commanders notifiers`
463
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
464 ### Controll artifact generators
465
466 * assistant
467 * executor
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
468 * flow
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
469 * notifier
470
471 Example usage:
472
c265e4c @kristianmandrup renamed flow_handler to flow
authored Aug 21, 2012
473 `$ rails g controll:flow create_service`
b2e3332 @kristianmandrup more refactor and better README
authored Aug 18, 2012
474
475 Use `-h` for help on any specific controller for more usage options and info.
476
84b9246 @kristianmandrup bump version
authored Sep 17, 2012
477 ## Notice
478
479 Due to a lot of recent API changes in order to simplify and improve usage, the README docs for the API might potentially contain a few inconsistencies with the code. Please notify me if you spot one. Thanks. See the specs and/or code in order to see the real API in this case.
480
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
481 ## Contributing to controll
482
483 * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
484 * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
485 * Fork the project.
486 * Start a feature/bugfix branch.
487 * Commit and push until you are happy with your contribution.
488 * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
489 * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
490
00e74a1 @kristianmandrup generators and engine added
authored Aug 16, 2012
491 ## Copyright
3cf7dcb @kristianmandrup initial structure and README
authored Aug 2, 2012
492
493 Copyright (c) 2012 Kristian Mandrup. See LICENSE.txt for
494 further details.
495
Something went wrong with that request. Please try again.