Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jpmckinney/token_action
Rails engine to redeem tokens and perform actions
https://github.com/jpmckinney/token_action
Last synced: about 1 month ago
JSON representation
Rails engine to redeem tokens and perform actions
- Host: GitHub
- URL: https://github.com/jpmckinney/token_action
- Owner: jpmckinney
- License: mit
- Created: 2013-01-05T18:33:56.000Z (almost 12 years ago)
- Default Branch: master
- Last Pushed: 2018-05-23T04:24:59.000Z (over 6 years ago)
- Last Synced: 2024-11-16T04:52:40.371Z (about 2 months ago)
- Language: Ruby
- Homepage:
- Size: 89.8 KB
- Stars: 0
- Watchers: 5
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# TokenAction
[![Gem Version](https://badge.fury.io/rb/token_action.svg)](https://badge.fury.io/rb/token_action)
[![Build Status](https://secure.travis-ci.org/jpmckinney/token_action.png)](https://travis-ci.org/jpmckinney/token_action)
[![Coverage Status](https://coveralls.io/repos/jpmckinney/token_action/badge.png)](https://coveralls.io/r/jpmckinney/token_action)
[![Code Climate](https://codeclimate.com/github/jpmckinney/token_action.png)](https://codeclimate.com/github/jpmckinney/token_action)TokenAction lets you create tokens to be used to authenticate actions. For example:
* Create a token for a user to confirm an account
* Create a token for a subscriber to unsubscribe from notifications
* Create a token for a user to confirm a change of email address## Getting Started
TokenAction works with Rails 3.1 onwards. Add it to your Gemfile:
gem 'token_action'
Install the gem and configure your application to use TokenAction with:
bundle
bundle exec rails generate token_actionIf you are using ActiveRecord, run the migration:
bundle exec rake db:migrate
## Basic Usage
Create a shared secret to confirm a user account, for example:
token = TokenAction::Token.create! kind: 'User', args: [1, :confirm]
token.token # a 20-character alphanumeric string like "j7NtCaYfUpZXyDCseKG2"You can then send the token with instructions to the user via email. When the user visits `/tokens/j7NtCaYfUpZXyDCseKG2/confirm`, TokenAction will look up the token. If not found, it will log an informational message to the Rails logger, set `flash[:alert]` and redirect to the `root_path`. If found, it will call the `redeem_token` method on the `User` class, passing in the arguments `1` and `:confirm`. You must implement the public `redeem_token` method. For example:
class User < ActiveRecord::Base
def self.redeem_token(id, meth)
User.find(id).send(meth)
enddef confirm
update_attribute :confirmed, true
end
endIf an exception is raised, TokenAction will log a warning message to the Rails logger, set `flash[:alert]` and redirect to the `root_path`. If no exception is raised, TokenAction will set `flash[:notice]` and redirect to the `root_path`. That's it!
## Customization
You can customize the redirect URLs, the routes, the flash messages and the tokens controller.
### Redirect URLs
To change the default success and failure URLs from `root_path`, edit the `config/initializers/token_action.rb` file created by `rails generate token_action`. You may also set success and failure URLs for each token, by creating tokens with `:success_url` and `:failure_url` arguments:
token = TokenAction::Token.create! kind: 'Cat', success_url: cat_path(1), failure_url: '/oops'
**Note:** If you change your URL structure after creating tokens, TokenAction may attempt to redirect to an unroutable path. If a path is unroutable, TokenAction will redirect to another URL in this order of precedence:
* `Token#success_url`
* `TokenAction.success_url`
* `root_path`If an exception was raised and a path is unroutable, it will redirect in this order of precedence:
* `Token#failure_url`
* `TokenAction.failure_url`
* `root_path`### Routes
The TokenAction generator will add `mount TokenAction::Engine => '/token_action'` to your routes, which defines:
get 'tokens/:token/*path', to: 'tokens#redeem'
As such, you can write URLs like `tokens/xxx/confirm` or `tokens/xxx/unsubscribe` or `tokens/xxx/a/b/c`.
To customize the first part of the route, replace `mount TokenAction::Engine => '/token_action'` with something like:
get 'jetons/:token/*path', to: 'token_action/tokens#redeem'
### Flash messages
The TokenAction generator will create a `config/locales/token_action.en.yml` file with the default messages for when a token is not found, an exception is raised, or the action is performed successfully. You will probably want to change these messages depending on the action taken and the exception raised.
* If a token was redeemed by accessing a URL like `tokens/xxx/confirm`, TokenAction will look for a message in the scope `token_action.tokens.confirm`. If not found, it will default to the scope `token_action.tokens.default`.
* If a token was redeemed by accessing a long URL like `tokens/xxx/a/b/c`, TokenAction will look for a message in the scope `token_action.tokens.a.b.c`.
You may want to raise an exception if an action has already been performed or if it is no longer valid, in which case you may want the failure message to change according to the exception raised.
* If an `AlreadyConfirmed` exception is raised, TokenAction will look for a message in the scope `token_action.tokens.default.already_confirmed`. If not found, it will default to `token_action.tokens.default.failure`.
* If a namespaced `MyModule::AlreadyConfirmed` exception is raised, TokenAction will look for a message in the scope `token_action.tokens.default.my_module.already_confirmed`.
Putting it all together, if an `AlreadyConfirmed` exception is raised accessing a URL like `tokens/xxx/confirm`, TokenAction will look for messages in this order of preference:
* `token_action.tokens.confirm.already_confirmed`
* `token_action.tokens.default.already_confirmed`
* `token_action.tokens.confirm.failure`
* `token_action.tokens.default.failure`### Tokens controller
To customize the controller without monkey patching, create a new controller like:
class TokensController < TokenAction::TokensController
endAnd replace the route with something like:
get 'tokens/:token/*path', to: 'tokens#redeem'
You can then override the `redeem` method in your new controller.
## Supported ORMs
* [ActiveRecord](https://rubygems.org/gems/activerecord)
* [Mongoid](https://rubygems.org/gems/mongoid)It should be easy to add adapters for [MongoMapper](https://rubygems.org/gems/mongo_mapper), DataMapper, Sequel and CouchPotato. If you are using DataMapper or Sequel, you must use an ActiveModel compliance plugin:
* [DataMapper plugin](https://github.com/datamapper/dm-active_model)
* [Sequel plugin](http://sequel.rubyforge.org/rdoc-plugins/classes/Sequel/Plugins/ActiveModel.html)If using Sequel, you will want to use the [orm_adapter-sequel](https://github.com/elskwid/orm_adapter-sequel) gem. If using CouchPotato, you will need to write your own adapter for ORM Adapter.
## Caveats
* If you change the name of a class, update the `kind` attribute on its tokens to avoid making them unprocessable.
* Be careful when changing the behavior of a `redeem_token` method, to avoid making tokens unprocessable.Copyright (c) 2012 James McKinney, released under the MIT license