# module GxGwww # RETAINED = {} RETAINED_THREAD_SAFETY = ::Mutex.new def self.get_retained(the_key) result = nil RETAINED_THREAD_SAFETY.synchronize do result = ::GxGwww::RETAINED[(the_key)] end result end def self.set_retained(the_key, the_value=nil) RETAINED_THREAD_SAFETY.synchronize do ::GxGwww::RETAINED[(the_key)] = the_value end the_value end # ### API toolbox API = {} API_SESSIONS = {} API_THREAD_SAFETY = ::Mutex.new def self.publish_api(the_service=nil, the_path=nil) if the_service && the_path the_controller = ::GxGwww::APIController.new(the_service, the_path) if the_controller ::GxGwww::API_THREAD_SAFETY.synchronize { ::GxGwww::API[(the_path.to_sym)] = the_controller } true else false end else false end end # def self.unpublish_api(the_path="/unknown") if the_path ::GxGwww::API_THREAD_SAFETY.synchronize { ::GxGwww::API.delete(the_path.to_sym) } end true end # def self.api_login(session_id=nil, credential=:"00000000-0000-4000-0000-000000000000") if session_id ::GxGwww::API_THREAD_SAFETY.synchronize { ::GxGwww::API_SESSIONS[(session_id.to_sym)] = credential } true else false end end # def self.api_logout(session_id=nil) if session_id ::GxGwww::API_THREAD_SAFETY.synchronize { ::GxGwww::API_SESSIONS.delete(session_id.to_sym) } true else false end end # def self.api_credential(session_id=nil) result = :"00000000-0000-4000-0000-000000000000" if session_id ::GxGwww::API_THREAD_SAFETY.synchronize { result = (::GxGwww::API_SESSIONS[(session_id.to_sym)] || :"00000000-0000-4000-0000-000000000000") } end result end # class APIController def initialize(the_service=nil, the_path="/unknown") @service = the_service @path = the_path end def service @service end def path @path end # def process(the_method=nil, the_request=nil, the_session=nil) credential = ::GxGwww::api_credential(the_session['session_id']) # Pre-processing response = nil operation = nil begin if the_method case the_method when :get if the_request["details"].to_s == "eyJpbnRyb2R1Y3Rpb24iOnRydWV9" response = [200, {"content-type" => "application/text"}, ({:csrf => the_session["csrf"]}.gxg_export.to_json.encode64)] else operation = (::JSON::parse(URI.unescape(URI.unescape(the_request.params["details"].to_s.decode64.decrypt(the_session["csrf"]))), {:symbolize_names => true})) unless operation.is_a?(::Hash) response = [500, {"content-type" => "application/text"}, "Malformed query."] end end when :put if the_request.body.respond_to?(:rewind) && the_request.body.respond_to?(:read) the_request.body.rewind operation = (::JSON::parse(URI.unescape(URI.unescape(the_request.body.read().to_s.decode64.decrypt(the_session["csrf"]))), {:symbolize_names => true})) unless operation.is_a?(::Hash) response = [500, {"content-type" => "application/text"}, "Malformed payload."] end else log_warn("Abnormal PUT Body #{the_request.body.inspect}") response = [500, {"content-type" => "application/text"}, "Malformed payload."] end else response = [500, {"content-type" => "application/text"}, "Provide a get or put method."] end else response = [500, {"content-type" => "application/text"}, "No http method provided."] end rescue Exception => the_error response = [500, {"content-type" => "application/text"}, the_error.to_s] end # Processing unless response response = [403, {"content-type" => "application/text"}, "You don't have permissions to do that."] # Operation formatting if operation.is_a?(::Hash) operation = ::Hash::gxg_import(operation) operation.search do |the_value, the_selector, the_container| if the_value.is_a?(::Hash) if the_value[:formats].is_a?(::Hash) && the_value[:records].is_a?(::Array) imported_list = ::GxG::Database::Database::detached_package_import(the_value) if imported_list.size > 1 the_container[(the_selector)] = imported_list else the_container[(the_selector)] = imported_list[0] end end end end end # if operation case operation.keys[0].to_sym when :upgrade_credential new_credential = ::GxG::DB[:authority].user_credential(operation[:upgrade_credential][:username].to_s, operation[:upgrade_credential][:password].to_s) if new_credential response = [200, {"content-type" => "application/text"}, {:result => ::GxGwww::api_login(the_session['session_id'], new_credential), :error => nil}.gxg_export.to_json.encrypt(the_session["csrf"]).encode64] else response = [403, {"content-type" => "application/text"}, {:result => nil, :error => "Bad username or password."}.gxg_export.to_json.encrypt(the_session["csrf"]).encode64] end when :downgrade_credential response = [200, {"content-type" => "application/text"}, {:result => ::GxGwww::api_logout(the_session['session_id']), :error => nil}.gxg_export.to_json.encrypt(the_session["csrf"]).encode64] when :interface response = [200, {"content-type" => "application/text"}, {:result => @service.interface(credential)}.gxg_export.to_json.encrypt(the_session["csrf"]).encode64] else begin call_response = @service.call_event(operation, credential) if call_response.is_a?(::Hash) call_response.search do |the_value, the_selector, the_container| if the_value.is_any?(::GxG::Database::PersistedHash, ::GxG::Database::DetachedHash) the_container[(the_selector)] = the_value.export_package() end end end response = [200, {"content-type" => "application/text"}, call_response.gxg_export.to_json.encrypt(the_session["csrf"]).encode64] rescue Exception => the_error response = [500, {"content-type" => "application/text"}, the_error.to_s] end end # the_manifest = GxG::SERVICES[:www][:manifests][(the_session['session_id'])] end end # response # API ???? # @service.call_event(operation_envelope=nil, credential) # GxG::SERVICES[:www][:manifests][(the_session['session_id'])] # unless the_manifest # the_manifest = ::GxGwww::Manifest.new({:credential => :'00000000-0000-4000-0000-000000000000'}) # # manifest format: {:credential => :'00000000-0000-4000-0000-000000000000', :displays => {}, :timers => {}, :connectors => {}, :status => :none} # GxG::SERVICES[:www][:manifests][(the_session['session_id'])] = the_manifest # end # operations = [] # case the_method # when :get # if the_request.params["details"].to_s.size > 0 # operations = (::JSON::parse(URI.unescape(URI.unescape(the_request.params["details"].to_s.decode64)), {:symbolize_names => true})) # end # when :put # if the_request.body.respond_to?(:rewind) && the_request.body.respond_to?(:read) # the_request.body.rewind # operations = (::JSON::parse(URI.unescape(URI.unescape(the_request.body.read())), {:symbolize_names => true})) # else # log_warn("Abnormal PUT Body #{the_request.body.inspect}") # end # end end end # ### Application Support module Applications MENU = [] def self.refresh_application_menu() result = false GxGwww::Applications::MENU.clear source_queue = ["/Public/www/software/applications"] while source_queue.size > 0 do the_item = source_queue.shift if ::GxG::VFS.exist?(the_item.to_s) profile = ::GxG::VFS.profile(the_item.to_s) if profile.is_a?(::Hash) # if [:virtual_directory, :directory, :persisted_array].include?(profile[:type]) ::GxG::VFS.entries(the_item.to_s).each do |entry| source_queue << (the_item.to_s + "/" + entry[:title]) end else # object = GxG::VFS.open(the_item) if object[:component].to_s == "application" record = {:location => (the_item[7..-1]), :application_icon_type => "", :application_icon => "", :application_name => "", :credentialed => false, :unique => true, :category => ""} # TODO: camelize this title text record[:application_name] = object.title.gsub("_"," ") # icon = nil icon_type = nil object[:content].each do |resource| if resource.title() == "application_icon" if resource[:options][:image_data] icon = resource[:options][:image_data] if icon.is_a?(::GxG::ByteArray) icon = icon.to_s end if resource[:options][:image_type] icon_type = resource[:options][:image_type] else mime_type = ::MimeMagic.by_magic(::StringIO.new(icon.to_s)) if mime_type icon_type = mime_type.type else icon_type = "application/octet-stream" end end icon = icon.encode64 else if resource[:options][:src] icon = resource[:options][:src] end end if icon break end end end if icon if icon_type record[:application_icon_type] = icon_type end record[:application_icon] = icon else cache_entry = ::GxGwww::CACHE.fetch("/themes/setup/icons/gxg_app.png",GxG::DB[:administrator]) if cache_entry record[:application_icon_type] = cache_entry[:content_type] record[:application_icon] = cache_entry[:data].to_s.encode64 end end # the_options = (object[:options].unpersist || {}) if the_options[:credentialed] == true record[:credentialed] = true else record[:credentialed] = false end if the_options[:unique] == true record[:unique] = true else record[:unique] = false end record[:category] = (the_options[:category] || "Other") # GxGwww::Applications::MENU << record end # end # end end # end result end end # module Storage class UnifiedMemoryCache # ONLY works with GxG::VFS # TODO : re-organize to use UniversalResourceAccessor # Access files and objects via: GxG::SERVICES[:core][:resources] # returns ==> {:token => the_token, :path => the_path, :resource => the_resource} def initialize() @cache_configuration = {} @cache_memory = {} @thread_safety = ::Mutex.new @cache_configuration[:cache_quota] = (GxG::SERVICES[:www].configuration[:cache_quota] || 1073741824) @cache_configuration[:cache_max_item_size] = (GxG::SERVICES[:www].configuration[:cache_max_item_size] || 1073741824) # self end # def flush_cache() @thread_safety.synchronize { @cache_memory = {} } end # def flush_cache_item(specifier=nil) if specifier.is_any?(::String, ::Symbol) @thread_safety.synchronize { @cache_memory.delete(specifier.to_s) } true else false end end # # def public_vfs_fetch(the_vfs_path="", credential=:"00000000-0000-4000-0000-000000000000") # # Does NOT fetch entire directories, only files/db_objects at specific path # # # log_info("Caching --> #{the_vfs_path}") # result = nil # unless GxG::SERVICES[:core][:resources].busy?(the_vfs_path) # if GxG::SERVICES[:core][:resources].exist?(the_vfs_path) # profile = GxG::SERVICES[:core][:resources].profile(the_vfs_path, credential) # if profile # case profile[:type] # when :file, :application, :library, :symlink # if profile[:size] <= @cache_configuration[:cache_max_item_size] # handle = GxG::SERVICES[:core][:resources].open(the_vfs_path.to_s, credential) # if handle # handle[:resource].rewind # # # if (the_vfs_path.to_s[0..10]) == "/Public/www" # location = the_vfs_path.to_s[11..-1] # else # location = the_vfs_path.to_s # end # # # buffer = ::GxG::ByteArray.new(handle[:resource].read()) # GxG::SERVICES[:core][:resources].close(handle[:token]) # # # result = {:location => location, :entry => {:content_type => profile[:mime], :data => buffer.to_s, :uuid => nil, :version => profile[:version], :database => nil, :profile => profile}} # # # end # else # log_warn "VFS file is too big to load (ignoring): #{the_vfs_path.to_s}" # end # when :persisted_hash # handle = GxG::SERVICES[:core][:resources].open(the_vfs_path.to_s, credential) # if handle # uuid = handle[:resource].uuid # version = handle[:resource].version # database = handle[:resource].db_address()[:database] # db_role = self.role_for_database(database) # # Include format records in gxg_export format # # This will trade bandwidth + memory for a speed gain later client side hopefully. # # Review: replace with .sync_export(credential,).to_json.encode64 # format_records = {} # object_record = handle[:resource].export # object_record.search do |item,selector,container| # if selector == :format || selector == :constraint # if item.to_s.size > 0 && ::GxG::valid_uuid?(item.to_s) # format_uuid = item # unless format_records[(item.to_s.to_sym)].is_a?(::Hash) # format_sample = database.format_load({:uuid => format_uuid.to_s.to_sym}) # format_sample[:content] = format_sample[:content].gxg_export() # format_records[(format_uuid.to_s.to_sym)] = format_sample # end # end # end # end # # buffer = ::GxG::ByteArray.new(::JSON.pretty_generate({:formats => format_records, :record => object_record}).encode64) # buffer = {:formats => format_records, :record => object_record}.to_json.encode64 # if buffer.size <= @cache_configuration[:cache_max_item_size] # # # if (the_vfs_path.to_s[0..10]) == "/Public/www" # location = the_vfs_path.to_s[11..-1] # else # location = the_vfs_path.to_s # end # # # # xxx Set Public permissions on db object. (publication speedup) # # # # xxx profile[:permissions][:other] = database.effective_element_permission(handle[:resource].db_address[:table], handle[:resource].db_address[:dbid], :"00000000-0000-4000-0000-000000000000") # result = {:location => location, :entry => {:content_type => "application/json+base64", :data => buffer.to_s, :uuid => uuid, :version => version, :database => db_role, :profile => profile}} # # # else # log_warn "VFS object is too big to load (ignoring): #{the_vfs_path.to_s}" # end # GxG::SERVICES[:core][:resources].close(handle[:token]) # end # end # end # end # end # result # end # # def add_to_cache(the_vfs_path="") # # # source_queue = [] # if the_vfs_path.is_any?(::Array, ::GxG::Database::PersistedArray) # source_list = the_vfs_path # else # source_list = [(the_vfs_path)] # end # source_list.each do |item| # if item.to_s.valid_path? # source_queue << item # end # end # # # while source_queue.size > 0 do # the_item = source_queue.shift # if GxG::SERVICES[:core][:resources].exist?(the_item.to_s) # profile = GxG::SERVICES[:core][:resources].profile(the_item.to_s) # if profile.is_a?(::Hash) # # # if [:virtual_directory, :directory, :persisted_array].include?(profile[:type]) # GxG::SERVICES[:core][:resources].entries(the_item.to_s).each do |entry| # source_queue << (the_item.to_s + "/" + entry[:title]) # end # else # # Cache Item # current_cache_size = @thread_safety.synchronize { @cache_memory.heap_used() } # record = self.public_vfs_fetch(the_item) # if record # if (record[:entry][:data].size <= @cache_configuration[:cache_max_item_size] && (record[:entry][:data].size + current_cache_size) <= @cache_configuration[:cache_quota]) # # Padrino.cache[(record[:location])] = record[:entry] # @thread_safety.synchronize { @cache_memory[(record[:location])] = record[:entry] } # else # log_warn "VFS item is too big to be cached (ignoring): #{the_item.to_s}" # end # end # end # # # end # end # # # end # # # end # def fetch_by_uuid(the_uuid=nil, credential=nil, auto_cache=true,search_only=false) result = nil # Search Cache first for matching entry the_object = nil found = nil from_cache = false unless search_only @thread_safety.synchronize do @cache_memory.keys.each do |the_key| if @cache_memory[(the_key)][:uuid].to_s.to_sym == the_uuid.to_sym found = @cache_memory[(the_key)] from_cache = true break end end end end # Then search each db by role for the object with the uuid (slow) unless found already_searched = [] GxG::DB[:roles].keys.each do |the_db_role| the_db = GxG::DB[:roles][(the_db_role)] unless already_searched.index(the_db) already_searched << the_db the_object = the_db.retrieve_by_uuid(the_uuid,credential) if the_object.is_a?(::GxG::Database::PersistedHash) break else the_object = nil end end # end # if the_object # prepare into Cache entry uuid = the_object.uuid version = the_object.version database = the_object.db_address()[:database] db_role = self.role_for_database(database) # Include format records in gxg_export format format_records = {} object_record = the_object.export object_record.search do |item,selector,container| if selector == :format || selector == :constraint if item.to_s.size > 0 format_uuid = item unless format_records[(item.to_s.to_sym)].is_a?(::Hash) format_sample = database.format_load({:uuid => format_uuid.to_s.to_sym}) format_sample[:content] = format_sample[:content].gxg_export() format_records[(format_uuid.to_s.to_sym)] = format_sample end end end end # buffer = ::GxG::ByteArray.new(::JSON.pretty_generate({:formats => format_records, :record => object_record}).encode64) buffer = {:formats => format_records, :records => [(object_record)]}.to_json.encode64 if buffer.size <= @cache_configuration[:cache_max_item_size] # Set Public permissions on db object. (publication speedup) # profile = {:title=> the_object.title, :type=>:persisted_hash, :owner_type=>:persisted_hash, :uuid=>uuid, :on_device=>nil, :on_device_major=>nil, :on_device_minor=>nil, :is_device=>nil, :is_device_major=>nil, :is_device_minor=>nil, :inode=>nil, :flags=>[:read], :hardlinks_to=>0, :user_id=>nil, :group_id=>nil, :size=>0, :block_size=>0, :blocks=>0, :accessed=>nil, :modified=>nil, :status_modified=>nil, :permissions=>{:effective=>{:execute=>false, :rename=>true, :move=>true, :destroy=>true, :create=>true, :write=>true, :read=>true}}, :mode=>nil} profile[:permissions][:effective] = database.effective_element_permission(the_object.db_address[:table], the_object.db_address[:dbid], credential.to_s.to_sym) # profile[:permissions][:other] = database.effective_element_permission(the_object.db_address[:table], the_object.db_address[:dbid], :"00000000-0000-4000-0000-000000000000") found = {:content_type => "application/json+base64", :data => buffer.to_s, :uuid => uuid, :version => version, :database => db_role, :profile => profile} # end the_object.deactivate end end # Cache if auto_cache=true if found unless from_cache if auto_cache @thread_safety.synchronize do @cache_memory[(the_uuid.to_s)] = found end end end result = found end result end # def role_for_database(the_db=nil) result = :vfs GxG::DB[:roles].keys.each do |the_db_role| if the_db == GxG::DB[:roles][(the_db_role)] result = the_db_role break end end result end # def database_by_role(the_role=nil) result = nil GxG::DB[:roles].keys.each do |the_db_role| if the_role == the_db_role result = GxG::DB[:roles][(the_db_role)] break end end result end # def update_cache_item(the_vfs_path="") # Customizable later: if ::GxG::valid_uuid?(the_vfs_path) # This is kinda crack-monkey, but it will only search dbs for a fresh copy of the object and add it to Cache. self.fetch_by_uuid(the_vfs_path, GxG::DB[:administrator], true, true) else self.add_to_cache(the_vfs_path) end true end # def fetch(the_location="",credential=:"00000000-0000-4000-0000-000000000000",auto_cache=true) result = nil fits_in_cache = true # if auto_cache == true @thread_safety.synchronize { result = @cache_memory[(the_location.to_s)] } end unless result.is_a?(::Hash) if ::GxG::valid_uuid?(the_location.to_s) # DB Object result = self.fetch_by_uuid(the_location.to_s, credential, false, false) else # File or DB Object in VFS handle = ::GxG::SERVICES[:core][:resources].open(the_location.to_s, credential) # profile = ::GxG::SERVICES[:core][:resources].profile(the_location.to_s, credential) # if handle.is_a?(::Hash) && profile.is_a?(::Hash) if handle[:resource].is_a?(::GxG::Database::PersistedHash) # DB Object uuid = handle[:resource].uuid version = handle[:resource].version database = handle[:resource].db_address()[:database] db_role = self.role_for_database(database) # Include format records in gxg_export format format_records = {} object_record = handle[:resource].export object_record.search do |item,selector,container| if selector == :format || selector == :constraint if item.to_s.size > 0 format_uuid = item unless format_records[(item.to_s.to_sym)].is_a?(::Hash) format_sample = database.format_load({:uuid => format_uuid.to_s.to_sym}) if format_sample.is_a?(::Hash) format_sample[:content] = format_sample[:content].gxg_export() format_records[(format_uuid.to_s.to_sym)] = format_sample end end end end end # buffer = ::GxG::ByteArray.new(::JSON.pretty_generate({:formats => format_records, :record => object_record}).encode64) buffer = {:formats => format_records, :records => [(object_record)]}.to_json.encode64 result = {:content_type => "application/json+base64", :data => buffer.to_s, :uuid => uuid, :version => version, :database => db_role, :profile => profile} unless buffer.size <= @cache_configuration[:cache_max_item_size] fits_in_cache = false log_warn("Item TOO BIG for CACHE : #{buffer.size} for #{handle[:path]}") end else # File Object if handle[:resource].is_a?(::File) handle[:resource].rewind buffer = ::GxG::ByteArray.new(handle[:resource].read().to_s) result = {:content_type => profile[:mime], :data => buffer.to_s, :uuid => nil, :version => profile[:version], :database => nil, :profile => profile} unless buffer.size <= @cache_configuration[:cache_max_item_size] fits_in_cache = false log_warn("Item TOO BIG for CACHE : #{buffer.size} for #{handle[:path]}") end end end # ::GxG::SERVICES[:core][:resources].close(handle[:token]) end end if result.is_a?(::Hash) if auto_cache == true && fits_in_cache == true # Store in CACHE @thread_safety.synchronize { @cache_memory[(the_location.to_s)] = result } end end end # result end end end # DisplayState class Display def initialize(settings={}) @resource_path = settings[:resource] @session = settings[:session] @uuid = (settings[:uuid] || GxG::uuid_generate) @remote_uuid = nil @socket = nil self end # def socket() @socket end # def set_socket(the_uuid) the_socket = nil GxGwww::SOCKETS_SAFETY.synchronize { the_socket = GxGwww::SOCKETS[(the_uuid)] if the_socket the_socket.instance_variable_set(:@session, @session) the_socket.instance_variable_set(:@display, @uuid) end } if the_socket @socket = the_socket true else false end end end # class Manifest def initialize(settings={}) @thread_safety = ::Mutex.new @credential = (settings[:credential] || :"00000000-0000-4000-0000-000000000000") @displays ={} @connectors = {} @timers = {} @state = :uncredentialed self end # def credential_set(the_credential=:"00000000-0000-4000-0000-000000000000") if the_credential @thread_safety.synchronize { @credential = the_credential } end end # def credential_get() the_credential = :"00000000-0000-4000-0000-000000000000" @thread_safety.synchronize { the_credential = @credential } the_credential end # def display_count() the_count = 0 @thread_safety.synchronize { the_count = @displays.keys.size } the_count end # def display_keys() the_keys = [] @thread_safety.synchronize { the_keys = @displays.keys } the_keys end # def display_exist?(the_display_key=nil) result = false if the_display_key @thread_safety.synchronize { if @displays[(the_display_key)] result = true end } end result end # def display_get(the_display_key=nil) result = :available if the_display_key @thread_safety.synchronize { result = @displays[(the_display_key)] } end result end # def display_set(the_display_key=nil, the_value=:available) result = nil if the_display_key @thread_safety.synchronize { @displays[(the_display_key)] = the_value } end result end # def state_set(the_state=:none) @thread_safety.synchronize { @state = the_state } end # def state_get() the_state = :none @thread_safety.synchronize { the_state = @state } the_state end # def timer_get(the_display_key=nil) result = nil if the_display_key @thread_safety.synchronize { result = @timers[(the_display_key)] } end result end # def timer_set(the_display_key=nil, timeout=0.0) if the_display_key @thread_safety.synchronize { @timers[(the_display_key)] = timeout } timeout else nil end end # def connector_get(the_display_key=nil) result = nil if the_display_key @thread_safety.synchronize { result = @connectors[(the_display_key)] } end result end # def connector_set(the_display_key=nil, the_connector=nil) if the_display_key && the_connector @thread_safety.synchronize { @connectors[(the_display_key)] = the_connector } end end end # --------------------------------------------------------------------- class Responder # def initialize(options={}) @thread_safety = ::Mutex.new end # def handle_request(the_method=nil, the_request=nil, the_session=nil) response = [404, {"content-type" => "application/text"}, "Not Found"] begin response[2] = "#{the_request.path} Not Found" if the_request.xhr? the_manifest = GxG::SERVICES[:www][:manifests][(the_session['session_id'])] unless the_manifest the_manifest = ::GxGwww::Manifest.new({:credential => :'00000000-0000-4000-0000-000000000000'}) # manifest format: {:credential => :'00000000-0000-4000-0000-000000000000', :displays => {}, :timers => {}, :connectors => {}, :status => :none} GxG::SERVICES[:www][:manifests][(the_session['session_id'])] = the_manifest end # the_display = (the_request.params["display_path"] || the_request.env["GxG-Display"]) the_display = the_request.params["display"] if the_display.is_a?(::String) if the_display.match(/\/display\/[0-9]/) || the_display.match(/\/display\/[0-9][0-9]/) if the_manifest if the_manifest.display_count() > 0 unless (the_display.split("/").last.to_i + 1) <= the_manifest.display_count() log_warn "Invalid Display Reference: #{the_display.inspect}" end end end else the_display = nil end else the_display = nil end # operations = [] the_parser = URI::Parser.new triple_parse = Proc.new {|the_string| the_parser.unescape(the_parser.unescape(the_parser.unescape(the_parser.unescape(the_string))))} case the_method when :get if the_request.params["details"].to_s.size > 0 operations = ::JSON::parse( triple_parse.call(the_request.params["details"].to_s.decode64), {:symbolize_names => true} ) end when :put if the_request.body.respond_to?(:rewind) && the_request.body.respond_to?(:read) the_request.body.rewind operations = ::JSON::parse( triple_parse.call(the_request.body.read), {:symbolize_names => true} ) else log_warn("Abnormal PUT Body #{the_request.body.inspect}") end when :post # if the_request.params["file"] if the_request.params["file"][:tempfile] temp_file = the_request.params["file"][:tempfile] if the_request.params["file"][:filename] file_name = the_request.params["file"][:filename] if the_request.params["destination"] destination = the_request.params["destination"] operations = [{:upload_file => {:temp_file => temp_file, :file_name => file_name, :destination => destination}}] end end end # end # end unless operations.is_a?(::Array) operations = [(operations)] end operations.each do |operation_frame| if operation_frame.is_a?(::Hash) the_operation = operation_frame.keys[0] parameters = operation_frame[(the_operation)] # Review : DEBUG: puts "Operation: #{the_operation.inspect} => #{parameters.inspect}" puts "Remote Host: #{the_request.env["HTTP_X_FORWARDED_FOR"].inspect}" puts "Session: #{the_session['session_id'].inspect}" # case the_operation when :heartbeat # use display_path? reset timer info? # pass server/credential status: :private or :public indicators only if the_manifest.credential_get() == :"00000000-0000-4000-0000-000000000000" status = {:status => "uncredentialed"} status[:credential] = (the_manifest.state_get() || :uncredentialed) else status = {:status => "credentialed"} status[:credential] = (the_manifest.state_get() || :credentialed) end if true # TODO: track and return the running mode of the server - Expansion status[:server] = :running else status[:server] = :maintainence end if the_display the_manifest.timer_set(the_display, ::Chronic::parse("in 3 minutes").to_f) end # response = [200, {"content-type" => "application/json"}, {:result => status}.to_json()] break # when :attach_socket if the_display the_uuid = parameters.to_s.to_sym if ::GxG::valid_uuid?(the_uuid) GxGwww::SOCKETS_SAFETY.synchronize { GxGwww::SOCKETS[(the_uuid)].instance_variable_set(:@session, the_session['session_id']) GxGwww::SOCKETS[(the_uuid)].instance_variable_set(:@display, the_display) } if GxG::SERVICES[:www][:manifests][(the_session['session_id'])] connector = GxG::SERVICES[:www][:manifests][(the_session['session_id'])].connector_get(the_display) if connector connector.set_socket_uuid(the_uuid) else raise Exception, "Connector Not Found." end else raise Exception, "Manifest Not Found For Session." end puts "Websocket Attached: #{the_uuid.inspect}" response = [200, {"content-type" => "application/json"}, {:result => true}.to_json()] break end end # Review : TODO: more follow up on internal socket messaging system # when :close if the_display if the_manifest.display_exist?(the_display) the_manifest.display_set(the_display, :available) unless the_manifest.connector_get(the_display).remote_closed? the_manifest.connector_get(the_display).close_remote end end response = [200, {"content-type" => "application/json"}, {:result => true}.to_json()] break end when :introduction # puts "Introduction Display: #{the_display.inspect}" connection_uuid = nil remote_uuid = parameters.to_s.to_sym unless ::GxG::valid_uuid?(remote_uuid.to_s) raise "Invalid Remote ID." end # xxx unless the_display # Expire old Displays and set to :available the_manifest.display_keys.each do |display_key| if the_manifest.timer_get(display_key).is_a?(::Numeric) if Time.now.to_f > the_manifest.timer_get(display_key) the_manifest.display_set(display_key, :available) connector = the_manifest.connector_get(display_key) if connector unless connector.remote_closed? connector.close_remote end end end else the_manifest.timer_set(display_key, ::Chronic::parse("in 3 minutes").to_f) the_manifest.display_set(display_key, :available) connector = the_manifest.connector_get(display_key) if connector unless connector.remote_closed? connector.close_remote end end end end # Find available Display the_manifest.display_keys.each do |display_key| if the_manifest.display_get(display_key) == :available the_manifest.display_set(display_key, :in_use) the_manifest.timer_set(display_key, ::Chronic::parse("in 3 minutes").to_f) connector = the_manifest.connector_get(display_key) if connector # re-open Connector connector.open_remote(remote_uuid) else # puts "Connector Created." # create Connector connector_settings = { :display => display_key, :session_id => the_session['session_id'], :remote_uuid => remote_uuid, :credential => the_manifest.credential_get(), :credential_status => :running } # the_manifest.connector_set(display_key, ::GxGwww::Connector.new(connector_settings)) # Review: what are all the session-wide manifest states possible? the_manifest.state_set(:running) end the_display = display_key connection_uuid = connector.uuid() break end end # Add Display if needed unless the_display the_display = ("/display/" << the_manifest.display_count.to_s) the_manifest.display_set(the_display, :in_use) the_manifest.timer_set(the_display, ::Chronic::parse("in 3 minutes").to_f) connector_settings = { :display => the_display, :session_id => the_session['session_id'], :remote_uuid => remote_uuid, :credential => the_manifest.credential_get(), :credential_status => :running } connector = ::GxGwww::Connector.new(connector_settings) # puts "Connector Created - 2nd Portion." the_manifest.connector_set(the_display, connector) connection_uuid = connector.uuid() end end unless connection_uuid connector = the_manifest.connector_get(the_display) if connector connection_uuid = connector.uuid() end end # if the_manifest.credential_get() == :"00000000-0000-4000-0000-000000000000" current_status = "uncredentialed" else current_status = "credentialed" end # response = [200, {"content-type" => "application/json"}, {:result => "OK", :csrf => the_session["csrf"], :display => the_display, :relative_url => GxG::SERVICES[:www].configuration[:relative_url], :remote_uuid => connection_uuid.to_s, :status => current_status}.to_json()] # break when :downgrade_credential the_manifest.state_set(:exiting) the_manifest.display_keys.each do |display_key| if the_manifest.connector_get(display_key) the_manifest.connector_get(display_key).update_credential_status(the_manifest.state_get()) end end # # manifest[:connectors][(the_display)].update_credential_status(status[:credential]) # check if the connectors are 'exitready' if the_manifest.state_get() == :exiting readyflag = true the_manifest.display_keys.each do |display_key| if the_manifest.connector_get(display_key) unless the_manifest.connector_get(display_key).exitready? readyflag = false end end end if readyflag == true the_manifest.credential_set(:"00000000-0000-4000-0000-000000000000") the_manifest.state_set(:uncredentialed) the_manifest.display_keys.each do |display_key| connector = the_manifest.connector_get(display_key) if connector connector.update_credential(:"00000000-0000-4000-0000-000000000000") connector.update_credential_status(the_manifest.state_get()) end end end end # response = [200, {"content-type" => "application/json"}, {:status => "uncredentialed"}.to_json()] # break when :update_credential response = [404, {"content-type" => "application/json"}, {:status => "Not Found"}.to_json()] if parameters.base64? parameters = parameters.decode64 end parameters = parameters.decrypt(the_session["csrf"].to_s) if parameters.json? parameters = ::JSON::parse(parameters, {:symbolize_names => true}) new_credential = GxG::DB[:authority].user_credential(parameters[:user].to_s, parameters[:password].to_s) if new_credential.is_any?(::String, ::Symbol) the_manifest.credential_set(new_credential.to_s.to_sym) # update connector credentials the_manifest.display_keys.each do |display_key| the_connector = the_manifest.connector_get(display_key) if the_connector the_connector.update_credential(new_credential.to_s.to_sym) end end response = [200, {"content-type" => "application/json"}, {:status => "credentialed"}.to_json()] # break else # Failed login attempt log_warn("Failed login attempt with: #{parameters.inspect}") end else # Hack attempt maybe? Malformed certainly. log_warn("Malformed payload on login attempt with: #{parameters.inspect}") end # else # Review : dispatch the_operation (operations not baked-in toward session/sockets) to the connector if the_display the_manifest.timer_set(the_display, ::Chronic::parse("in 3 minutes").to_f) connector = the_manifest.connector_get(the_display) if connector if connector.respond_to?(the_operation) if parameters response = connector.send(the_operation, parameters) else response = connector.send(the_operation) end end end end # end # end the_operation case end end # end .xhr? else # TODO : check for websocket here and place on the right display object/connector. # Standard request # Strip BASEURL if present if GxG::SERVICES[:www].configuration[:relative_url].size > 0 request_path = the_request.path[((GxG::SERVICES[:www].configuration[:relative_url].size)..-1)] else request_path = the_request.path end # # puts "Got Request Path: #{request_path}" # ???? case the_method when :get, :put if request_path.to_s.downcase[(0..3)].include?("/api") # Filter for API controller match the_controller = nil ::GxGwww::API_THREAD_SAFETY.synchronize { ::GxGwww::API.each_pair do |the_path, the_handler| if request_path.to_s[(4..-1)] == the_path.to_s the_controller = the_handler break end end } if the_controller response = the_controller.process(the_method, the_request, the_session) else response = [404, {"content-type" => "application/text"}, "Endpoint Not Found"] end else if ["", "/", "/index"].include?(request_path) || ::GxG::SERVICES[:core][:resources].exist?("/Public/www/content/pages#{request_path}") # Send bootstrap html page and wait for xhr requests # content = GxGwww::CACHE.fetch("/page.html",the_session[:credential]) response[0] = 200 # response[1]["content-type"] = content[:content_type] response[1]["content-type"] = "text/html" # response[2] = content[:data] response[2] = self.default_page_content() else # Asset :get request if ::GxG::SERVICES[:core][:resources].exist?(("/Public/www" << request_path)) content = GxGwww::CACHE.fetch(("/Public/www" << request_path), (the_session[:credential] || :"00000000-0000-4000-0000-000000000000"), true) if content response[0] = 200 response[1]["content-type"] = content[:content_type] response[1]["X-Content-Type-Options"] = "nosniff" response[2] = content[:data] else log_warn "Failed to fetch: #{request_path}" end end end end when :post # if the_request.path.include?("/display/") # if the_request.params["operation"] == "close" # puts "Close Attempt on #{the_request.path}" # end # end when :delete end end rescue Exception => the_error log_error({:error => the_error, :parameters => {:method => the_method, :request => the_request, :session => the_session}}) response = [500, {"content-type" => "application/text"}, "Error"] end # response end # def default_page_content() result = "" # result << "\n" result << "\t\n" result << "\t\t\n" result << "\t\t\n" result << "\t\t\n" # result << ("\t\t\n") result << ("\t\t\n") # result << ("\t\t\n") result << ("\t\t\n") result << "\t\n" result << "\t\n" result << ("\t\t\n") result << ("\t\t\n") result << ("\t\t\n") result << ("\t\t\n") result << ("\t\t\n") result << ("\t\t\n") result << ("\t\t\n") result << ("\t\t\n") result << ("\t\t\n") result << ("\t\t\n") result << ("\t\t\n") result << ("\t\t\n") result << "\t\n" result << "" # result end # end # class Connector # def initialize(settings={}) @uuid = ::GxG::uuid_generate().to_sym @remote_uuid = settings[:remote_uuid].to_s.to_sym @credential = settings[:credential] @credential_status = settings[:credential_status] @active = true @application_states = [] @display = settings[:display] @session_id = settings[:session_id] @socket = nil # ???? self end # def socket_uuid() @socket end # def uuid() @uuid end def update_credential(the_credential=nil) if ::GxG::valid_uuid?(the_credential.to_s) @credential = the_credential.to_s.to_sym end true end # def update_credential_status(credential_status) @credential_status = credential_status end # def exitready?() # When all applications acknowledge exiting status and set 'exitready' THEN downgrade the credential and return true. exitready = true @application_states.each do |the_record| unless the_record[:status] == 'exitready' exitready = false break end end exitready end # def inspect() " #{@uuid.inspect}, :remote_uuid => #{@remote_uuid.inspect}>" end # def open_remote(remote_uuid=nil) if remote_uuid @remote_uuid = remote_uuid.to_s.to_sym @active = true end end # def close_remote() @remote_uuid = nil @active = false end # def remote_closed? if @remote_uuid false else true end end # def close() close_remote end # def closed? ! @active end # --------------------------------------------- # Callable Toolbox def set_socket_uuid(the_uuid) @socket = the_uuid end # def admin_get_roles() if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else if GxG::DB[:authority].role_member?(GxG::DB[:authority][:system_credentials][:administrators], @credential) response = [200, {"content-type" => "application/json"}, ({:result => GxG::DB[:authority].role_manifest()}).to_json] else # err - Hack attempt ?? response = [404, {"content-type" => "application/json"}, ({:result => false, :error => "Not Found.", :parameters => false}).to_json()] end end response end # def call_event(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else the_service = ::GxG::SERVICES[(details[:service].to_s.downcase.to_sym)] if the_service the_result = the_service.call_event(details[:op_frame], @credential) if the_result[:error] response = [500, {"content-type" => "application/json"}, ({:result => false, :error => the_result[:error], :parameters => false}).to_json()] else response = [200, {"content-type" => "application/json"}, (the_result.to_json)] end else # err - service not found response = [404, {"content-type" => "application/json"}, ({:result => false, :error => "Service #{details[:service].to_s} Not Found.", :parameters => false}).to_json()] end end response end # def upload_file(details={}) response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Unknown Error."}).to_json()] # {:temp_file => temp_file, :file_name => file_name, :destination => destination} begin temp_dir = "/Temporary/#{::GxG::uuid_generate().to_s}" download_path = "#{temp_dir + "/" + (details[:file_name] || "Untitled").to_s}" # if details[:destination].to_s[0..4] == "/User" if @credential == :"00000000-0000-4000-0000-000000000000" details[:destination] = ("/Public/www/" << details[:destination].to_s[5..-1]).gsub("//","/") else details[:destination] = ("/Users/#{@credential.to_s}/" << details[:destination].to_s[5..-1]).gsub("//","/") unless GxG::SERVICES[:core][:resources].home_mounted?(@credential) GxG::SERVICES[:core][:resources].home_mount(@credential) end end else details[:destination] = ("/Public/www/" << details[:destination].to_s).gsub("//","/") end if GxG::SERVICES[:core][:resources].permissions(details[:destination], @credential)[:write] == true # final_path = "#{details[:destination].to_s + "/" + (details[:file_name] || "Untitled").to_s}".gsub("//","/") GxG::SERVICES[:core][:resources].create_directory(temp_dir, ::GxG::DB[:administrator]) GxG::SERVICES[:core][:resources].create(download_path, ::GxG::DB[:administrator]) handle = GxG::SERVICES[:core][:resources].open_writable(download_path, ::GxG::DB[:administrator]) handle[:resource].write details[:temp_file].read GxG::SERVICES[:core][:resources].close(handle[:token]) GxG::SERVICES[:core][:resources].move(download_path, ::GxG::DB[:administrator], final_path) GxG::SERVICES[:core][:resources].set_permissions(final_path, @credential, {:execute => false, :rename => true, :move => true, :destroy => true, :create => true, :write => true, :read=>true}) GxG::SERVICES[:core][:resources].destroy(temp_dir, ::GxG::DB[:administrator]) # response = [200, {"content-type" => "application/json"}, ({:result => true}).to_json()] else response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "You lack permissions to write."}).to_json()] end rescue Exception => the_error response = [500, {"content-type" => "application/json"}, ({:result => false, :error => the_error.to_s}).to_json()] end response end # def download_file(details={}) # {:path => "/path/to/object"} response = [404, {"content-type" => "application/json"}, ({:result => false, :error => "Object Not Found."}).to_json()] puts "Download Got: #{details.inspect}" begin # temp_dir = "/Temporary/#{::GxG::uuid_generate().to_s}" final_path = "#{temp_dir}/#{File.basename(details[:path])}" # if details[:path].to_s[0..4] == "/User" if @credential == :"00000000-0000-4000-0000-000000000000" details[:path] = ("/Public/www/" << details[:path].to_s[5..-1]).gsub("//","/") else details[:path] = ("/Users/#{@credential.to_s}/" << details[:path].to_s[5..-1]).gsub("//","/") unless GxG::SERVICES[:core][:resources].home_mounted?(@credential) GxG::SERVICES[:core][:resources].home_mount(@credential) end end else details[:path] = ("/Public/www/" << details[:path].to_s).gsub("//","/") end # puts "Download Path: #{details.inspect}" # temp_file = "#{temp_dir}/#{File.basename((details[:path] || 'Untitled').to_s)}" if GxG::SERVICES[:core][:resources].exist?(details[:path]) profile = GxG::SERVICES[:core][:resources].profile(details[:path], @credential) if profile if profile[:permissions][:effective][:read] == true GxG::SERVICES[:core][:resources].create_directory(temp_dir, ::GxG::DB[:administrator]) if GxG::SERVICES[:core][:resources].copy(details[:path], ::GxG::DB[:administrator], final_path) cache_profile = (GxG::SERVICES[:core][:resources].entries(temp_dir, ::GxG::DB[:administrator]) || []).first if cache_profile handle = GxG::SERVICES[:core][:resources].open((temp_dir + "/" + cache_profile[:title]), ::GxG::DB[:administrator]) if handle # download_path = handle[:resource].path() response = [200, {"content-type" => "application/json"}, ({:result => {:file_name => cache_profile[:title], :file_data => handle[:resource].read.encode64}}).to_json()] GxG::SERVICES[:core][:resources].close(handle[:token]) GxG::SERVICES[:core][:resources].destroy(temp_dir, ::GxG::DB[:administrator]) # response = [-255, {"content-type" => "application/hash"}, {:result => {:file => download_path, :vfs_dir => temp_dir}}] else raise "Failed to get cache profile." end else raise "Failed to get cache profile." end else response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Failed to cache file."}).to_json()] end else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "You don't have read access."}).to_json()] end else raise "Failed to get profile." end # end rescue Exception => the_error log_error({:error => the_error}) response = [500, {"content-type" => "application/json"}, ({:result => false, :error => the_error.to_s}).to_json()] end # response end # def vfs_mkfile(details={}) # Review : find correct cooresponding return codes for errors. if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else if details.is_a?(::Hash) the_path = (GxG::SERVICES[:core][:resources].home_path(@credential).to_s + "/" + details[:path].to_s).gsub("//","/") if GxG::SERVICES[:core][:resources].exist?(the_path) response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Already Exists.", :parameters => details}).to_json()] else dir_profile = GxG::SERVICES[:core][:resources].profile(::File.dirname(the_path),@credential) if dir_profile.is_a?(::Hash) if dir_profile[:permissions][:effective][:create] == true if details[:format] result = GxG::SERVICES[:core][:resources].create(the_path, @credential, {:format => details[:format]}) else result = GxG::SERVICES[:core][:resources].create(the_path, @credential) end response = [200, {"content-type" => "application/json"}, result.to_json()] else # err - Hack attempt ?? (user app SHOULD pre-screen!) response = [404, {"content-type" => "application/json"}, ({:result => false, :error => "Not Found.", :parameters => false}).to_json()] end else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Malformed Profile.", :parameters => details}).to_json()] end end # else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Malformed Parameter.", :parameters => details}).to_json()] end end response end # def vfs_mkdir(details={}) # Review : find correct cooresponding return codes for errors. if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else if details.is_a?(::Hash) the_path = (GxG::SERVICES[:core][:resources].home_path(@credential).to_s + "/" + details[:path].to_s).gsub("//","/") if GxG::SERVICES[:core][:resources].exist?(the_path) response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Already Exists.", :parameters => details}).to_json()] else dir_profile = GxG::SERVICES[:core][:resources].profile(::File.dirname(the_path),@credential) if dir_profile.is_a?(::Hash) if dir_profile[:permissions][:effective][:create] == true response = [200, {"content-type" => "application/json"}, GxG::SERVICES[:core][:resources].create_directory(the_path, @credential).to_json()] else # err - Hack attempt ?? (user app SHOULD pre-screen!) response = [404, {"content-type" => "application/json"}, ({:result => false, :error => "Not Found.", :parameters => false}).to_json()] end else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Malformed Profile.", :parameters => details}).to_json()] end end # else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Malformed Parameter.", :parameters => details}).to_json()] end end response end # def vfs_rename(details={}) # Review : find correct cooresponding return codes for errors. if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else if details.is_a?(::Hash) error_response = nil unless details[:path].to_s.size > 0 error_response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Path.", :parameters => details}).to_json()] end unless details[:new_name].to_s.size > 0 error_response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "New Name Not Specified.", :parameters => details}).to_json()] end if error_response response = error_response else prefix = GxG::SERVICES[:core][:resources].home_path(@credential).to_s container = (prefix + "/" + File.dirname(details[:path].to_s)).gsub("//","/") the_path = (prefix + "/" + details[:path].to_s).gsub("//","/") if GxG::SERVICES[:core][:resources].exist?((container + "/" + details[:new_name].to_s).gsub("//","/")) response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Already Exists.", :parameters => details}).to_json()] else the_profile = GxG::SERVICES[:core][:resources].profile(the_path,@credential) if the_profile.is_a?(::Hash) if the_profile[:permissions][:effective][:rename] == true result = GxG::SERVICES[:core][:resources].rename(the_path, @credential, details[:new_name].to_s) if result[:result] == true response = [200, {"content-type" => "application/json"}, GxG::SERVICES[:core][:resources].rename(the_path, @credential, details[:new_name].to_s).to_json()] # else response = [403, {"content-type" => "application/json"}, result.to_json()] end else # err - Hack attempt ?? (user app SHOULD pre-screen!) response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Permission Error.", :parameters => false}).to_json()] end else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Malformed Input.", :parameters => details}).to_json()] end end # end # else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Malformed Parameter.", :parameters => details}).to_json()] end end response end # def vfs_destroy(detials={}) # Review : find correct cooresponding return codes for errors. if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else if details.is_a?(::Hash) the_path = (GxG::SERVICES[:core][:resources].home_path(@credential).to_s + "/" + details[:path].to_s).gsub("//","/") if GxG::SERVICES[:core][:resources].exist?(the_path) the_profile = GxG::SERVICES[:core][:resources].profile(the_path, @credential) if the_profile.is_a?(::Hash) if the_profile[:permissions][:effective][:destroy] == true result = GxG::SERVICES[:core][:resources].destroy(the_path, @credential) if result[:result] == true response = [200, {"content-type" => "application/json"}, result.to_json()] else response = [403, {"content-type" => "application/json"}, result.to_json()] end else # err - Hack attempt ?? (user app SHOULD pre-screen!) response = [404, {"content-type" => "application/json"}, ({:result => false, :error => "Not Found.", :parameters => false}).to_json()] end else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Malformed Profile.", :parameters => details}).to_json()] end else response = [404, {"content-type" => "application/json"}, ({:result => false, :error => "Not Found.", :parameters => details}).to_json()] end # else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Malformed Parameter.", :parameters => details}).to_json()] end end response end # def vfs_copy(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else error_response = nil unless details[:source].to_s.size > 0 error_response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Source Path.", :parameters => details}).to_json()] end unless details[:destination].to_s.size > 0 error_response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Destination Path.", :parameters => details}).to_json()] end if error_response response = error_response else source_path = (GxG::SERVICES[:core][:resources].home_path(@credential).to_s + "/" + details[:source].to_s).gsub("//","/") destination_path = (GxG::SERVICES[:core][:resources].home_path(@credential).to_s + "/" + details[:destination].to_s).gsub("//","/") result = GxG::SERVICES[:core][:resources].copy(source_path, @credential, destination_path) if result[:result] == true response = [200, {"content-type" => "application/json"}, result.to_json()] else response = [403, {"content-type" => "application/json"}, result.to_json()] end end end response end # def vfs_move(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else error_response = nil unless details[:source].to_s.size > 0 error_response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Source Path.", :parameters => details}).to_json()] end unless details[:destination].to_s.size > 0 error_response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Destination Path.", :parameters => details}).to_json()] end if error_response response = error_response else source_path = (GxG::SERVICES[:core][:resources].home_path(@credential).to_s + "/" + details[:source].to_s).gsub("//","/") destination_path = (GxG::SERVICES[:core][:resources].home_path(@credential).to_s + "/" + details[:destination].to_s).gsub("//","/") result = GxG::SERVICES[:core][:resources].copy(source_path, @credential, destination_path) if result[:result] == true response = [200, {"content-type" => "application/json"}, result.to_json()] else response = [403, {"content-type" => "application/json"}, result.to_json()] end end end response end # def set_permissions(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else # Review : at this point, since home_path is by credential class - open to anyone to alter permissions in their respective areas. error_response = nil unless details[:revocations].is_a?(::Array) error_response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Source Path.", :parameters => details}).to_json()] end unless details[:alterations].is_a?(::Array) error_response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Destination Path.", :parameters => details}).to_json()] end if error_response response = error_response else the_path = (GxG::SERVICES[:core][:resources].home_path(@credential).to_s + "/" + details[:path].to_s).gsub("//","/") if GxG::SERVICES[:core][:resources].exist?(the_path) (details[:revocations] || []).each do |the_credential| # credentials whos permissions are to be revoked. GxG::SERVICES[:core][:resources].revoke_permissions(the_path, the_credential.to_s.to_sym) end (details[:alterations] || []).each do |the_record| GxG::SERVICES[:core][:resources].set_permissions(the_path, the_record[:credential], the_record[:permissions]) end response = [200, {"content-type" => "application/json"}, {:result => true}.to_json()] else response = [404, {"content-type" => "application/json"}, ({:result => false, :error => "Not Found.", :parameters => details}).to_json()] end end end response end # def get_format(details={}) importation_record = {:formats => {}, :records => []} if details.is_a?(::Array) format_list = [] details.each do |the_criteria| if ::GxG::valid_uuid?(the_criteria) ::GxG::DB[:roles][:formats].format_list({:uuid => the_criteria.to_s.to_sym}).each do |the_format| format_list << the_format end else ::GxG::DB[:roles][:formats].format_list({:ufs => the_criteria.to_s}).each do |the_format| format_list << the_format end end end else format_list = ::GxG::DB[:roles][:formats].format_list(details) end format_list.each do |the_format_header| format_record = ::GxG::DB[:roles][:formats].format_load({:uuid => the_format_header[:uuid]}) format_record[:content] = format_record[:content].gxg_export importation_record[:formats][(the_format_header[:uuid])] = format_record end [200, {"content-type" => "application/json"}, {:result => importation_record}.to_json()] end # def put_format(details={}) if GxG::DB[:authority].role_member?(GxG::DB[:authority][:system_credentials][:administrators], @credential) || GxG::DB[:authority].role_member?(GxG::DB[:authority][:system_credentials][:developers], @credential) result = ::GxG::DB[:roles][:formats].sync_import(GxG::DB[:administrator],details) [200, {"content-type" => "application/json"}, {:result => result}.to_json()] else [403, {"content-type" => "application/json"}, ({:result => false, :error => "You do not have sufficient permissions to do this.", :parameters => details}).to_json()] end end # def get_object(details={}) if details[:path].to_s.size > 0 if details[:path].to_s.include?("/Public/www") [200, {"content-type" => "application/json"}, {:result => (((GxGwww::CACHE.fetch(details[:path].to_s, @credential, true)) || {})[:data] || "")}.to_json()] else if details[:path].to_s[0..4] == "/User" the_path = (GxG::SERVICES[:core][:resources].home_path(@credential).to_s + "/" + details[:path].to_s[5..-1]).gsub("//","/") [200, {"content-type" => "application/json"}, {:result => (((GxGwww::CACHE.fetch(the_path, @credential, false)) || {})[:data] || "")}.to_json()] else if details[:path].to_s[0..6] == "/Shared" # Review : Expansion --> work out a scheme for shared group folders/files/db-obj (WebDAV mounts??) # [403, {"content-type" => "application/json"}, ({:result => false, :error => "Not Yet Implemented.", :parameters => details}).to_json()] the_path = ("/Users/Shared/" + details[:path].to_s[7..-1]).gsub("//","/") [200, {"content-type" => "application/json"}, {:result => (((GxGwww::CACHE.fetch(the_path, @credential, false)) || {})[:data] || "")}.to_json()] else [200, {"content-type" => "application/json"}, {:result => (((GxGwww::CACHE.fetch(details[:path].to_s, @credential, false)) || {})[:data] || "")}.to_json()] end end end else if GxG::valid_uuid?(details[:uuid].to_s) [200, {"content-type" => "application/json"}, {:result => (((GxGwww::CACHE.fetch_by_uuid(details[:uuid].to_s.to_sym, @credential, false)) || {})[:data] || "")}.to_json()] else [403, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Specifier.", :parameters => details}).to_json()] end end end # def put_object(details={}) response = nil if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else if details[:object].is_a?(::Hash) database = nil the_object = ::GxG::DB[:roles][:data].retrieve_by_uuid(details[:uuid].to_s.to_sym, ::GxG::DB[:administrator]) if the_object database = the_object.db_address()[:database] the_object.deactivate if details[:path].to_s.size > 0 handle = ::GxG::SERVICES[:core][:resources].open(details[:path].to_s, ::GxG::DB[:administrator]) if handle.is_a?(::Hash) database = handle[:resource].db_address()[:database] ::GxG::SERVICES[:core][:resources].close(handle[:token]) else response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Error finding object database.", :parameters => false}).to_json()] end end else # needs to be created if details[:path].to_s.size > 0 status = ::GxG::SERVICES[:core][:resources].create(details[:path].to_s, @credential, {:with_uuid => details[:uuid].to_s.to_sym}) unless status[:result] == true response = [500, {"content-type" => "application/json"}, ({:result => false, :error => status[:error], :parameters => false}).to_json()] end unless response handle = ::GxG::SERVICES[:core][:resources].open(details[:path].to_s, ::GxG::DB[:administrator]) if handle.is_a?(::Hash) database = handle[:resource].db_address()[:database] ::GxG::SERVICES[:core][:resources].close(handle[:token]) else response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Error finding object database.", :parameters => false}).to_json()] end end else database = ::GxG::DB[:roles][:data] end end if database.is_a?(::GxG::Database::Database) status = database.sync_import(@credential, details[:object]) if status == true response = [200, {"content-type" => "application/json"}, {:result => true}.to_json()] GxGwww::CACHE.flush_cache_item(details[:uuid].to_s) if details[:path].to_s.size > 0 GxGwww::CACHE.flush_cache_item(details[:path].to_s) end else response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Error writing data.", :parameters => false}).to_json()] end else response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Unable to find a suitable database.", :parameters => false}).to_json()] end else if details[:object].is_a?(::String) if details[:path].to_s.size > 0 unless ::GxG::SERVICES[:core][:resources].exist?(details[:path].to_s) status = ::GxG::SERVICES[:core][:resources].create(details[:path].to_s, @credential) unless status[:result] == true response = [500, {"content-type" => "application/json"}, ({:result => false, :error => status[:error], :parameters => false}).to_json()] end end unless response handle = ::GxG::SERVICES[:core][:resources].open_writable(details[:path].to_s, @credential) if handle.is_a?(::Hash) handle[:resource].rewind handle[:resource].write(details[:object].decode64) ::GxG::SERVICES[:core][:resources].close(handle[:token]) response = [200, {"content-type" => "application/json"}, {:result => true}.to_json()] else response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Unable to open file.", :parameters => false}).to_json()] end end else response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "You MUST specify a valid path.", :parameters => false}).to_json()] end else response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Object Type.", :parameters => false}).to_json()] end end end response end # def get_permissions(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else if details[:path].to_s.size > 0 the_path = (GxG::SERVICES[:core][:resources].home_path(@credential).to_s + "/" + details[:path].to_s).gsub("//","/") result = [] if GxG::SERVICES[:core][:resources].exist?(the_path) result = GxG::SERVICES[:core][:resources].get_permissions(the_path, @credential) end response = [200, {"content-type" => "application/json"}, {:result => result.to_json.encode64}.to_json()] else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Path.", :parameters => details}).to_json()] end end response end # def search_database(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else search_result = {} if details[:criteria].is_a?(::Hash) details[:criteria].keys.each do |the_role| if ::GxG::DB[:roles].keys.include?(the_role) # Fix for string/symbol hoo-hah: if details[:criteria][(the_role)][:select].is_a?(::Array) new_selector = [] details[:criteria][(the_role)][:select].each do |the_selector| new_selector << the_selector.to_s.to_sym end details[:criteria][(the_role)][:select] = new_selector end search_result[(the_role)] = ::GxG::DB[:roles][(the_role)].search_database(@credential, details[:criteria][(the_role)]) end end response = [200, {"content-type" => "application/json"}, {:result => search_result.to_json.encode64}.to_json()] else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Criteria.", :parameters => details}).to_json()] end end response end # def search_pull(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else importation_record = {:formats => {}, :records => []} pull_list = [] if details[:criteria].is_a?(::Hash) details[:criteria].keys.each do |the_role| if ::GxG::DB[:roles].keys.include?(the_role) # Fix for string/symbol hoo-hah: if details[:criteria][(the_role)][:select].is_a?(::Array) new_selector = [] details[:criteria][(the_role)][:select].each do |the_selector| new_selector << the_selector.to_s.to_sym end details[:criteria][(the_role)][:select] = new_selector end (::GxG::DB[:roles][(the_role)].search_database(@credential, details[:criteria][(the_role)]).map {|entry| entry[:uuid]}).each do |the_uuid| unless pull_list.include?(the_uuid) pull_list << the_uuid end end end end # pull_list.each do |the_uuid| the_record = ::GxG::DB[:roles][:data].retrieve_by_uuid(the_uuid, @credential) if the_record.is_a?(::GxG::Database::PersistedHash) the_record.search do |value, selector, container| format_uuid = nil if value.is_a?(::GxG::Database::PersistedHash) if value.format format_uuid = value.format end end if value.is_a?(::GxG::Database::PersistedArray) if value.constraint format_uuid = value.constraint end end if format_uuid unless importation_record[:formats].keys.include?(format_uuid) format_record = ::GxG::DB[:roles][:formats].format_load({:uuid => format_uuid}) if format_record format_record[:content] = format_record[:content].gxg_export importation_record[:formats][(format_uuid)] = format_record end end end end importation_record[:records] << the_record.export end end # response = [200, {"content-type" => "application/json"}, {:result => importation_record}.to_json()] else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Criteria.", :parameters => details}).to_json()] end end response end # def entries(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else if details[:path].to_s.size > 0 the_path = (GxG::SERVICES[:core][:resources].home_path(@credential).to_s + "/" + details[:path].to_s).gsub("//","/") if GxG::SERVICES[:core][:resources].exist?(the_path) response = [200, {"content-type" => "application/json"}, {:result => GxG::SERVICES[:core][:resources].entries(the_path, @credential).to_json.encode64}.to_json()] else response = [404, {"content-type" => "application/json"}, ({:result => false, :error => "Not Found.", :parameters => details}).to_json()] end else response = [403, {"content-type" => "application/json"}, ({:result => false, :error => "Invalid Path.", :parameters => details}).to_json()] end end response end # def destroy_object(details={}) # details[:uuid] : specifies uuid of db object to destroy. if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else success = false GxG::DB[:roles].keys.each do |the_role| the_permissions = GxG::DB[:roles][(the_role)].effective_uuid_permission(details[:uuid].to_s.to_sym, @credential) if the_permissions.is_a?(::Hash) if the_permissions[:destroy] == true if GxG::DB[:roles][(the_role)].destroy_by_uuid(@credential, details[:uuid].to_s.to_sym) == true unless success == true success = true end end end end end response = [200, {"content-type" => "application/json"}, {:result => success}.to_json()] end response end # def get_library(details={}) # Supply: details => {:library => "lib-name", :manifest => true/false, :dependencies => true/false, :minimum => 0.0, :maximum => 0.0, :loaded => [...]} # Grab library by name and version params. optionally deliver full stack of in-order load deps. minimum = details[:minimum] || 0.0 maximum = details[:maximum] marshalled = [] if details[:loaded].is_a?(::Array) details[:loaded].each do |the_uuid| marshalled << the_uuid.to_s.to_sym end end the_lib = nil the_list = [] manifest = GxG::DB[:roles][:software].uuid_list(@credential, {:select => [:uuid, :version], :title => (details[:library]), :order => {:descending => :version}}) manifest.each do |the_record| if maximum if ((minimum)..(maximum)).include?(the_record[:version]) the_lib = the_record break end else if the_record[:version] >= minimum the_lib = the_record break end end end if the_lib if details[:dependencies] == true # calculate dependencies (in proper load order) dep_template = {:library => "", :uuid => nil, :version => 0.0, :minimum => 0.0, :maximum => nil, :dependencies => []} deps = {} the_base_lib = GxG::DB[:roles][:software].retrieve_by_uuid(the_lib[:uuid].to_s.to_sym,@credential) build_queue = [(the_base_lib)] while build_queue.size > 0 do entry = build_queue.shift if entry unless deps[(entry.uuid)] new_dep = dep_template.clone new_dep[:library] = entry.title new_dep[:uuid] = entry.uuid new_dep[:version] = entry.version deps[(entry.uuid)] = new_dep end # if entry[:requirements].is_a?(::GxG::Database::PersistedArray) entry[:requirements].each do |the_dep| # libarary requirement format: {:library => "", :type => "", :minimum => 0.0, :maximum => nil} new_dep = nil # new_list = GxG::DB[:roles][:software].uuid_list(@credential, {:select => [:uuid, :version], :title => (the_dep[:library].to_s), :order => {:descending => :version}}) new_list.each do |the_item| if the_dep[:maximum] if ((the_dep[:minimum])..(the_dep[:maximum])).include?(the_item[:version]) new_dep = dep_template.clone new_dep[:library] = the_dep[:library].to_s new_dep[:uuid] = the_item[:uuid] new_dep[:version] = the_item[:version] new_dep[:minimum] = the_dep[:minimum].to_f new_dep[:maximum] = the_dep[:maximum].to_f break end else if the_item[:version] >= the_dep[:minimum] new_dep = dep_template.clone new_dep[:library] = the_dep[:library].to_s new_dep[:uuid] = the_item[:uuid] new_dep[:version] = the_item[:version] new_dep[:minimum] = the_dep[:minimum].to_f break end end end # if new_dep deps[(entry.uuid)][:dependencies] << new_dep build_queue << (GxG::DB[:roles][:software].retrieve_by_uuid(new_dep[:uuid].to_s.to_sym,@credential)) end end end # entry.deactivate end end deps_pool = (deps.sort_by {|key,value| value[:dependencies].size}).to_h deps_pool.each_pair do |the_uuid,the_record| the_record[:dependencies].each do |the_dep| unless marshalled.include?(the_dep[:uuid]) if details[:manifest] == true the_list << {:library => the_record[:library], :uuid => the_dep[:uuid], :version => the_record[:version]} else data = GxGwww::CACHE.fetch(the_dep[:uuid].to_s,@credential) the_list << {:library => the_record[:library], :uuid => the_dep[:uuid], :version => the_record[:version], :data => data[:data]} end marshalled << the_uuid end end unless marshalled.include?(the_uuid) if details[:manifest] == true the_list << {:library => the_record[:library], :uuid => the_uuid, :version => the_record[:version]} else data = GxGwww::CACHE.fetch(the_uuid.to_s,@credential) the_list << {:library => the_record[:library], :uuid => the_uuid, :version => the_record[:version], :data => data[:data]} end marshalled << the_uuid end end else # pull and append library object record to content[:data] data = GxGwww::CACHE.fetch(the_lib[:uuid].to_s,@credential) the_list << {:library => details[:library], :version => the_lib[:version], :data => data} end end # [200, {"content-type" => "application/json"}, {:result => the_list.to_json.encode64}.to_json()] end # def application_menu() if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else results = [] app_menu = (GxGwww::Applications::MENU || []) # entry: {:location => "", :application_icon => "", :application_name => "", :credentialed => false, :unique => true :category => ""} # ... app_menu.each do |entry| begin profile = ::GxG::VFS.profile(("/Public/www" << entry[:location].to_s), {:with_credential => @credential, :follow_symlinks => true}) if profile.is_a?(::Hash) if profile[:permissions][:effective][:read] == true results << entry end end rescue Exception => the_error log_warn("Cannot access application: #{"/Public/www" << entry[:location].to_s}") end end response = [200, {"content-type" => "application/json"}, {:result => results.to_json.encode64}.to_json()] end response end # def application_list() if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else results = [] @application_states.each do |the_app| results << {:application => the_app[:application].to_s, :credentialed => the_app[:credentialed], :unique => the_app[:unique], :location => the_app[:location].to_s} end response = [200, {"content-type" => "application/json"}, {:result => results.to_json.encode64}.to_json()] end response end # def application_close(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else found = nil @application_states.each_with_index do |the_app, the_index| if the_app[:application] == details[:application] found = the_index break end end if found record = @application_states.delete_at(found) response = [200, {"content-type" => "application/json"}, {:result => true}.to_json()] else response = [200, {"content-type" => "application/json"}, {:result => false}.to_json()] end end response end # def application_open(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else credentialed = false unique = false unless details[:path] app_menu = (GxGwww::Applications::MENU || []) # entry: {:location => "", :application_icon => "", :application_name => "", :credentialed => false, :unique => true :category => ""} # ... app_menu.each do |the_entry| if details[:name] == File.basename(the_entry[:location]) details[:path] = the_entry[:location] break end end end begin # Review : switch over to new resource accessor?? # GxG::SERVICES[:core][:resources].open(the_path, @credential) # token format : {:token => the_token, :path => the_path, :resource => the_resource} # the_object = GxG::VFS.open("/Public/www" << details[:path].to_s) the_object_token = GxG::SERVICES[:core][:resources].open(("/Public/www" << details[:path].to_s), @credential) if the_object_token the_object = the_object_token[:resource] else the_object = nil end rescue the_object_token = nil the_object = nil end if the_object.is_a?(::GxG::Database::PersistedHash) # source_uuid = the_object.uuid the_options = the_object[:options] if the_options[:credentialed] credentialed = the_options[:credentialed] end if the_options[:unique] unique = the_options[:unique] end app_uuid = GxG::uuid_generate.to_s.to_sym the_options = nil the_object.deactivate already_running = false if unique || (details[:restore] == true) @application_states.each do |the_app_record| if the_app_record[:location] == details[:path].to_s already_running = true app_uuid = the_app_record[:application] break end end end # if already_running == true if details[:restore] == true response = [200, {"content-type" => "application/json"}, {:result => {:application => app_uuid.to_s, :location => details[:path].to_s}.to_json().encode64}.to_json()] else if unique response = [403, {"content-type" => "application/json"}, {:result => false, :error => "Already Running"}.to_json()] else somedata = GxGwww::CACHE.fetch(details[:path].to_s,@credential) if somedata app_uuid = GxG::uuid_generate.to_s.to_sym response = [200, {"content-type" => "application/json"}, {:result => {:application => app_uuid.to_s, :location => details[:path].to_s}.to_json().encode64}.to_json()] @application_states << {:application => app_uuid.to_s, :credentialed => credentialed, :unique => unique, :location => details[:path].to_s, :status => "exitready", :data => nil} else response = [403, {"content-type" => "application/json"}, {:result => false, :error => "Could not locate application in storage #{details.inspect}"}.to_json()] end end end else somedata = GxGwww::CACHE.fetch(details[:path].to_s,@credential) if somedata response = [200, {"content-type" => "application/json"}, {:result => {:application => app_uuid.to_s, :location => details[:path].to_s}.to_json().encode64}.to_json()] @application_states << {:application => app_uuid.to_s, :credentialed => credentialed, :unique => unique, :location => details[:path].to_s, :status => "exitready", :data => nil} else response = [403, {"content-type" => "application/json"}, {:result => false, :error => "Could not locate application in storage #{details.inspect}"}.to_json()] end end # else response = [403, {"content-type" => "application/json"}, {:result => false, :error => "Invalid name or path: #{details.inspect}"}.to_json()] end # if the_object_token GxG::SERVICES[:core][:resources].close(the_object_token[:token]) end end response end # def app_state_pull(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else record = nil @application_states.each_with_index do |the_app, the_index| if the_app[:application] == details[:application] record = @application_states[(the_index)] break end end if record response = [200, {"content-type" => "application/json"}, {:result => record.to_json().encode64}.to_json()] else response = [200, {"content-type" => "application/json"}, {:result => {}.to_json().encode64}.to_json()] end end response end # def app_state_push(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else found = nil @application_states.each_with_index do |the_app, the_index| if the_app[:application] == details[:application] found = index break end end # decode payload prior content = details[:data] if found if content # {:application => app_uuid.to_s, :credentialed => credentialed, :unique => unique, :location => details[:path].to_s, :status => "exitready", :data => nil} @application_states[(found)][:data] = content @application_states[(found)][:status] = "exitready" response = [200, {"content-type" => "application/json"}, {:result => true}.to_json()] else # error response = [500, {"content-type" => "application/json"}, {:result => false, :error => "State Data Missing.", :parameters => details[:data]}.to_json()] end else response = [404, {"content-type" => "application/json"}, {:result => false, :error => "Application Not Found.", :parameters => details[:application]}.to_json()] end end response end # def format_pull(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else # Uncredentialed applications might pull formats - no credential screening for now. records = [] if details[:criteria].is_a?(::Hash) criterias = [(details[:criteria])] else criterias = details[:criteria] end if criterias.is_a?(::Array) criterias.each do |the_criteria| GxG::DB[:roles][:formats].format_list(the_criteria).each do |the_format_stub| if the_format_stub[:ufs].to_s.size > 0 records << (GxG::DB[:roles][:formats].format_load({:ufs => the_format_stub[:ufs]})) else if the_format_stub[:uuid].to_s.size > 0 records << (GxG::DB[:roles][:formats].format_load({:uuid => the_format_stub[:uuid].to_s.to_sym})) end end end end end response = [200, {"content-type" => "application/json"}, {:result => records.to_json.encode64}.to_json()] end response end # def format_push(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else begin unless GxG::DB[:authority].role_member?(GxG::DB[:authority][:system_credentials][:administrators], @credential) || GxG::DB[:authority].role_member?(GxG::DB[:authority][:system_credentials][:developers], @credential) raise Exception, "You do not have permissions sufficient to write this format." end # Check inputs unless ::GxG::valid_uuid?(details[:uuid].to_s.to_sym) raise Exception, "Invalid UUID passed for the format" end unless details[:type].is_any?(::String, ::Symbol) raise Exception, "You must pass the format_record[:type] as a String or Symbol" end unless details[:ufs].is_any?(::String, ::Symbol) raise Exception, "You must pass the format_record[:ufs] as a String or Symbol" end unless details[:title].is_a?(::String) raise Exception, "You must pass the format_record[:title] as a String" end unless details[:version].is_a?(::Float) raise Exception, "You must pass the format_record[:version] as a Float" end unless details[:mime_types].is_any?(::String, ::Array) raise Exception, "You must pass the format_record[:mime_types] as a String" end unless details[:content].is_a?(::Hash) raise Exception, "You must pass the format_record[:content] as a Hash" end unless GxG::DB[:roles][:formats].persistable?(details[:content]) raise Exception, "You must pass the format_record[:content] as a Hash of persistable elements" end # prepare format record format_record = GxG::DB[:roles][:formats].format_template(details[:type].to_s.to_sym) unless format_record raise ArgumentError, "Invalid format structural type" end format_record[:uuid] = details[:uuid].to_s.to_sym format_record[:type] = details[:type].to_s.to_sym format_record[:ufs] = details[:ufs].to_s format_record[:title] = details[:title].to_s format_record[:version] = details[:version].to_f format_record[:mime_types] = details[:mime_types] format_record[:content] = details[:content] # If format exists, update, else create if GxG::DB[:roles][:formats].format_list({:uuid => details[:uuid].to_s.to_sym}).size > 0 unless GxG::DB[:roles][:formats].format_update(format_record) raise Exception, "Unkown Format Update Error" end else unless GxG::DB[:roles][:formats].format_create(format_record) raise Exception, "Unkown Format Creation Error" end end response = [200, {"content-type" => "application/json"}, {:result => true}.to_json()] rescue Exception => the_error response = [500, {"content-type" => "application/json"}, ({:result => false, :error => the_error.to_s, :parameters => details}).to_json()] end # end response end # def format_template(details={}) begin format_record = GxG::DB[:roles][:formats].format_template(details[:type].to_s.to_sym) unless format_record raise ArgumentError, "Invalid format structural type" end response = [200, {"content-type" => "application/json"}, {:result => format_record.to_json.encode64}.to_json()] rescue Exception => the_error response = [500, {"content-type" => "application/json"}, ({:result => false, :error => the_error.to_s, :parameters => details}).to_json()] end response end # def format_list(details={}) if self.closed? response = [500, {"content-type" => "application/json"}, ({:result => false, :error => "Connector Closed.", :parameters => false}).to_json()] else response = [200, {"content-type" => "application/json"}, {:result => GxG::DB[:roles][:formats].format_list(details).to_json.encode64}.to_json()] end response end # def format_destroy(details={}) begin unless GxG::DB[:authority].role_member?(GxG::DB[:authority][:system_credentials][:administrators], @credential) || GxG::DB[:authority].role_member?(GxG::DB[:authority][:system_credentials][:developers], @credential) raise Exception, "You do not have permissions sufficient to destroy this format." end criteria={} if GxG::valid_uuid?(details[:uuid]) criteria[:uuid] = details[:uuid].to_s.to_sym else if details[:ufs].is_a?(::String) criteria[:ufs] = details[:ufs].to_s end end unless criteria.keys.size > 0 raise ArgumentError, "You must specify which format to destroy with either :uuid or :ufs specifier." end response = [200, {"content-type" => "application/json"}, {:result => GxG::DB[:roles][:formats].format_destroy(criteria)}.to_json()] rescue Exception => the_error response = [500, {"content-type" => "application/json"}, ({:result => false, :error => the_error.to_s, :parameters => details}).to_json()] end response end # --------------------------------------------- end # end # module GxGwww # --------------------------------------------------------------------- CACHE = ::GxGwww::Storage::UnifiedMemoryCache.new # --------------------------------------------------------------------- end #