sessionvoc-open 1.7.3
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/.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
|