sessionvoc-open 1.7.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +26 -0
- data/LICENSE.txt +202 -0
- data/README.md +193 -0
- data/Rakefile +51 -0
- data/VERSION +1 -0
- data/config.yml.sample +5 -0
- data/examples/example.sql +31 -0
- data/examples/example.xml +110 -0
- data/init.rb +6 -0
- data/install.rb +4 -0
- data/lib/sessionvoc-open.rb +26 -0
- data/lib/sessionvoc-store/open/controller_methods.rb +10 -0
- data/lib/sessionvoc-store/open/railtie.rb +17 -0
- data/lib/sessionvoc-store/open/sessionvoc_store.rb +299 -0
- data/lib/sessionvoc/open/authentification.rb +137 -0
- data/lib/sessionvoc/open/base.rb +169 -0
- data/lib/sessionvoc/open/client.rb +54 -0
- data/lib/sessionvoc/open/configuration.rb +24 -0
- data/lib/sessionvoc/open/data_conversion.rb +100 -0
- data/lib/sessionvoc/open/exceptions.rb +59 -0
- data/lib/sessionvoc/open/form_data.rb +64 -0
- data/lib/sessionvoc/open/meta_data.rb +18 -0
- data/lib/sessionvoc/open/session.rb +63 -0
- data/sessionvoc-open.gemspec +103 -0
- data/test/config.yml +5 -0
- data/test/helper.rb +38 -0
- data/test/test_sessionvoc_authentification.rb +62 -0
- data/test/test_sessionvoc_base.rb +62 -0
- data/test/test_sessionvoc_data_conversion.rb +96 -0
- data/test/test_sessionvoc_form_data.rb +118 -0
- data/test/test_sessionvoc_meta_data.rb +17 -0
- data/test/test_sessionvoc_session.rb +73 -0
- data/uninstall.rb +4 -0
- metadata +228 -0
@@ -0,0 +1,137 @@
|
|
1
|
+
# Copyright:: 2011 triAGENS GmbH
|
2
|
+
# Author:: Oliver Kiessler (mailto:kiessler@inceedo.com)
|
3
|
+
module Sessionvoc
|
4
|
+
module Open
|
5
|
+
module Authentification
|
6
|
+
# Performs the simple authentification method against the SessionVOC server.
|
7
|
+
# Currently not available.
|
8
|
+
# === Parameters
|
9
|
+
# * sid = Session Id
|
10
|
+
# * uid = User
|
11
|
+
# * password = Plaintext Password
|
12
|
+
# * options
|
13
|
+
def simple(sid, uid, password, options = {})
|
14
|
+
logger.debug("Authentification#simple for sid: #{sid} for uid: #{uid}")
|
15
|
+
password = Digest::MD5.hexdigest(password) if meta_data["authenticationMethod"] > 0 and meta_data["clientHash"] == 1
|
16
|
+
response = get_response(:put, "/session/#{sid}/authenticate", {:body => {'uid' => uid, 'password' => password}.to_json})
|
17
|
+
if response_ok?(response)
|
18
|
+
response.parsed_response
|
19
|
+
else
|
20
|
+
if options[:no_exception]
|
21
|
+
false
|
22
|
+
else
|
23
|
+
handle_exception(response.parsed_response["errorCode"], response.parsed_response["message"])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Performs the challenge-response authentification method against the SessionVOC
|
29
|
+
# === Parameters
|
30
|
+
# * sid = Session Id
|
31
|
+
# * uid = User
|
32
|
+
# * password = User Password
|
33
|
+
# * options
|
34
|
+
def challenge(sid, uid, password, options = {})
|
35
|
+
logger.debug("Authentification#challenge for sid: #{sid} for uid: #{uid}")
|
36
|
+
response = get_response(:put, "/session/#{sid}/authenticate",
|
37
|
+
{:body => {'uid' => uid}.to_json})
|
38
|
+
if response_ok?(response) and response.parsed_response["loginData"]
|
39
|
+
return challenge_response(sid, uid, password, response.parsed_response["loginData"]['salt'],
|
40
|
+
response.parsed_response["loginData"]['hash'], options)
|
41
|
+
else
|
42
|
+
if options[:no_exception]
|
43
|
+
return nil
|
44
|
+
else
|
45
|
+
handle_exception(response.parsed_response["errorCode"], response.parsed_response["message"])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Performs a user logout.
|
51
|
+
# === Parameters
|
52
|
+
# * sid = Session Id
|
53
|
+
def logout(sid, options = {})
|
54
|
+
logger.debug("Authentification#logout for sid: #{sid}")
|
55
|
+
response = get_response(:put, "/session/#{sid}/authenticate", {:body => nil})
|
56
|
+
response_ok?(response) ? true : handle_exception(response.parsed_response["errorCode"], response.parsed_response["message"])
|
57
|
+
end
|
58
|
+
|
59
|
+
# Create a (one time) usable nonce.
|
60
|
+
# === Parameters
|
61
|
+
# * ts = Timestamp (only used for testing)
|
62
|
+
# * random_number = (only used for testing)
|
63
|
+
# * options
|
64
|
+
def create_nonce(ts = nil, random_number = nil, options = {})
|
65
|
+
timestamp = ts ? ts.to_s : Time.now.to_i.to_s
|
66
|
+
if options[:no_encode]
|
67
|
+
"#{timestamp[0..3]}#{random_number ? random_number[4..11] : gen_64bit_id[4..11]}"
|
68
|
+
else
|
69
|
+
Base64.encode64("#{timestamp[0..3]}#{random_number ? random_number[4..11] : gen_64bit_id[4..11]}")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Checks if the previously created nonce was already used.
|
74
|
+
# === Parameters
|
75
|
+
# * nonce = Nonce string
|
76
|
+
def get_nonce(nonce, options = {})
|
77
|
+
response = get_response(:post, "/nonce/#{nonce}", {}, true)
|
78
|
+
(response_ok?(response) and response.parsed_response["status"]) ? true : handle_exception(response.parsed_response["errorCode"], response.parsed_response["message"])
|
79
|
+
end
|
80
|
+
|
81
|
+
# Generates a 64bit random number as part of the nonce.
|
82
|
+
def gen_64bit_id
|
83
|
+
encode_id(rand(18446744073709551615))
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
# The second part of the challenge response authentification method.
|
88
|
+
# === Parameters
|
89
|
+
# * sid = Session Id
|
90
|
+
# * uid = User
|
91
|
+
# * password = User password
|
92
|
+
# * salt = Salt delivered by SessionVOC
|
93
|
+
# * hash = Hash delivered by SessionVOC
|
94
|
+
# * options
|
95
|
+
def challenge_response(sid, uid, password, salt, hash, options = {})
|
96
|
+
logger.debug("Authentification#challenge_response for sid: #{sid} for uid: #{uid}")
|
97
|
+
response = get_response(:put, "/session/#{sid}/authenticate",
|
98
|
+
{:body => {'uid' => uid, 'password' => encrypt_password(password, salt, hash)}.to_json})
|
99
|
+
if response_ok?(response)
|
100
|
+
response.parsed_response
|
101
|
+
else
|
102
|
+
if options[:no_exception]
|
103
|
+
false
|
104
|
+
else
|
105
|
+
handle_exception(response.parsed_response["errorCode"], response.parsed_response["message"])
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Creates an encrypted and hashed password as required by the SessionVOC server.
|
111
|
+
# === Parameters
|
112
|
+
# * password = Password
|
113
|
+
# * salt = Salt delivered by SessionVOC
|
114
|
+
# * hash = Hash delivered by SessionVOC
|
115
|
+
def encrypt_password(password, salt, hash)
|
116
|
+
if hash.to_i == Sessionvoc::Open::Base::HASH_TYPES[:HASH_NONE]
|
117
|
+
return password
|
118
|
+
elsif hash.to_i == Sessionvoc::Open::Base::HASH_TYPES[:HASH_SHA1]
|
119
|
+
return Digest::MD5.hexdigest(Digest::MD5.hexdigest(Digest::SHA1.hexdigest(password)) + salt)
|
120
|
+
elsif hash.to_i == Sessionvoc::Open::Base::HASH_TYPES[:HASH_SHA224]
|
121
|
+
raise Sessionvoc::Open::NotSupportedException, "SHA224 is not supported"
|
122
|
+
elsif hash.to_i == Sessionvoc::Open::Base::HASH_TYPES[:HASH_SHA256]
|
123
|
+
raise Sessionvoc::Open::NotSupportedException, "SHA256 is not supported"
|
124
|
+
elsif hash.to_i == Sessionvoc::Open::Base::HASH_TYPES[:HASH_MD5]
|
125
|
+
return Digest::MD5.hexdigest(Digest::MD5.hexdigest(password) + salt)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Encodes the 64bit random number.
|
130
|
+
# === Parameters
|
131
|
+
# * n = Random number
|
132
|
+
def encode_id(n)
|
133
|
+
n.to_s(36).rjust(13, '0')
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
# Copyright:: 2011 triAGENS GmbH
|
2
|
+
# Author:: Oliver Kiessler (mailto:kiessler@inceedo.com)
|
3
|
+
module Sessionvoc
|
4
|
+
module Open
|
5
|
+
# This Ruby library provides a Ruby on Rails session store for the SessionVOC. It can also be used outside of Rails to interact with SessionVOC
|
6
|
+
# directly or within Sinatra and other webapplication frameworks in Ruby.
|
7
|
+
#
|
8
|
+
# The SessionVOC is a noSQL database optimized for the management of user sessions. Additionally the SessionVOC establishes security mechanisms
|
9
|
+
# that are difficult to implement with other session management systems. It depends on the actual scenario which of these functions
|
10
|
+
# has the highest priority.
|
11
|
+
class Base
|
12
|
+
VERSION = '1.7.3'
|
13
|
+
attr_accessor :configuration, :logger
|
14
|
+
|
15
|
+
# SessionVOC Error Codes used by the server.
|
16
|
+
ERROR_CODES = {
|
17
|
+
1 => "Errorcode 1: Internal Server Error",
|
18
|
+
2 => "Errorcode 2: Illegal request",
|
19
|
+
3 => "Errorcode 3: Unknown session identifier",
|
20
|
+
4 => "Errorcode 4: Authentification failed",
|
21
|
+
5 => "Errorcode 5: Unknown form data",
|
22
|
+
6 => "Errorcode 6: Temporary error",
|
23
|
+
7 => "Errorcode 7: Illegal authentification request",
|
24
|
+
8 => "Errorcode 8: Illegal user identifier",
|
25
|
+
9 => "Errorcode 9: Session remove (delete) failure",
|
26
|
+
10 => "Errorcode 10: Get request failure, can not output",
|
27
|
+
11 => "Errorcode 11: Parser error, illegal Json",
|
28
|
+
12 => "Errorcode 12: Error while attempting to create form data, internet server error",
|
29
|
+
13 => "Errorcode 13: Error while attempting to delete form data, invalid form identifier or internal server error",
|
30
|
+
14 => "Errorcode 14: Error while attempting to modify form data, invalid form identifier",
|
31
|
+
15 => "Errorcode 15: Error while attempting to output form data, invalid form identifier",
|
32
|
+
16 => "Errorcode 16: Internal Server Error while attempting to remove form data",
|
33
|
+
17 => "Errorcode 17: Error while attempting to update form data, invalid session or form identifier"
|
34
|
+
}
|
35
|
+
|
36
|
+
# Existing hash types used by the server.
|
37
|
+
HASH_TYPES = {
|
38
|
+
:HASH_NONE => 0,
|
39
|
+
:HASH_SHA1 => 1,
|
40
|
+
:HASH_SHA224 => 2,
|
41
|
+
:HASH_SHA256 => 3,
|
42
|
+
:HASH_MD5 => 4
|
43
|
+
}
|
44
|
+
|
45
|
+
# Existing data types used by the server.
|
46
|
+
DATA_TYPES = {
|
47
|
+
0 => :DT_NULL,
|
48
|
+
1 => :DT_BOOLEAN,
|
49
|
+
2 => :DT_CHAR,
|
50
|
+
3 => :DT_DOUBLE,
|
51
|
+
4 => :DT_FLOAT,
|
52
|
+
5 => :DT_INTEGER,
|
53
|
+
6 => :DT_LONG_INTEGER,
|
54
|
+
7 => :DT_STRING,
|
55
|
+
8 => :DT_UNSIGNED_INTEGER,
|
56
|
+
9 => :DT_UNSIGNED_LONG_INTEGER,
|
57
|
+
10 => :DT_BLOB,
|
58
|
+
11 => :DT_VARIANT,
|
59
|
+
-1 => :DT_UNDEFINED
|
60
|
+
}
|
61
|
+
|
62
|
+
# Existing access types allowed by the server.
|
63
|
+
DATA_ACCESS = {
|
64
|
+
0 => :DA_READ_ONLY,
|
65
|
+
1 => :DA_READ_WRITE,
|
66
|
+
2 => :DA_WRITE_ONLY,
|
67
|
+
-1 => :DA_UNDEFINED
|
68
|
+
}
|
69
|
+
|
70
|
+
# === Parameters
|
71
|
+
# * host = Hostname (required)
|
72
|
+
# * port = Port (required)
|
73
|
+
# * protocol = "http"/"https", defaults to "http"
|
74
|
+
# * log_level = defaults to LOGGER::INFO
|
75
|
+
# * auth = Authentication method configured in SessionVOC server
|
76
|
+
def initialize(options = {})
|
77
|
+
default_options = {'host' => 'localhost', 'port' => '8208', 'protocol' => 'http', 'log_level' => Logger::INFO,
|
78
|
+
'strict_mode' => true, 'auth' => 'none'}
|
79
|
+
options = default_options.merge(options)
|
80
|
+
options.empty? ? read_configuration : self.configuration = Sessionvoc::Open::Configuration.new(options)
|
81
|
+
if defined?(Rails)
|
82
|
+
self.logger = Rails.logger
|
83
|
+
else
|
84
|
+
self.logger = Logger.new(STDOUT)
|
85
|
+
self.logger.level = options['log_level']
|
86
|
+
end
|
87
|
+
self.logger.info("SessionVOC Open Ruby Client Version: #{VERSION}")
|
88
|
+
end
|
89
|
+
|
90
|
+
protected
|
91
|
+
# Reads the configuration from the current directory and when it doesn't find it falls back to the
|
92
|
+
# global configuration in the home directory (~/.sessionvoc.yml) under which this ruby interpreter is run.
|
93
|
+
def read_configuration
|
94
|
+
if File.exists?("config.yml")
|
95
|
+
logger.info("Using config in this directory")
|
96
|
+
self.configuration = Sessionvoc::Open::Configuration.new(YAML.load(File.read("config.yml")))
|
97
|
+
else
|
98
|
+
begin
|
99
|
+
logger.info("Using config in your home directory")
|
100
|
+
self.configuration = Sessionvoc::Open::Configuration.new(YAML.load(File.read("#{ENV['HOME']}/.sessionvoc.yml")))
|
101
|
+
rescue Errno::ENOENT
|
102
|
+
raise Sessionvoc::Open::ConfigurationMissingException, "config.yml expected in current directory or ~/.sessionvoc.yml"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Returns the HTTP base URL for the SessionVOC Rest Service.
|
108
|
+
def base_url
|
109
|
+
"#{self.configuration.options['protocol']}://#{self.configuration.options['host']}:#{self.configuration.options['port']}"
|
110
|
+
end
|
111
|
+
|
112
|
+
# Returns true/false whether to use the client in strict-mode or not.
|
113
|
+
# In strict-mode exceptions are raised for the most common client operations.
|
114
|
+
def use_strict_mode?
|
115
|
+
self.configuration.options['strict_mode']
|
116
|
+
end
|
117
|
+
|
118
|
+
# Convenience method to access error codes from within this instance.
|
119
|
+
def codes; ERROR_CODES; end
|
120
|
+
|
121
|
+
# Internal method used to handle internal exceptions and map the error code to a human
|
122
|
+
# readable message.
|
123
|
+
# === Parameters
|
124
|
+
# * errorCode = Errorcode number
|
125
|
+
# * message = Optional message
|
126
|
+
def handle_exception(errorCode, message = nil)
|
127
|
+
case errorCode
|
128
|
+
when 1
|
129
|
+
raise Sessionvoc::Open::InternalServerErrorException, display_message(errorCode, message)
|
130
|
+
when 2
|
131
|
+
raise Sessionvoc::Open::IllegalRequestException, display_message(errorCode, message)
|
132
|
+
when 3
|
133
|
+
raise Sessionvoc::Open::InvalidSidException, display_message(errorCode, message)
|
134
|
+
when 4
|
135
|
+
raise Sessionvoc::Open::AuthentificationFailedException, display_message(errorCode, message)
|
136
|
+
when 5
|
137
|
+
raise Sessionvoc::Open::InvalidFidException, display_message(errorCode, message)
|
138
|
+
when 6
|
139
|
+
raise Sessionvoc::Open::TemporaryErrorException, display_message(errorCode, message)
|
140
|
+
when 7
|
141
|
+
raise Sessionvoc::Open::IllegalAuthentificationRequestException, display_message(errorCode, message)
|
142
|
+
when 8
|
143
|
+
raise Sessionvoc::Open::IllegalUserIdentifierException, display_message(errorCode, message)
|
144
|
+
when 9
|
145
|
+
raise Sessionvoc::Open::SessionDeletionFailure, display_message(errorCode, message)
|
146
|
+
when 11
|
147
|
+
raise Sessionvoc::Open::InvalidJSONException, display_message(errorCode, message)
|
148
|
+
when 12
|
149
|
+
raise Sessionvoc::Open::InternalServerErrorException, display_message(errorCode, message)
|
150
|
+
when 13
|
151
|
+
raise Sessionvoc::Open::InvalidFidException, display_message(errorCode, message)
|
152
|
+
when 14
|
153
|
+
raise Sessionvoc::Open::FormDataCantBeModifiedException, display_message(errorCode, message)
|
154
|
+
when 15
|
155
|
+
raise Sessionvoc::Open::InvalidFidException, display_message(errorCode, message)
|
156
|
+
when 16
|
157
|
+
raise Sessionvoc::Open::FormDataCantBeDestroyedException, display_message(errorCode, message)
|
158
|
+
when 17
|
159
|
+
raise Sessionvoc::Open::InvalidSidException, display_message(errorCode, message)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Displays a message if available.
|
164
|
+
def display_message(errorCode, message)
|
165
|
+
message ? "#{codes[errorCode]} - #{message}" : codes[errorCode]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Copyright:: 2011 triAGENS GmbH
|
2
|
+
# Author:: Oliver Kiessler (mailto:kiessler@inceedo.com)
|
3
|
+
module Sessionvoc
|
4
|
+
module Open
|
5
|
+
# You can setup the client by passing options into the constructor or by using a configuration file in YAML.
|
6
|
+
# client = Sessionvoc::Open::Client.new('host' => 'localhost', 'port' => 12345, 'auth' => 'challenge')
|
7
|
+
class Client < Sessionvoc::Open::Base
|
8
|
+
include Sessionvoc::Open::Session
|
9
|
+
include Sessionvoc::Open::Authentification
|
10
|
+
include Sessionvoc::Open::FormData
|
11
|
+
include Sessionvoc::Open::DataConversion
|
12
|
+
include Sessionvoc::Open::MetaData
|
13
|
+
|
14
|
+
private
|
15
|
+
# Internal method to create the httparty request and return the http response that is already parsed by httparty.
|
16
|
+
# === Parameters
|
17
|
+
# * http_verb = HTTP verb symbol (:get, :post, :put, :delete)
|
18
|
+
# * endpoint = HTTP URL endpoint
|
19
|
+
# * options = Optional options with body and headers
|
20
|
+
def get_response(http_verb, endpoint, options = {}, no_uri_escape = false)
|
21
|
+
begin
|
22
|
+
if no_uri_escape
|
23
|
+
endpoint_value = "#{base_url}#{endpoint}"
|
24
|
+
else
|
25
|
+
endpoint_value = "#{base_url}#{URI.escape(endpoint)}"
|
26
|
+
end
|
27
|
+
logger.debug "Using endpoint: #{endpoint_value}"
|
28
|
+
body = {}; body.merge!(options) if options and options.any?
|
29
|
+
response = (http_verb == :post or http_verb == :put) ? HTTParty.send(http_verb, endpoint_value, body) : HTTParty.send(http_verb, endpoint_value)
|
30
|
+
logger.debug "Response: #{response.inspect}" if response
|
31
|
+
response
|
32
|
+
rescue => e
|
33
|
+
logger.error("Could not connect to SessionVOC: #{e.message}")
|
34
|
+
raise Sessionvoc::Open::ConnectionRefusedException
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Internal method to check the statuscode of a response and its error message if available.
|
39
|
+
# === Parameters
|
40
|
+
# * response = HTTP response
|
41
|
+
def response_ok?(response)
|
42
|
+
response and response.parsed_response and response.response.is_a?(Net::HTTPOK) and not response.parsed_response["error"]
|
43
|
+
end
|
44
|
+
|
45
|
+
# Internal method to get meta data about the types and access permissions for the given SessionVOC server installation.
|
46
|
+
def meta_data
|
47
|
+
logger.debug("Client#meta_data")
|
48
|
+
@@meta_data ||= nil
|
49
|
+
@@meta_data = self.datainfo unless @@meta_data
|
50
|
+
@@meta_data
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright:: 2011 triAGENS GmbH
|
2
|
+
# Author:: Oliver Kiessler (mailto:kiessler@inceedo.com)
|
3
|
+
module Sessionvoc
|
4
|
+
module Open
|
5
|
+
# You can also provide a configuration file in the current directory of your client to avoid setting up the client within your code.
|
6
|
+
# Checkout the config.yml.sample file as an example.
|
7
|
+
#
|
8
|
+
# If this configuration file isn't found in the current directory, the client will look for a "global" configuration file in your
|
9
|
+
# home directory (~/.sessionvoc.yml).
|
10
|
+
class Configuration
|
11
|
+
attr_accessor :options
|
12
|
+
|
13
|
+
# === Parameters
|
14
|
+
# * host = Hostname (required)
|
15
|
+
# * port = Port (required)
|
16
|
+
# * protocol = "http"/"https", defaults to "http"
|
17
|
+
# * auth = "none"/"simple"/"challenge"
|
18
|
+
# * log_level = defaults to LOGGER::INFO
|
19
|
+
def initialize(options = {})
|
20
|
+
self.options = options
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# Copyright:: 2011 triAGENS GmbH
|
2
|
+
# Author:: Oliver Kiessler (mailto:kiessler@inceedo.com)
|
3
|
+
module Sessionvoc
|
4
|
+
module Open
|
5
|
+
# The methods in this module handle the data conversion and access permissions expected by the SessionVOC
|
6
|
+
# server.
|
7
|
+
module DataConversion
|
8
|
+
# Forces session values to conform the data type the SessionVOC server expects. This method also
|
9
|
+
# checks if the value is allowed to be changed.
|
10
|
+
# === Parameters
|
11
|
+
# * scope = "transData","userData","formData"
|
12
|
+
# * key = Key
|
13
|
+
# * value = Value
|
14
|
+
# * session_data = Session object to work on
|
15
|
+
def enforce_value_type(scope, key, value, session_data)
|
16
|
+
if session_data and session_data[scope] and session_data['sid']
|
17
|
+
meta_data = datainfo
|
18
|
+
scope = "form" if scope == "formData"
|
19
|
+
if meta_data and meta_data["access"] and meta_data["access"][scope] and [1, 2].include?(meta_data["access"][scope][key.to_s])
|
20
|
+
if meta_data["types"] and meta_data["types"][scope] and meta_data["types"][scope][key.to_s]
|
21
|
+
desired_type = Sessionvoc::Open::Base::DATA_TYPES[meta_data["types"][scope][key.to_s]]
|
22
|
+
if desired_type
|
23
|
+
session_data[scope][key] = convert(key, value, desired_type)
|
24
|
+
else
|
25
|
+
raise Sessionvoc::Open::DataConversionException, "Unknown type"
|
26
|
+
end
|
27
|
+
else
|
28
|
+
raise Sessionvoc::Open::DataConversionException, "Unknown attribute"
|
29
|
+
end
|
30
|
+
else
|
31
|
+
raise Sessionvoc::Open::DataConversionException, "Scope '#{scope}' not found"
|
32
|
+
end
|
33
|
+
return session_data
|
34
|
+
else
|
35
|
+
if session_data.nil? or (session_data['sid'].nil? or session_data['sid'].blank?)
|
36
|
+
raise Sessionvoc::Open::InvalidSidException
|
37
|
+
else
|
38
|
+
raise Sessionvoc::Open::DataConversionException
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Sets the meta data used by the SessionVOC server.
|
44
|
+
def datainfo
|
45
|
+
@@meta_data ||= nil
|
46
|
+
@@meta_data = ActionDispatch::Session::SessionvocStore::Session.client.datainfo unless @@meta_data
|
47
|
+
@@meta_data
|
48
|
+
end
|
49
|
+
|
50
|
+
# This methods performs the actual type conversion.
|
51
|
+
# === Parameters
|
52
|
+
# * key = Key
|
53
|
+
# * value = value
|
54
|
+
# * desired_type = Type expected by SessionVOC server
|
55
|
+
def convert(key, value, desired_type)
|
56
|
+
if key and value and desired_type
|
57
|
+
begin
|
58
|
+
case desired_type
|
59
|
+
when :DT_NULL
|
60
|
+
value = nil
|
61
|
+
when :DT_BOOLEAN
|
62
|
+
if value == "true" or value == "1"
|
63
|
+
value = true
|
64
|
+
elsif value == "false" or value == "0"
|
65
|
+
value = false
|
66
|
+
else
|
67
|
+
value = false
|
68
|
+
end
|
69
|
+
when :DT_CHAR
|
70
|
+
value = value.to_s[0..0]
|
71
|
+
when :DT_STRING
|
72
|
+
value = value.to_s
|
73
|
+
when :DT_DOUBLE
|
74
|
+
value = value.to_f
|
75
|
+
when :DT_FLOAT
|
76
|
+
value = value.to_f
|
77
|
+
when :DT_INTEGER
|
78
|
+
value = value.to_i
|
79
|
+
when :DT_LONG_INTEGER
|
80
|
+
value = value.to_i
|
81
|
+
when :DT_UNSIGNED_INTEGER
|
82
|
+
value = value.to_i
|
83
|
+
value = nil if value < 0
|
84
|
+
when :DT_UNSIGNED_LONG_INTEGER
|
85
|
+
value = value.to_i
|
86
|
+
value = nil if value < 0
|
87
|
+
when :DT_BLOB
|
88
|
+
value = Base64.encode64(value)
|
89
|
+
else
|
90
|
+
value = value.to_s
|
91
|
+
end
|
92
|
+
rescue => e
|
93
|
+
return nil
|
94
|
+
end
|
95
|
+
value
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|