module Scrivito # # @api public # class Configuration # # Default path of a CA certification file in PEM format. # # @api public # DEFAULT_CA_FILE = File.expand_path('../../../config/ca-bundle.crt', __FILE__) class << self # Determine if current visitor is permitted to edit content. attr_accessor :find_user_proc # # Configures a callback to be invoked when the SDK determines whether current visitor is # permitted to edit content. # # If the callback is missing in the +development+ or +test+ environment, then the SDK will # assume, that the current visitor is {Scrivito::User.system_user}, who can always create # workspaces, can always read, write, publish, delete and invite to any workspace. # # If the callback is missing in any other environment (for example in +production+ or # +staging+), then the SDK will assume, that the current visitor is not permitted to edit # content. # # @api public # # @param [Proc] block proc for detemining if the current visitor is permitted to edit content # @yieldparam [Hash] env rack env # @yieldreturn [Scrivito::User] if the current visitor is permitted to edit content # @yieldreturn [false, nil] if the current visitor is not permitted to edit content # # @example # Scrivito::Configuration.editing_auth do |env| # if user_id = env['USER_ID'] # Scrivito::User.define(user_id) # end # end # def editing_auth(&block) if block.respond_to?(:arity) && block.arity == 1 @editing_auth_callback = block else raise ArgumentError, 'editing_auth should have only one attribute!' end end def editing_auth_callback @editing_auth_callback || default_editing_auth_callback end # Configures how to find users for the in-place GUI. # @api public # @param [Proc] find_user_proc proc for finding a user by the user id # @yieldparam [String] user_id id of the user # @yieldreturn [Scrivito::User] if the user with the given user id was found # @yieldreturn [NilClass] if the user with the given user id was not found # @raise [Scrivito::ScrivitoError] if the proc returns neither a {Scrivito::User}, nor +nil+ # @note This configuration key is optional. If it is not configured the in-place GUI would # behave normally, but would not be able to find any users. # @example Return a "dummy" {Scrivito::User} # Scrivito.configure do |config| # config.find_user do |user_id| # Scrivito::User.new(user_id) # end # end # @example Find the user with a custom user model and convert it to a {Scrivito::User} # Scrivito.configure do |config| # config.find_user do |user_id| # my_user = MyUserModel.find(user_id) # if my_user # my_user.to_scrivito_user # end # end # end def find_user(&find_user_proc) self.find_user_proc = find_user_proc end # # Set the path for the filesystem cache. # # +Scrivito+ makes heavy use of filesystem caching. Use this method to configure the directory # that should be used to store cached data. By default, +RAILS_ROOT/tmp/scrivito_cache+ will # be used. # # @api public # # @param path [String] Path to directory that should be used to store cached data. # # @example Configure +Scrivito+ to store its cache under +/tmp/my_cache+. # # Scrivito.configure do |config| # config.cache_path = '/tmp/my_cache' # end # def cache_path=(path) CmsDataCache.cache_path = path end # # Sets the second level cache. # # If it is set, then +Scrivito+ will additionaly store its cache in both: the filesystem cache # and the second level cache. Also +Scrivito+ will search in the second level cache if # searching in the filesystem cache returns no results. If the second level cache returns # results, then the results will be store in the filesystem cache. # # By default it is not set. # # @api public # # @param cache_store [ActiveSupport::Cache::Store] cache store to be used as the second level # cache # # @example Use Memcached as the second level cache (https://rubygems.org/gems/dalli) # # Scrivito.configure do |config| # config.second_level_cache = ActiveSupport::Cache::DalliStore.new("localhost", "server-downstairs.localnetwork:8229") # end # def second_level_cache=(cache_store) CmsDataCache.second_level_cache = cache_store end # # Sets the tenant name. # This configuration key _must_ be provided. # # @api public # def tenant=(tenant_name) @endpoint_uri = nil @tenant = tenant_name end # # Sets the API key. # This configuration key _must_ be provided. # # @api public # attr_writer :api_key # # Sets the API endpoint URL. # This configuration key is optional. # Default is +'api.scrivito.com'+. # If no schema is provided HTTPS is assumed. # # @api public # attr_writer :endpoint # # Gets the path of a CA certification file in PEM format. # # @return [String] # @api public # attr_reader :ca_file # Sets path of a CA certification file in PEM format. # The file can contain several CA certificates. # Certifications will be used for endpoint peer verification of various scrivito services # e.g. Content Read Service. # @api public def ca_file=(path) File.read(path) if path # Try to read the given file and fail if it doesn't exist or is not readable. @ca_file = path end def to_prepare unless Rails.configuration.cache_classes NamedLink.reset_cache BasicObj.reset_type_computer! BasicWidget.reset_type_computer! end end def tenant tenant = @tenant || ENV['SCRIVITO_TENANT'] assert_configuration_key_present(:tenant, tenant) tenant end def api_key api_key = @api_key || ENV['SCRIVITO_API_KEY'] assert_configuration_key_present(:api_key, api_key) api_key end def endpoint raise 'Missing required configuration key "endpoint"' unless @endpoint @endpoint end def endpoint_uri @endpoint_uri ||= calculate_endpoint_uri end def set_defaults! self.ca_file = DEFAULT_CA_FILE self.endpoint = 'api.scrivito.com' self.check_batch_size = 100 end attr_accessor :choose_homepage_callback, :check_batch_size # Configure a callback to be invoked when the Scrivito SDK delivers the homepage. # The given callback will receive the rack env # and must return an {BasicObj Obj} to be used as the homepage. # If no callback is configured, {BasicObj.homepage Obj.homepage} will be used as the default. # @api public def choose_homepage(&block) self.choose_homepage_callback = block end def obj_formats @obj_formats ||= { '_default' => proc do |obj, user| { id: obj.id, obj_class_name: obj.obj_class_name, description_for_editor: obj.description_for_editor, modification: obj.modification, has_conflict: obj.has_conflict?, last_changed: obj.last_changed.utc.iso8601, is_binary: obj.binary?, restriction_messages: user.restriction_messages_for(obj) } end } end def register_obj_format(name, &block) if name.start_with? '_' raise InvalidFormatNameError.new('Format names starting with underscore are not allowed.') else obj_formats[name] = block end end # For test purposes only. def reset_editing_auth_callback! @editing_auth_callback = nil end def migration_path 'scrivito/migrate' end private def default_editing_auth_callback if Rails.env.development? || Rails.env.test? ->(_) { User.system_user } end end def assert_configuration_key_present(key, value) unless value raise %{ Missing the required configuration key "#{key}". You need to configure the "tenant" and the "api_key" in order to connect the application to the Scrivito backend. Either use the environment variables "SCRIVITO_TENANT" and "SCRIVITO_API_KEY" or set the keys in an initializer: Scrivito.configure do |config| config.tenant = 'my_tenant' config.api_key = 'secret123' end The values of the keys can be obtained from the dashboard at https://scrivito.com. } end end def calculate_endpoint_uri url = endpoint url = "https://#{url}" unless url.match(/^http/) url = "#{url}/tenants/#{tenant}" URI.parse(url) end end self.set_defaults! end class InvalidFormatNameError < StandardError end end