cassiopeia 0.0.1
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/README +8 -0
- data/Rakefile +31 -0
- data/lib/cassiopeia/action_controller_client_mixin.rb +86 -0
- data/lib/cassiopeia/action_controller_server_mixin.rb +142 -0
- data/lib/cassiopeia/active_record_server_mixin.rb +36 -0
- data/lib/cassiopeia/base.rb +20 -0
- data/lib/cassiopeia/client.rb +59 -0
- data/lib/cassiopeia/config.rb +27 -0
- data/lib/cassiopeia/server.rb +22 -0
- data/lib/cassiopeia/tickets_controller_config.rb +10 -0
- data/lib/cassiopeia/user.rb +13 -0
- data/lib/cassiopeia.rb +26 -0
- metadata +85 -0
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
|
6
|
+
desc 'Default: .'
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
PKG_FILES = FileList[ '[a-zA-Z]*', 'lib/**/*' ]
|
10
|
+
|
11
|
+
spec = Gem::Specification.new do |s|
|
12
|
+
s.name = "cassiopeia"
|
13
|
+
s.version = "0.0.1"
|
14
|
+
s.author = "smecsia"
|
15
|
+
s.email = "smecsia@gmail.com"
|
16
|
+
#s.homepage = ""
|
17
|
+
s.platform = Gem::Platform::RUBY
|
18
|
+
s.summary = "Rails plugin for custom CAS(Cassiopeia) server/client implementation"
|
19
|
+
s.add_dependency('uuidtools')
|
20
|
+
s.add_dependency('rails', '>=2.3.5')
|
21
|
+
s.files = PKG_FILES.to_a
|
22
|
+
s.require_path = "lib"
|
23
|
+
s.has_rdoc = false
|
24
|
+
s.extra_rdoc_files = ["README"]
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'Turn this plugin into a gem.'
|
28
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
29
|
+
pkg.gem_spec = spec
|
30
|
+
end
|
31
|
+
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Cassiopeia
|
2
|
+
module ActionControllerClientMixin
|
3
|
+
module ActionControllerMethods
|
4
|
+
::CAS_USER_KEY = Cassiopeia::CONFIG[:current_user_key]
|
5
|
+
::CAS_TICKET_ID_KEY = Cassiopeia::CONFIG[:ticket_id_key]
|
6
|
+
::CAS_TICKET_KEY = Cassiopeia::CONFIG[:ticket_key]
|
7
|
+
def cas_current_ticket
|
8
|
+
session[CAS_TICKET_KEY] || params[CAS_TICKET_KEY]
|
9
|
+
end
|
10
|
+
def cas_current_ticket_id
|
11
|
+
params[CAS_TICKET_ID_KEY] || session[CAS_TICKET_ID_KEY]
|
12
|
+
end
|
13
|
+
def cas_store_current_user(ticket, user)
|
14
|
+
session[CAS_TICKET_KEY] = ticket
|
15
|
+
session[CAS_USER_KEY] = current_user
|
16
|
+
end
|
17
|
+
def cas_erase_current_user
|
18
|
+
cas_store_current_user nil, nil
|
19
|
+
session[CAS_TICKET_ID_KEY] = nil
|
20
|
+
end
|
21
|
+
def cas_current_ticket_valid?
|
22
|
+
logger.debug "\n Ticket.expires_at= #{cas_current_ticket[:expires_at]} \n" + "="*50 if cas_current_ticket
|
23
|
+
logger.debug "\nCurrent ticket valid: #{DateTime.parse(cas_current_ticket[:expires_at])} >= #{DateTime.now}\n" + "="*50 if cas_current_ticket && cas_current_ticket[:expires_at]
|
24
|
+
cas_current_ticket && DateTime.parse(cas_current_ticket[:expires_at]) >= DateTime.now if cas_current_ticket && cas_current_ticket[:expires_at]
|
25
|
+
end
|
26
|
+
def cas_request_ticket_id
|
27
|
+
store_location if respond_to?('store_location')
|
28
|
+
redirect_to Cassiopeia::Client::instance.cas_check_url(session)
|
29
|
+
end
|
30
|
+
def cas_request_current_user
|
31
|
+
session[CAS_TICKET_ID_KEY] = cas_current_ticket_id
|
32
|
+
@ticket = Cassiopeia::Client::instance.cas_current_ticket(session)
|
33
|
+
@current_user = Cassiopeia::User.new(@ticket[:user])
|
34
|
+
logger.debug "\nCurrent user identified (#{@current_user.login}), storing to session\n" + "="*50
|
35
|
+
cas_store_current_user(@ticket, @current_user)
|
36
|
+
logger.debug "\nShould redirect user to #{session[:return_to]}\n" + "="*50
|
37
|
+
redirect_back_or_default root_path if respond_to?('redirect_back_or_default')
|
38
|
+
end
|
39
|
+
def cas_required_roles
|
40
|
+
self.class.cas_required_roles if self.class.respond_to? :cas_required_roles
|
41
|
+
end
|
42
|
+
def cas_check_required_roles
|
43
|
+
if cas_required_roles
|
44
|
+
logger.debug "\nCas check required roles #{cas_required_roles}...\n" + "="*50
|
45
|
+
cas_required_roles.each do |r|
|
46
|
+
raise Cassiopeia::AccessDeniedException.new "You don't have required roles for this controller" unless current_user.has_role? r
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
def cas_require_user
|
51
|
+
if !cas_current_ticket_id
|
52
|
+
logger.debug "\nNo cas_ticket_id, requesting from cassiopeia...\n" + "="*50
|
53
|
+
return cas_request_ticket_id
|
54
|
+
end
|
55
|
+
if cas_current_ticket && !cas_current_ticket_valid?
|
56
|
+
logger.debug "\nCurrent ticket is invalid, erasing current user\n" + "="*50
|
57
|
+
cas_erase_current_user
|
58
|
+
return cas_request_ticket_id
|
59
|
+
end
|
60
|
+
if cas_current_ticket_id && !cas_current_ticket
|
61
|
+
logger.debug "\nCas ticket_id is in request, retrieving current_ticket and user...\n\n" + "="*50
|
62
|
+
return cas_request_current_user
|
63
|
+
elsif cas_current_ticket
|
64
|
+
logger.debug "\nCurrent user session is valid (current user = #{current_user.login})\n" + "="*50
|
65
|
+
end
|
66
|
+
end
|
67
|
+
def current_user
|
68
|
+
return @current_user if @current_user
|
69
|
+
@current_user = session[CAS_USER_KEY]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
def cas_required_roles
|
73
|
+
@required_roles
|
74
|
+
end
|
75
|
+
def cas_require_roles(*roles)
|
76
|
+
@required_roles = [] unless defined? @required_roles
|
77
|
+
@required_roles |= roles
|
78
|
+
logger.debug "\nCAS add required role #{roles}, now roles_required: #{@required_roles}...\n" + "="*50
|
79
|
+
end
|
80
|
+
def use_cas_authorization
|
81
|
+
@current_user = nil
|
82
|
+
before_filter :cas_require_user, :cas_check_required_roles
|
83
|
+
include ActionControllerMethods
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module Cassiopeia
|
2
|
+
autoload :TicketsControllerConfig, 'cassiopeia/tickets_controller_config'
|
3
|
+
|
4
|
+
module ActionControllerServerMixin
|
5
|
+
module ActionControllerMethods
|
6
|
+
def ActionControllerMethods.rolesMethod=(m)
|
7
|
+
@@rolesMethod = m
|
8
|
+
end
|
9
|
+
def ActionControllerMethods.ticketClass=(c)
|
10
|
+
@@ticketClass = c
|
11
|
+
end
|
12
|
+
def cas_ticket_id
|
13
|
+
session[@ticket_id_key] || params[@ticket_id_key]
|
14
|
+
end
|
15
|
+
def cas_service_url
|
16
|
+
session[@service_url_key] || params[@service_url_key]
|
17
|
+
end
|
18
|
+
def cas_service_id
|
19
|
+
session[@service_id_key] || params[@service_id_key]
|
20
|
+
end
|
21
|
+
|
22
|
+
def cas_require_config
|
23
|
+
raise "ticketClass should be set to use this functionality" unless @@ticketClass
|
24
|
+
end
|
25
|
+
|
26
|
+
def cas_store_params
|
27
|
+
@ticket_id_key = Cassiopeia::CONFIG[:ticket_id_key]
|
28
|
+
@service_id_key = Cassiopeia::CONFIG[:service_id_key]
|
29
|
+
@service_url_key = Cassiopeia::CONFIG[:service_url_key]
|
30
|
+
session[@ticket_id_key] = cas_ticket_id
|
31
|
+
session[@service_id_key] = cas_service_id
|
32
|
+
session[@service_url_key] = cas_service_url
|
33
|
+
end
|
34
|
+
|
35
|
+
def cas_create_or_find_ticket
|
36
|
+
if current_user && !(cas_current_ticket_exists?)
|
37
|
+
@ticket = @@ticketClass.new(:user_id => current_user.id)
|
38
|
+
@ticket.user = current_user
|
39
|
+
@ticket.service = cas_service_id
|
40
|
+
if @ticket.save
|
41
|
+
session[@ticket_id_key] = @ticket.identity
|
42
|
+
session[@service_id_key] = @ticket.service
|
43
|
+
else
|
44
|
+
@ticket = nil
|
45
|
+
end
|
46
|
+
else
|
47
|
+
@ticket = @@ticketClass.find_by_identity(cas_ticket_id.to_s)
|
48
|
+
end
|
49
|
+
@ticket
|
50
|
+
end
|
51
|
+
|
52
|
+
def cas_current_ticket
|
53
|
+
@ticket = cas_create_or_find_ticket unless @ticket
|
54
|
+
logger.debug "\nCurrentTicket = #{@ticket.identity if @ticket}\n" + "="*50
|
55
|
+
@ticket
|
56
|
+
end
|
57
|
+
|
58
|
+
def cas_current_ticket_exists?
|
59
|
+
logger.debug "\nTicketExists = #{@@ticketClass.exists?(cas_ticket_id)}\n" + "="*50
|
60
|
+
@@ticketClass.exists?(cas_ticket_id)
|
61
|
+
end
|
62
|
+
|
63
|
+
def cas_current_ticket_valid?
|
64
|
+
logger.debug "\nTicketValid = #{cas_current_ticket.valid_for?(cas_service_id)}\n" + "="*50 if cas_current_ticket_exists?
|
65
|
+
cas_current_ticket.valid_for?(cas_service_id) if cas_current_ticket_exists?
|
66
|
+
end
|
67
|
+
|
68
|
+
def cas_respond_current_ticket
|
69
|
+
ticket_hash = cas_current_ticket.attributes
|
70
|
+
if cas_current_ticket.user
|
71
|
+
user_hash = cas_current_ticket.user.attributes
|
72
|
+
roles = []
|
73
|
+
roles = (cas_current_ticket.user.send @@rolesMethod) if cas_current_ticket.user.respond_to? @@rolesMethod
|
74
|
+
roles_hash = roles
|
75
|
+
user_hash[:roles] = roles_hash
|
76
|
+
else
|
77
|
+
user_hash = nil
|
78
|
+
end
|
79
|
+
ticket_hash = ticket_hash.merge({:user => user_hash}) if cas_current_ticket.user
|
80
|
+
logger.debug "\n Rendering ticket: \n"
|
81
|
+
logger.debug ticket_hash.to_json + "\n" + "="*50
|
82
|
+
simple_rest ticket_hash, {:status => :ok}
|
83
|
+
end
|
84
|
+
|
85
|
+
def cas_process_request
|
86
|
+
if current_user
|
87
|
+
cas_respond_current_ticket
|
88
|
+
elsif cas_current_ticket_exists?
|
89
|
+
cas_respond_current_ticket
|
90
|
+
else
|
91
|
+
@res = {:error => "Ticket not found"}
|
92
|
+
simple_rest @res, {:status => :error}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def cas_proceed_auth
|
97
|
+
if cas_current_ticket_valid? && current_user
|
98
|
+
logger.debug "\nCurrentTicketValid, current_user exists redirecting to service...\n" + "="*50
|
99
|
+
return redirect_to Cassiopeia::Server::instance.service_url(session)
|
100
|
+
elsif current_user
|
101
|
+
logger.debug "\nCurrentTicketInvalid, but current_user exists, should create new ticket...\n" + "="*50
|
102
|
+
cas_current_ticket.destroy
|
103
|
+
cas_create_or_find_ticket
|
104
|
+
return redirect_to Cassiopeia::Server::instance.service_url(session)
|
105
|
+
elsif cas_current_ticket_exists?
|
106
|
+
logger.debug "\nCurrentTicketInvalid, but current_user exists, destroying ticket, redirecting to login...\n" + "="*50
|
107
|
+
cas_current_ticket.destroy
|
108
|
+
end
|
109
|
+
redirect_to login_url
|
110
|
+
end
|
111
|
+
|
112
|
+
def create
|
113
|
+
cas_process_request
|
114
|
+
end
|
115
|
+
|
116
|
+
def show
|
117
|
+
cas_proceed_auth
|
118
|
+
end
|
119
|
+
|
120
|
+
def index
|
121
|
+
cas_proceed_auth
|
122
|
+
end
|
123
|
+
|
124
|
+
def detroy(params)
|
125
|
+
cas_current_ticket.destroy if cas_current_ticket_exists?
|
126
|
+
simple_rest nil, {:status => :ok}
|
127
|
+
end
|
128
|
+
end
|
129
|
+
def acts_as_cas_controller
|
130
|
+
defaultTicketClass = Ticket if defined? Ticket
|
131
|
+
controllerConfig = Cassiopeia::TicketsControllerConfig.new defaultTicketClass, :roles
|
132
|
+
yield controllerConfig
|
133
|
+
ActionControllerMethods.rolesMethod = controllerConfig.rolesMethod
|
134
|
+
ActionControllerMethods.ticketClass = controllerConfig.ticketClass
|
135
|
+
ActiveRecordServerMixin.ticketClass = controllerConfig.ticketClass
|
136
|
+
skip_before_filter :verify_authenticity_token, :only=> [:create, :index]
|
137
|
+
before_filter :require_user, :except => [:create, :index]
|
138
|
+
before_filter :cas_store_params, :cas_create_or_find_ticket, :cas_require_config
|
139
|
+
include ActionControllerMethods
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'uuidtools'
|
2
|
+
|
3
|
+
module Cassiopeia
|
4
|
+
module ActiveRecordServerMixin
|
5
|
+
def ActiveRecordServerMixin.ticketClass=(c)
|
6
|
+
@@ticketClass = c
|
7
|
+
end
|
8
|
+
# cas ticket
|
9
|
+
def acts_as_cas_ticket
|
10
|
+
class_eval do
|
11
|
+
def valid_for?(service)
|
12
|
+
return false unless identity && user
|
13
|
+
(ticket = self.for_service service) && ticket.expires_at >= DateTime.now
|
14
|
+
end
|
15
|
+
def for_service(service)
|
16
|
+
@@ticketClass.find(:first, :conditions => {:service => service, :user_id => user.id })
|
17
|
+
end
|
18
|
+
end
|
19
|
+
instance_eval do
|
20
|
+
def generate_expiration
|
21
|
+
DateTime.now() + Cassiopeia::CONFIG[:ticket_max_lifetime] / 24.0 / 60.0
|
22
|
+
end
|
23
|
+
def generate_uuid
|
24
|
+
UUIDTools::UUID.timestamp_create.to_s
|
25
|
+
end
|
26
|
+
def exists?(ticket_id)
|
27
|
+
self.find_by_identity(ticket_id.to_s) != nil
|
28
|
+
end
|
29
|
+
before_create do |obj|
|
30
|
+
obj.identity = generate_uuid
|
31
|
+
obj.expires_at = generate_expiration
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Cassiopeia
|
2
|
+
class Base
|
3
|
+
protected
|
4
|
+
def query_to_hash(query)
|
5
|
+
CGI.parse(query)
|
6
|
+
end
|
7
|
+
|
8
|
+
def hash_to_query(hash)
|
9
|
+
pairs = []
|
10
|
+
hash.each do |k, vals|
|
11
|
+
vals = [vals] unless vals.kind_of? Array
|
12
|
+
vals.each {|v| pairs << "#{CGI.escape(k.to_s)}=#{(v)?CGI.escape(v.to_s):''}"}
|
13
|
+
end
|
14
|
+
pairs.join("&")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class AccessDeniedException < Exception
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'cgi'
|
3
|
+
require 'net/https'
|
4
|
+
require 'rexml/document'
|
5
|
+
|
6
|
+
##################
|
7
|
+
# Client
|
8
|
+
##################
|
9
|
+
module Cassiopeia
|
10
|
+
class Client < Base
|
11
|
+
private
|
12
|
+
@instance = nil
|
13
|
+
def server_url
|
14
|
+
Cassiopeia::CONFIG[:server_url] + "/" + Cassiopeia::CONFIG[:server_controller] + "." + Cassiopeia::CONFIG[:format]
|
15
|
+
end
|
16
|
+
|
17
|
+
def cas_data(session)
|
18
|
+
{
|
19
|
+
Cassiopeia::CONFIG[:service_url_key] => Cassiopeia::CONFIG[:service_url],
|
20
|
+
Cassiopeia::CONFIG[:service_id_key] => Cassiopeia::CONFIG[:service_id],
|
21
|
+
Cassiopeia::CONFIG[:ticket_id_key] => session[Cassiopeia::CONFIG[:ticket_id_key]]
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
# Submits some data to the given URI and returns a Net::HTTPResponse.
|
26
|
+
def do_post(uri, data)
|
27
|
+
uri = URI.parse(uri) unless uri.kind_of? URI
|
28
|
+
req = Net::HTTP::Post.new(uri.path)
|
29
|
+
req.set_form_data(data, ';')
|
30
|
+
https = Net::HTTP.new(uri.host, uri.port)
|
31
|
+
https.use_ssl = (uri.scheme == 'https')
|
32
|
+
res = https.start {|conn| conn.request(req) }
|
33
|
+
end
|
34
|
+
|
35
|
+
public
|
36
|
+
def self.instance
|
37
|
+
return @instance if @instance
|
38
|
+
@instance = Cassiopeia::Client.new
|
39
|
+
end
|
40
|
+
|
41
|
+
def cas_current_ticket(session)
|
42
|
+
res = do_post(server_url, cas_data(session))
|
43
|
+
case res
|
44
|
+
when Net::HTTPSuccess
|
45
|
+
begin
|
46
|
+
return ActiveSupport::JSON.decode(res.body).symbolize_keys if Cassiopeia::CONFIG[:format] == "js"
|
47
|
+
rescue
|
48
|
+
end
|
49
|
+
end
|
50
|
+
return {}
|
51
|
+
end
|
52
|
+
|
53
|
+
def cas_check_url(session)
|
54
|
+
server_url + "?" + hash_to_query(cas_data(session))
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Cassiopeia
|
4
|
+
private
|
5
|
+
DEFAULT_CONFIG = {
|
6
|
+
:ticket_max_lifetime => 120,
|
7
|
+
:server_controller => "cas",
|
8
|
+
:session_id_key => "cassiopeia_sesion_id",
|
9
|
+
:ticket_id_key => "ticket_id",
|
10
|
+
:service_id_key => "service_id",
|
11
|
+
:service_url_key => "service_url",
|
12
|
+
:server_url => "https://localhost/cassiopeia",
|
13
|
+
:service_url => "https://localhost/test_rails",
|
14
|
+
:service_id => "test",
|
15
|
+
:current_user_key => "current_user"
|
16
|
+
}
|
17
|
+
CONFIG_PATH = "#{RAILS_ROOT}/config/cassiopeia.yml"
|
18
|
+
@@conf = {}
|
19
|
+
if !File.exist?(CONFIG_PATH)
|
20
|
+
raise "Cassiopeia config required! Please, create RAILS_ROOT/conf/cassiopeia.yml file with server/service url"
|
21
|
+
end
|
22
|
+
@@conf = YAML::load(ERB.new((IO.read(CONFIG_PATH))).result).symbolize_keys if File.exist?(CONFIG_PATH)
|
23
|
+
@@ticketClass = Class.class
|
24
|
+
@@controllerClass = Class.class
|
25
|
+
public
|
26
|
+
CONFIG = DEFAULT_CONFIG.merge(@@conf)
|
27
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Cassiopeia
|
2
|
+
class Server < Base
|
3
|
+
private
|
4
|
+
@instance = nil
|
5
|
+
def cas_data(session)
|
6
|
+
{
|
7
|
+
Cassiopeia::CONFIG[:ticket_id_key] => session[Cassiopeia::CONFIG[:ticket_id_key]]
|
8
|
+
}
|
9
|
+
end
|
10
|
+
public
|
11
|
+
def self.instance
|
12
|
+
return @instance if @instance
|
13
|
+
@instance = Cassiopeia::Server.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def service_url(session)
|
17
|
+
session[Cassiopeia::CONFIG[:service_url_key]] + "?" + hash_to_query(cas_data(session))
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/lib/cassiopeia.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
module Cassiopeia
|
4
|
+
VERSION = '0.0.1'
|
5
|
+
autoload :User, 'cassiopeia/user'
|
6
|
+
autoload :Base, 'cassiopeia/base'
|
7
|
+
autoload :AccessDeniedException, 'cassiopeia/base'
|
8
|
+
autoload :Server, 'cassiopeia/server'
|
9
|
+
autoload :Client, 'cassiopeia/client'
|
10
|
+
autoload :CONFIG, 'cassiopeia/config'
|
11
|
+
autoload :ActiveRecordServerMixin, 'cassiopeia/active_record_server_mixin'
|
12
|
+
autoload :ActionControllerServerMixin, 'cassiopeia/action_controller_server_mixin'
|
13
|
+
autoload :ActionControllerClientMixin, 'cassiopeia/action_controller_client_mixin'
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def enable
|
17
|
+
ActionController::Base.send :extend, ActionControllerServerMixin
|
18
|
+
ActiveRecord::Base.send :extend, ActiveRecordServerMixin
|
19
|
+
ActionController::Base.send :extend, ActionControllerClientMixin
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
if defined? Rails && defined? RAILS_ROOT
|
25
|
+
Cassiopeia.enable
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cassiopeia
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- smecsia
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-03-03 00:00:00 +03:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: uuidtools
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rails
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.3.5
|
34
|
+
version:
|
35
|
+
description:
|
36
|
+
email: smecsia@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- README
|
43
|
+
files:
|
44
|
+
- README
|
45
|
+
- Rakefile
|
46
|
+
- lib/cassiopeia.rb
|
47
|
+
- lib/cassiopeia/active_record_server_mixin.rb
|
48
|
+
- lib/cassiopeia/action_controller_server_mixin.rb
|
49
|
+
- lib/cassiopeia/config.rb
|
50
|
+
- lib/cassiopeia/server.rb
|
51
|
+
- lib/cassiopeia/user.rb
|
52
|
+
- lib/cassiopeia/client.rb
|
53
|
+
- lib/cassiopeia/tickets_controller_config.rb
|
54
|
+
- lib/cassiopeia/action_controller_client_mixin.rb
|
55
|
+
- lib/cassiopeia/base.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage:
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.3.5
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: Rails plugin for custom CAS(Cassiopeia) server/client implementation
|
84
|
+
test_files: []
|
85
|
+
|