edge-auth 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +27 -0
- data/app/assets/javascripts/edge_auth/application.js +15 -0
- data/app/assets/stylesheets/edge_auth/application.css +13 -0
- data/app/controllers/edge_auth/application_controller.rb +4 -0
- data/app/helpers/edge_auth/application_helper.rb +4 -0
- data/app/models/edge_auth/identity.rb +126 -0
- data/app/views/edge_auth/_form.html.erb +16 -0
- data/app/views/layouts/edge_auth/application.html.erb +14 -0
- data/config/routes.rb +2 -0
- data/lib/edge-auth/engine.rb +17 -0
- data/lib/edge-auth/version.rb +3 -0
- data/lib/edge-auth.rb +31 -0
- data/lib/tasks/edge-auth_tasks.rake +4 -0
- metadata +71 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'EdgeAuth'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
Bundler::GemHelper.install_tasks
|
27
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// the compiled file.
|
9
|
+
//
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'mongoid/edge-state-machine'
|
2
|
+
|
3
|
+
module EdgeAuth
|
4
|
+
class Identity
|
5
|
+
include Mongoid::Document
|
6
|
+
include Mongoid::Timestamps
|
7
|
+
include Mongoid::EdgeStateMachine
|
8
|
+
|
9
|
+
|
10
|
+
field :email , :type => String
|
11
|
+
field :encrypted_password , :type => String
|
12
|
+
field :salt , :type => String
|
13
|
+
field :state , :type => String
|
14
|
+
field :activation_code , :type => String
|
15
|
+
field :activated_at , :type => DateTime
|
16
|
+
field :password_reset_code , :type => String
|
17
|
+
field :reset_password_mail_sent_at , :type => DateTime
|
18
|
+
|
19
|
+
|
20
|
+
index :email, unique: true
|
21
|
+
|
22
|
+
attr_accessor :password, :updating_password
|
23
|
+
attr_accessible :email, :password, :password_confirmation, :activation_code
|
24
|
+
|
25
|
+
validates_presence_of :email, on: :create
|
26
|
+
validates_length_of :email, maximum: 255, on: :create
|
27
|
+
validates_uniqueness_of :email, case_sensitive: false, on: :create
|
28
|
+
validates_format_of :email, with: /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i, on: :create
|
29
|
+
|
30
|
+
validates_presence_of :password, :if => :should_validate_password?
|
31
|
+
validates_confirmation_of :password, :if => :should_validate_password?
|
32
|
+
validates_length_of :password, minimum: 6, maximum: 40, :if => :should_validate_password?
|
33
|
+
|
34
|
+
before_save :encrypt_password
|
35
|
+
before_create :make_activation_code
|
36
|
+
|
37
|
+
state_machine do
|
38
|
+
state :pending
|
39
|
+
state :active
|
40
|
+
state :blocked # the user in this state can't sign in
|
41
|
+
|
42
|
+
event :activate do
|
43
|
+
transition :from => [:pending], :to => :active, :on_transition => :do_activate
|
44
|
+
end
|
45
|
+
|
46
|
+
event :block do
|
47
|
+
transition :from => [:pending, :active], :to => :blocked
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Return true if the user's password matches the submitted password.
|
52
|
+
def has_password?(submitted_password)
|
53
|
+
encrypted_password == encrypt(submitted_password)
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.authenticate(email, submitted_password)
|
57
|
+
user = Identity.first(conditions: {email: email})
|
58
|
+
return nil if user.nil? or user.state == "blocked"
|
59
|
+
return user if user.has_password?(submitted_password)
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.authenticate_with_salt(id, cookie_salt)
|
63
|
+
return nil if id.nil?
|
64
|
+
user = Identity.first(conditions: {_id: id})
|
65
|
+
(user && user.salt == cookie_salt) ? user : nil
|
66
|
+
end
|
67
|
+
|
68
|
+
def activated?
|
69
|
+
if self.activated_at == nil
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
return true
|
73
|
+
end
|
74
|
+
|
75
|
+
def reset_password_expired?
|
76
|
+
return self.reset_password_mail_sent_at < 1.day.ago
|
77
|
+
end
|
78
|
+
|
79
|
+
def reset_password
|
80
|
+
self.password_reset_code = generate_token
|
81
|
+
self.reset_password_mail_sent_at = Time.now.utc
|
82
|
+
self.save!(validate: false)
|
83
|
+
# we send the reset password mail
|
84
|
+
#UserMailer.reset_password(self).deliver
|
85
|
+
end
|
86
|
+
|
87
|
+
def do_activate
|
88
|
+
self.activated_at = Time.now.utc
|
89
|
+
self.save!
|
90
|
+
end
|
91
|
+
private
|
92
|
+
|
93
|
+
def encrypt_password
|
94
|
+
self.salt = make_salt if new_record?
|
95
|
+
self.encrypted_password = encrypt(password) if should_validate_password?
|
96
|
+
end
|
97
|
+
|
98
|
+
def encrypt(s)
|
99
|
+
secure_hash("#{salt}--#{s}")
|
100
|
+
end
|
101
|
+
|
102
|
+
def make_salt
|
103
|
+
begin
|
104
|
+
salt = secure_hash("#{Time.now.utc}--#{password}--#{SecureRandom.urlsafe_base64}")
|
105
|
+
user = Identity.where(salt: salt)
|
106
|
+
end while Identity.exists?(conditions: { salt: salt })
|
107
|
+
return salt
|
108
|
+
end
|
109
|
+
|
110
|
+
def secure_hash(string)
|
111
|
+
Digest::SHA2.hexdigest(string)
|
112
|
+
end
|
113
|
+
|
114
|
+
def make_activation_code
|
115
|
+
self.activation_code = generate_token
|
116
|
+
end
|
117
|
+
|
118
|
+
def should_validate_password?
|
119
|
+
updating_password || new_record?
|
120
|
+
end
|
121
|
+
|
122
|
+
def generate_token
|
123
|
+
Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<%= simple_form_for @auth_form_model, @auth_form_options do |f| %>
|
2
|
+
<% if @auth_form_model.respond_to? :username %>
|
3
|
+
<%= f.input :username, :autofocus => :true, :placeholder => 'Username' %>
|
4
|
+
<% end %>
|
5
|
+
<%= f.input :email, :placeholder => "email@domain.com" %>
|
6
|
+
<%= f.input :password, :label => 'Password', :required => true %>
|
7
|
+
<%= f.input :password_confirmation, :required => true %>
|
8
|
+
<% if EdgeCaptcha::Engine.config.recaptcha[:enable] %>
|
9
|
+
<%= render 'edge_captcha/recaptcha' %>
|
10
|
+
<% unless @auth_form_model.errors[:recaptcha].empty? %>
|
11
|
+
<small class="error recaptcha"><%= display_all_error_messages @auth_form_model, :recaptcha %></small>
|
12
|
+
<% end %>
|
13
|
+
<% end %>
|
14
|
+
<hr />
|
15
|
+
<%= f.submit "Create new account", :class => "nice large radius blue button" %>
|
16
|
+
<% end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>EdgeAuth</title>
|
5
|
+
<%= stylesheet_link_tag "edge-auth/application", :media => "all" %>
|
6
|
+
<%= javascript_include_tag "edge-auth/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
module EdgeAuth
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace EdgeAuth
|
4
|
+
config.generators do |g|
|
5
|
+
g.test_framework :rspec, :view_specs => false
|
6
|
+
g.fixture_replacement :factory_girl
|
7
|
+
g.orm :mongoid
|
8
|
+
end
|
9
|
+
|
10
|
+
config.recaptcha = {}
|
11
|
+
config.recaptcha[:enable] = true
|
12
|
+
config.recaptcha[:private_key] = '6Len6sISAAAAAOnvKTBhB-qav8UHClxqP2RAuIHE'
|
13
|
+
config.recaptcha[:public_key] = '6Len6sISAAAAAFjJaGLIU7IxEEheifrB8HY2AQj7'
|
14
|
+
config.recaptcha[:api_server_url] = "http://www.google.com/recaptcha/api/verify"
|
15
|
+
config.recaptcha[:ssl_api_service_url] = "https://www.google.com/recaptcha/api/verify"
|
16
|
+
end
|
17
|
+
end
|
data/lib/edge-auth.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require "edge-auth/engine"
|
2
|
+
|
3
|
+
module EdgeAuth
|
4
|
+
|
5
|
+
#try and verify the captcha response. Then give out a message to flash
|
6
|
+
def self.verify_recaptcha(remote_ip, params)
|
7
|
+
|
8
|
+
unless EdgeCaptcha::Engine.config.recaptcha[:enable]
|
9
|
+
return true
|
10
|
+
end
|
11
|
+
|
12
|
+
responce = Net::HTTP.post_form(URI.parse(EdgeCaptcha::Engine.config.recaptcha[:api_server_url]),
|
13
|
+
{ :privatekey => EdgeCaptcha::Engine.config.recaptcha[:private_key],
|
14
|
+
:remoteip => remote_ip,
|
15
|
+
:challenge => params[:recaptcha_challenge_field],
|
16
|
+
:response => params[:recaptcha_response_field] })
|
17
|
+
|
18
|
+
result = { :status => responce.body.split("\n")[0],
|
19
|
+
:error_code => responce.body.split("\n")[1] }
|
20
|
+
|
21
|
+
if result[:error_code] == "incorrect-captcha-sol"
|
22
|
+
return false
|
23
|
+
elsif result[:error_code] == 'success'
|
24
|
+
return true
|
25
|
+
else
|
26
|
+
flash[:alert] = "There has been a unexpected error with the application. Please contact the administrator. error code: #{result[:error_code]}"
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
return true
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: edge-auth
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dan Persa
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-24 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: &23338900 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.2.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *23338900
|
25
|
+
description: EdgeAuth is an authentication solution
|
26
|
+
email:
|
27
|
+
- dan.persa@gmail.com
|
28
|
+
executables: []
|
29
|
+
extensions: []
|
30
|
+
extra_rdoc_files: []
|
31
|
+
files:
|
32
|
+
- app/models/edge_auth/identity.rb
|
33
|
+
- app/helpers/edge_auth/application_helper.rb
|
34
|
+
- app/controllers/edge_auth/application_controller.rb
|
35
|
+
- app/views/layouts/edge_auth/application.html.erb
|
36
|
+
- app/views/edge_auth/_form.html.erb
|
37
|
+
- app/assets/stylesheets/edge_auth/application.css
|
38
|
+
- app/assets/javascripts/edge_auth/application.js
|
39
|
+
- config/routes.rb
|
40
|
+
- lib/tasks/edge-auth_tasks.rake
|
41
|
+
- lib/edge-auth.rb
|
42
|
+
- lib/edge-auth/engine.rb
|
43
|
+
- lib/edge-auth/version.rb
|
44
|
+
- MIT-LICENSE
|
45
|
+
- Rakefile
|
46
|
+
- README.rdoc
|
47
|
+
homepage: https://github.com/danpersa/edge-auth
|
48
|
+
licenses: []
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
requirements: []
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.8.15
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: EdgeAuth is an authentication solution
|
71
|
+
test_files: []
|