lam_auth 0.1.0
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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.rdoc +42 -0
- data/Rakefile +2 -0
- data/lam_auth.gemspec +19 -0
- data/lib/generators/active_record/lam_auth_generator.rb +23 -0
- data/lib/generators/active_record/templates/migration.rb +20 -0
- data/lib/generators/lam_auth/helpers.rb +19 -0
- data/lib/generators/lam_auth/lam_auth_generator.rb +28 -0
- data/lib/generators/templates/README +9 -0
- data/lib/generators/templates/lam_auth.yml +13 -0
- data/lib/generators/templates/xd_receiver.html +15 -0
- data/lib/lam_auth/controller_extensions.rb +45 -0
- data/lib/lam_auth/helpers.rb +18 -0
- data/lib/lam_auth/model.rb +51 -0
- data/lib/lam_auth/version.rb +3 -0
- data/lib/lam_auth.rb +48 -0
- metadata +89 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
Аутентификация для спецпроектов Lookatme
|
2
|
+
|
3
|
+
== Установка
|
4
|
+
|
5
|
+
gem install lam_auth
|
6
|
+
|
7
|
+
После установки/добавления в Gemfile:
|
8
|
+
|
9
|
+
rails generate lam_auth User
|
10
|
+
|
11
|
+
после этого нужно добавить настройки приложения для соответствующих environment в config/lam_auth.yml.
|
12
|
+
|
13
|
+
== Обработчик LoginRequiredException
|
14
|
+
|
15
|
+
Для actions, где требуется залогиненный пользователь:
|
16
|
+
|
17
|
+
before_filter :login_required
|
18
|
+
|
19
|
+
можно сделать обработчик для LoginRequiredException:
|
20
|
+
|
21
|
+
rescue_from LamAuth::LoginRequiredException, :with => :render_login_required
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def render_login_required
|
26
|
+
render :file => 'shared/login_required', :layout => 'application', :status => 401
|
27
|
+
end
|
28
|
+
|
29
|
+
== Подключение панели
|
30
|
+
|
31
|
+
Подключить js-код в head:
|
32
|
+
|
33
|
+
<%= lam_auth_include_tag %>
|
34
|
+
|
35
|
+
Затем:
|
36
|
+
|
37
|
+
<div id="lam-root"></div>
|
38
|
+
<%= lam_auth_init_tag %>
|
39
|
+
|
40
|
+
== Подробно о механизме аутентификации
|
41
|
+
|
42
|
+
http://mindscan.msk.ru/downloads/lam_auth.pdf
|
data/Rakefile
ADDED
data/lam_auth.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "lam_auth/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "lam_auth"
|
7
|
+
s.version = LamAuth::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Max Macovsky", "Anton Platonov"]
|
10
|
+
s.email = ["robotector@gmail.com", "platosha@lookatme.ru"]
|
11
|
+
s.homepage = "http://github.com/macovsky/lam_auth"
|
12
|
+
s.summary = %q{Аутентификация для спецпроектов Lookatme}
|
13
|
+
s.description = %q{}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
require 'generators/lam_auth/helpers'
|
3
|
+
|
4
|
+
module ActiveRecord
|
5
|
+
module Generators
|
6
|
+
class LamAuthGenerator < ActiveRecord::Generators::Base
|
7
|
+
include LamAuth::Generators::Helpers
|
8
|
+
source_root File.expand_path("../templates", __FILE__)
|
9
|
+
|
10
|
+
def generate_model
|
11
|
+
invoke "active_record:model", [name], :migration => false unless model_exists? && behavior == :invoke
|
12
|
+
end
|
13
|
+
|
14
|
+
def copy_lam_auth_migration
|
15
|
+
migration_template "migration.rb", "db/migrate/create_#{table_name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def inject_lam_auth_content
|
19
|
+
inject_into_class(model_path, class_name, model_contents) if model_exists?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Create<%= table_name.camelize %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table(:<%= table_name %>) do |t|
|
4
|
+
t.string :login, :null => false
|
5
|
+
t.string :email, :null => false
|
6
|
+
t.string :first_name
|
7
|
+
t.string :last_name
|
8
|
+
t.string :userpic
|
9
|
+
t.text :profile
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index :<%= table_name %>, :login
|
14
|
+
add_index :<%= table_name %>, :email
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.down
|
18
|
+
drop_table :<%= table_name %>
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module LamAuth
|
2
|
+
module Generators
|
3
|
+
module Helpers
|
4
|
+
def model_exists?
|
5
|
+
File.exists?(File.join(destination_root, model_path))
|
6
|
+
end
|
7
|
+
|
8
|
+
def model_path
|
9
|
+
@model_path ||= File.join("app", "models", "#{file_path}.rb")
|
10
|
+
end
|
11
|
+
|
12
|
+
def model_contents
|
13
|
+
<<-CONTENT
|
14
|
+
include LamAuth::Model
|
15
|
+
CONTENT
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module LamAuth
|
2
|
+
module Generators
|
3
|
+
class LamAuthGenerator < Rails::Generators::NamedBase
|
4
|
+
namespace "lam_auth"
|
5
|
+
source_root File.expand_path("../../templates", __FILE__)
|
6
|
+
|
7
|
+
desc "Installs lam_auth: generates a model plus includes required extensions."
|
8
|
+
|
9
|
+
hook_for :orm
|
10
|
+
|
11
|
+
def inject_controller_content
|
12
|
+
inject_into_class(File.join("app", "controllers", "application_controller.rb"), 'ApplicationController', " lam_auth_for :#{file_path}\n")
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy_xd_receiver
|
16
|
+
copy_file 'xd_receiver.html', 'public/xd_receiver.html'
|
17
|
+
end
|
18
|
+
|
19
|
+
def copy_yml
|
20
|
+
copy_file 'lam_auth.yml', 'config/lam_auth.yml'
|
21
|
+
end
|
22
|
+
|
23
|
+
def show_readme
|
24
|
+
readme "README" if behavior == :invoke
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
|
2
|
+
888 888 888
|
3
|
+
888 http://github.com/macovsky/lam_auth 888 888
|
4
|
+
888 888 888
|
5
|
+
888 8888b. 88888b.d88b. 8888b. 888 888 888888 88888b.
|
6
|
+
888 "88b 888 "888 "88b "88b 888 888 888 888 "88b
|
7
|
+
888 .d888888 888 888 888 .d888888 888 888 888 888 888
|
8
|
+
888 888 888 888 888 888 888 888 Y88b 888 Y88b. 888 888
|
9
|
+
888 "Y888888 888 888 888 88888888 "Y888888 "Y88888 "Y888 888 888
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<!DOCTYPE HTML>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8">
|
5
|
+
<title></title>
|
6
|
+
<script type="text/javascript">
|
7
|
+
window.opener.LAM.successLogin(window.location.hash.substring(1));
|
8
|
+
</script>
|
9
|
+
</head>
|
10
|
+
<body><p>Loading...</p>
|
11
|
+
</body>
|
12
|
+
</html>
|
13
|
+
|
14
|
+
|
15
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module LamAuth
|
2
|
+
module ControllerExtensions
|
3
|
+
def lam_auth_for(klass)
|
4
|
+
class_inheritable_accessor :model_class
|
5
|
+
self.model_class = klass.to_s.classify.constantize
|
6
|
+
helper_method(:current_user, :logged_in?)
|
7
|
+
before_filter :login_from_cookie
|
8
|
+
|
9
|
+
include InstanceMethods
|
10
|
+
protected :logged_in?, :current_user, :current_user=, :auth_token, :login_from_cookie, :login_required
|
11
|
+
end
|
12
|
+
|
13
|
+
module InstanceMethods
|
14
|
+
def logged_in?
|
15
|
+
!!current_user
|
16
|
+
end
|
17
|
+
|
18
|
+
def current_user
|
19
|
+
@current_user ||= session[:user] && model_class.find_by_id(session[:user])
|
20
|
+
end
|
21
|
+
|
22
|
+
def current_user=(new_user)
|
23
|
+
session[:user] = new_user && new_user.id
|
24
|
+
@current_user = new_user
|
25
|
+
end
|
26
|
+
|
27
|
+
def auth_token
|
28
|
+
cookie = cookies[LamAuth.cookie_id]
|
29
|
+
@auth_token ||= LamAuth.valid_cookie?(cookie) && LamAuth.parse_cookie_to_hash(cookie)['access_token']
|
30
|
+
end
|
31
|
+
|
32
|
+
def login_from_cookie
|
33
|
+
if logged_in?
|
34
|
+
!auth_token && self.current_user = nil
|
35
|
+
else
|
36
|
+
auth_token && self.current_user = model_class.find_by_auth_token(auth_token)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def login_required
|
41
|
+
logged_in? || raise(LoginRequiredException)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module LamAuth
|
2
|
+
module Helpers
|
3
|
+
def lam_auth_include_tag
|
4
|
+
javascript_include_tag(LamAuth.url + "/api/js/LAM.Login.js")
|
5
|
+
end
|
6
|
+
|
7
|
+
def lam_auth_init_tag(options = {})
|
8
|
+
options.reverse_merge!(
|
9
|
+
:app_id => LamAuth.config['app_id'],
|
10
|
+
:panel_node_id => 'lam-root',
|
11
|
+
:fixed => false
|
12
|
+
)
|
13
|
+
options.reverse_merge!(:xd_receiver_url => LamAuth.config['return_url']) if LamAuth.config['return_url']
|
14
|
+
|
15
|
+
javascript_tag("LAM.init({#{options.map{|k, v| "#{k.to_s.camelize(:lower)}: #{v.inspect}"}.join(",\n")}});")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
module LamAuth
|
4
|
+
module Model
|
5
|
+
def self.included(base)
|
6
|
+
base.validates_presence_of :login, :email
|
7
|
+
base.validates_uniqueness_of :login, :email
|
8
|
+
base.serialize :profile
|
9
|
+
base.send(:extend, ClassMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def find_by_auth_token(auth_token)
|
14
|
+
Rails.logger.info("Trying to authorize a token #{auth_token.inspect} ")
|
15
|
+
|
16
|
+
lam_uri = LamAuth.uri
|
17
|
+
http = Net::HTTP.new(lam_uri.host, lam_uri.port)
|
18
|
+
response, body = http.get("#{lam_uri.path}/users/me", {'Authorization' => "Token token=\"#{auth_token}\""})
|
19
|
+
if response.code == "200"
|
20
|
+
data = ActiveSupport::JSON.decode(body)
|
21
|
+
Rails.logger.info("...success: #{data.inspect}")
|
22
|
+
create_or_update_by_auth_data(data)
|
23
|
+
end
|
24
|
+
rescue Net::ProtoRetriableError => detail
|
25
|
+
Rails.logger.info("...failed!")
|
26
|
+
Rails.logger.info(detail)
|
27
|
+
nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_or_update_by_auth_data(data)
|
31
|
+
user = find_or_initialize_by_login(data['login'])
|
32
|
+
user.update_attributes data.slice(*%w{email first_name last_name}).merge(
|
33
|
+
'userpic' => data['userpic']['icon'],
|
34
|
+
'profile' => data.except(*%w{login email first_name last_name userpic})
|
35
|
+
)
|
36
|
+
user
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def name
|
41
|
+
[first_name, last_name].select(&:present?).join(" ")
|
42
|
+
end
|
43
|
+
|
44
|
+
def userpic(version = :icon)
|
45
|
+
pic = read_attribute(:userpic)
|
46
|
+
return nil if pic.blank?
|
47
|
+
pic.sub(/user-userpic-\w+/, "user-userpic-#{version}")
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
data/lib/lam_auth.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rack/utils'
|
2
|
+
require 'digest/md5'
|
3
|
+
|
4
|
+
require 'lam_auth/controller_extensions'
|
5
|
+
require 'lam_auth/helpers'
|
6
|
+
require 'lam_auth/model'
|
7
|
+
ActionController::Base.extend(LamAuth::ControllerExtensions)
|
8
|
+
ActionController::Base.helper(LamAuth::Helpers)
|
9
|
+
|
10
|
+
module LamAuth
|
11
|
+
class LoginRequiredException < Exception
|
12
|
+
end
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def config
|
16
|
+
@config ||= YAML.load_file(Rails.root.join("config/lam_auth.yml"))[Rails.env]
|
17
|
+
end
|
18
|
+
|
19
|
+
def url
|
20
|
+
"http://www.lookatme.ru"
|
21
|
+
end
|
22
|
+
|
23
|
+
def signup_url
|
24
|
+
"#{url}/signup"
|
25
|
+
end
|
26
|
+
|
27
|
+
def uri
|
28
|
+
URI.parse(url)
|
29
|
+
end
|
30
|
+
|
31
|
+
def cookie_id
|
32
|
+
"lam_#{config['app_id']}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def valid_cookie?(data)
|
36
|
+
valid_hash?(parse_cookie_to_hash(data))
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_cookie_to_hash(data)
|
40
|
+
Rack::Utils.parse_query(Rack::Utils.unescape(data.to_s.gsub('"', '')))
|
41
|
+
end
|
42
|
+
|
43
|
+
def valid_hash?(hash)
|
44
|
+
Digest::MD5.hexdigest(hash.except('sig').sort.map{|v| v.join('=')}.join + LamAuth.config['secret']) == hash['sig']
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lam_auth
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Max Macovsky
|
14
|
+
- Anton Platonov
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2011-04-13 00:00:00 +04:00
|
20
|
+
default_executable:
|
21
|
+
dependencies: []
|
22
|
+
|
23
|
+
description: ""
|
24
|
+
email:
|
25
|
+
- robotector@gmail.com
|
26
|
+
- platosha@lookatme.ru
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- .gitignore
|
35
|
+
- Gemfile
|
36
|
+
- README.rdoc
|
37
|
+
- Rakefile
|
38
|
+
- lam_auth.gemspec
|
39
|
+
- lib/generators/active_record/lam_auth_generator.rb
|
40
|
+
- lib/generators/active_record/templates/migration.rb
|
41
|
+
- lib/generators/lam_auth/helpers.rb
|
42
|
+
- lib/generators/lam_auth/lam_auth_generator.rb
|
43
|
+
- lib/generators/templates/README
|
44
|
+
- lib/generators/templates/lam_auth.yml
|
45
|
+
- lib/generators/templates/xd_receiver.html
|
46
|
+
- lib/lam_auth.rb
|
47
|
+
- lib/lam_auth/controller_extensions.rb
|
48
|
+
- lib/lam_auth/helpers.rb
|
49
|
+
- lib/lam_auth/model.rb
|
50
|
+
- lib/lam_auth/version.rb
|
51
|
+
has_rdoc: true
|
52
|
+
homepage: http://github.com/macovsky/lam_auth
|
53
|
+
licenses: []
|
54
|
+
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
hash: 3
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
requirements: []
|
79
|
+
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 1.6.2
|
82
|
+
signing_key:
|
83
|
+
specification_version: 3
|
84
|
+
summary: !binary |
|
85
|
+
0JDRg9GC0LXQvdGC0LjRhNC40LrQsNGG0LjRjyDQtNC70Y8g0YHQv9C10YbQ
|
86
|
+
v9GA0L7QtdC60YLQvtCyIExvb2thdG1l
|
87
|
+
|
88
|
+
test_files: []
|
89
|
+
|