Skip to content

Commit

Permalink
Merge pull request #2 from i2bskn/feature/update
Browse files Browse the repository at this point in the history
Update to 0.2.0
  • Loading branch information
i2bskn committed Nov 23, 2014
2 parents bfec7d5 + e1d6979 commit ec1f09f
Show file tree
Hide file tree
Showing 95 changed files with 1,838 additions and 1,592 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ language: ruby
rvm:
- 2.0.0
- 2.1.0
branches:
only:
- master
gemfile:
- Gemfile
script: bundle exec rake spec
Expand Down
31 changes: 30 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,35 @@
## 0.2.0

Remake the this library.

#### Upgrade

1. Run the following commands.

```
$ bundle update passwd
$ bundle exec rails gneratate passwd:config
```

2. Migrate your passwd settings to `config/initializers/passwd.rb`.
3. Updates your code!

#### Changes

- Add extention to ActiveController.
- Add `current_user`, `signin!` and `signout!` to ActionController.
- Add `require_signin` method for `before_action`.
- Include the `Passwd::ActiveRecord` was no longer needed.
- Rename method `define_column` to `with_authenticate` in your User model.
- Rename method `Passwd.create` to `Passwd.random`.
- Rename method `Passwd.hashing` to `Passwd.digest`.
- Add `passwd` method User class. Create Passwd::Password object from target user attributes.
- Split object password and salt.

## 0.1.5

Features:
#### Changes

- Can be specified algorithm of hashing
- Change default hashing algorithm to SHA512 from SHA1

3 changes: 2 additions & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2013 i2bskn
Copyright (c) 2013-2014 i2bskn

MIT License

Expand All @@ -20,3 +20,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

252 changes: 96 additions & 156 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,230 +1,170 @@
# Passwd

[![Gem Version](https://badge.fury.io/rb/passwd.png)](http://badge.fury.io/rb/passwd)
[![Build Status](https://travis-ci.org/i2bskn/passwd.png?branch=master)](https://travis-ci.org/i2bskn/passwd)
[![Coverage Status](https://coveralls.io/repos/i2bskn/passwd/badge.png?branch=master)](https://coveralls.io/r/i2bskn/passwd?branch=master)
[![Code Climate](https://codeclimate.com/github/i2bskn/passwd.png)](https://codeclimate.com/github/i2bskn/passwd)
[![Gem Version](https://badge.fury.io/rb/passwd.svg)](http://badge.fury.io/rb/passwd)
[![Build Status](https://travis-ci.org/i2bskn/passwd.svg?branch=master)](https://travis-ci.org/i2bskn/passwd)
[![Coverage Status](https://img.shields.io/coveralls/i2bskn/passwd.svg)](https://coveralls.io/r/i2bskn/passwd?branch=master)
[![Code Climate](https://codeclimate.com/github/i2bskn/passwd/badges/gpa.svg)](https://codeclimate.com/github/i2bskn/passwd)

Password utilities.
Password utilities and integration to Rails.

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'passwd'
gem "passwd"
```

And then execute:

$ bundle

Or install it yourself as:

$ gem install passwd

## Usage

```ruby
require 'passwd'
```
### ActiveRecord with Rails

### Create random password
Add authentication to your `User` model.
Model name is `User` by default, but can be changed in configuration file.

```ruby
password = Passwd.create
class User < ActiveRecord::Base
with_authenticate
end
```

### Hashing password
#### Options

Hashing with SHA1.
User model The following column are required.
Column name can be changed with the specified options.

```ruby
password_hash = Passwd.hashing(password)
```

### Password settings
- `:id => :email` Unique value to be used for authentication.
- `:salt => :salt` Column of String to save the salt.
- `:password => :password` Column of String to save the hashed password.

Default config is stored in the class instance variable.
Changing the default configs are as follows:
Use the `name` column as id.

```ruby
Passwd.config # => Get config object.
Passwd.config(length: 10) # => Change to the default length.

Passwd.configure do |c|
c.algorithm = :sha512
c.length = 10
class User < ActiveRecord::Base
with_authenticate id: :name
end
```

Options that can be specified:

* :algorithm => Hashing algorithm. default is :sha512.
* :length => Number of characters. default is 8.
* :lower => Skip lower case if set false. default is true.
* :upper => Skip upper case if set false. default is true.
* :number => Skip numbers if set false. default is true.
* :letters_lower => Define an array of lower case. default is ("a".."z").to_a
* :letters_upper => Define an array of upper case. default is ("A".."Z").to_a
* :letters_number => Define an array of numbers. default is ("0".."9").to_a
#### Authenticate

### Policy check

Default policy is 8 more characters and require lower case and require number.
`authenticate` method is available in both instance and class.
Returns user object if the authentication successful.
Returns nil if authentication fails or doesn't exists user.
Instance method is not required `id`.

```ruby
Passwd.policy_check("secret") # => true or false
user = User.authenticate(params[:email], params[:password]) # => return user object or nil.
user.authenticate(params[:password])
```

### Policy settings
`set_password` method will be set random password.
To specify password as an argument if you want to specify a password.

```ruby
Passwd.policy_configure do |c|
c.min_length = 10
end
```

Options that can be specified:

* :min_length => Number of minimum characters. default is 8.
* :require_lower => Require lower case if set true. default is true.
* :require_upper => Require upper case if set true. default is false.
* :require_number => Require number if set true. default is true.
current_user.set_password("secret") # => random password if not specified a argument.
current_user.passwd.plain # => new password
current_user.save

### Password object
new_user = User.new
password = new_user.passwd.plain
UserMailer.register(new_user, password).deliver!
```

Default password is randomly generated.
Default salt is "#{Time.now.to_s}".
`update_password` method will be set new password if the authentication successful.
But `update_password` method doesn't call `save` method.

```ruby
password = Passwd::Password.new
password.text # return text password.
password.salt_text # return text salt.
password.salt_hash # return hash salt.
password.hash # return hash password.
# update_password(OLD_PASSWORD, NEW_PASSWORD[, POLICY_CHECK=false])
current_user.update_password(old_pass, new_pass, true)
current_user.save
```

Options that can be specified:

* :password => Text password. default is random.
* :salt_text => Text salt. default is #{Time.now.to_s}.
#### Policy check

Password authenticate:
Default policy is 8 more characters and require lower case and require number.
Can be changed in configuration file.

```ruby
password = Passwd::Password.new
Passwd.auth(password.text, password.salt_hash, password.hash) # => true
Passwd.auth("invalid!!", password.salt_hash, password.hash) # => false

password == password.text # => true
password == "invalid!!" # => false
Passwd.policy_check("secret") # => true or false
```

## For ActiveRecord
### ActionController

### User model
Already several methods is available in your controller.

Include `Passwd::ActiveRecord` module and define id/salt/password column from `define_column` method.
`id` column is required uniqueness.
If you want to authenticate the application.
Unauthorized access is thrown exception.
Can be specified to redirect in configuration file.

```ruby
class User < ActiveRecord::Base
include Passwd::ActiveRecord
# if not specified arguments for define_column => {id: :email, salt: :salt, password: :password}
define_column id: :id_colname, salt: :salt_colname, password: :password_colname

...
class ApplicationController < ActionController::Base
before_action :require_signin
end
```

Available following method by defining id/salt/password column.

### Authentication

`authenticate` method is available in both instance and class.
Return the user object if the authentication successful.
Return the nil if authentication fails or doesn't exists user.
If you want to implement the session management.

```ruby
user = User.authenticate(params[:email], params[:password]) # => return user object or nil.

if user
session[:user] = user.id
redirect_to bar_path, notice: "Hello #{user.name}!"
else
flash.now[:alert] = "Authentication failed"
render action: :new
class SessionsController < ApplicationController
# If you has been enabled `require_signin` in ApplicationController
skip_before_action :require_signin

# GET /signin
def new; end

# POST /signin
def create
# Returns nil or user
@user = User.authenticate(params[:email], params[:password])

if @user
# Save user_id to session
signin!(@user)
redirect_to some_url, notice: "Signin was successful. Hello #{current_user.name}"
else # Authentication fails
render action: :new
end
end

# DELETE /signout
def destroy
# Clear session (Only user_id)
signout!
redirect_to some_url
end
end
```

instance method is not required `id`.
`current_user` method available if already signin.

```ruby
current_user = User.find(session[:user])

if current_user.authenticate(params[:password]) # => return true or false
# some process
redirect_to bar_path, notice: "Some process is successfully"
else
flash.now[:alert] = "Authentication failed"
render action: :edit
# app/controllers/greet_controller.rb
def greet
render text: "Hello #{current_user.name}!!"
end
```

### Change passowrd
# app/views/greet/greet.html.erb
<p>Hello <%= current_user.name %>!!<p>
```

`set_password` method will be set random password.
Return value is plain text password.
To specify the password as an argument if you want to specify a password.
`salt` also set if salt is nil.
### Generate configuration file

```ruby
current_user = User.find(session[:user])
password_text = current_user.set_password
Run generator of Rails.
Configuration file created to `config/initializers/passwd.rb`.

if current_user.save
redirect_to bar_path, notice: "Password update successfully"
else
render action: :edit
end
```

`update_password` method will be set new password if the authentication successful.
But `update_password` method doesn't call `save` method.

```ruby
current_user = User.find(session[:user])

begin
Passwd.confirm_check(params[:password], params[:password_confirmation])
# update_password(OLD_PASSWORD, NEW_PASSWORD[, POLICY_CHECK=false])
current_user.update_password(old_pass, new_pass, true)
current_user.save!
redirect_to bar_path, notice: "Password updated successfully"
rescue Passwd::PasswordNotMatch
# PASSWORD != PASSWORD_CONFIRMATION from Passwd.#confirm_check
flash.now[:alert] = "Password not match"
render action: :edit
rescue Passwd::AuthError
# Authentication failed from #update_password
flash.now[:alert] = "Password is incorrect"
render action: :edit
rescue Passwd::PolicyNotMatch
# Policy not match from #update_password
flash.now[:alert] = "Policy not match"
render action: :edit
rescue
# Other errors
flash.now[:alert] = "Password update failed"
render action: :edit
end
$ bundle exec rails generate passwd:config
```

## Contributing

1. Fork it
1. Fork it ( https://github.com/i2bskn/passwd/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Added some feature'`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request
5. Create a new Pull Request

1 change: 1 addition & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ RSpec::Core::RakeTask.new(:spec) do |t|
end

task :default => :spec

0 comments on commit ec1f09f

Please sign in to comment.