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__) # Determine if current visitor is permitted to edit content. def self.find_user_proc=(value) @find_user_proc = value end def self.find_user_proc @find_user_proc end # # 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 self.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 self.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.define(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 self.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 self.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 self.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 self.tenant=(tenant_name) @endpoint_uri = nil @tenant = tenant_name end # # Sets the API key. # This configuration key _must_ be provided. # # @api public # def self.api_key=(value) @api_key = value end # # 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 # def self.endpoint=(value) @endpoint = value end # # Sets a minimum # {https://ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html#open_timeout-attribute-method # +Net::HTTP#open_timeout+} for endpoint connections. # # Default is +0.5+ # # @api public # def self.minimum_open_timeout=(value) ConnectionManager.minimum_open_timeout = value end # # Sets a minimum # {https://ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html#ssl_timeout-attribute-method # +Net::HTTP#ssl_timeout+} for endpoint connections. # # Default is +1.0+ # # @api public # def self.minimum_ssl_timeout=(value) ConnectionManager.minimum_ssl_timeout = value end # # Sets a minimum # {https://ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html#read_timeout-attribute-method # +Net::HTTP#read_timeout+} for endpoint connections. # # Default is +0.5+ # # @api public # def self.minimum_read_timeout=(value) ConnectionManager.minimum_read_timeout = value end # # Gets the path of a CA certification file in PEM format. # # @return [String] # @api public # def self.ca_file @ca_file end # 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 self.ca_file=(path) if path # Try to read the given file and fail if it doesn't exist or is not readable. File.read(path) end @ca_file = path end def self.to_prepare unless Rails.configuration.cache_classes BasicObj.reset_type_computer! BasicWidget.reset_type_computer! end end def self.tenant tenant = @tenant || ENV['SCRIVITO_TENANT'] assert_configuration_key_present(:tenant, tenant) tenant end def self.api_key api_key = @api_key || ENV['SCRIVITO_API_KEY'] assert_configuration_key_present(:api_key, api_key) api_key end def self.endpoint raise 'Missing required configuration key "endpoint"' unless @endpoint @endpoint end def self.endpoint_uri @endpoint_uri ||= calculate_endpoint_uri end def self.set_defaults! self.ca_file = DEFAULT_CA_FILE self.endpoint = 'api.scrivito.com' self.check_batch_size = 100 self.legacy_routing = false self.default_image_transformation = {} self.choose_homepage_callback = -> (env) { Obj.root } self.find_user_proc = nil self.inject_preset_routes = true @editing_auth_callback = nil end # # Configures the in-place UI to use a locale different from the one used by the rest of the # application. # # @api public # @example # # The application will use +:de+ as locale. # I18n.locale = :de # # Scrivito.configure do |config| # # But the in-place UI will nevertheless use +:en+. # config.ui_locale = :en # end # def self.ui_locale @ui_locale end def self.ui_locale=(value) @ui_locale = value end # @api public # @deprecated The legacy routing is deprecated and will be removed in the next major # version of Scrivito. # # Scrivito changed its routing to a slug first url scheme. This configuration option # allows you to switch back to the old id first url scheme. def self.legacy_routing @legacy_routing end def self.legacy_routing=(enabled) if enabled Scrivito::Deprecation.warn(%[ The legacy routing is deprecated and will be removed in the next major version of Scrivito. Please use the new scrivito_route api to replicate the legacy routes: scrivito_route '/', using: 'homepage', via: :all scrivito_route '(/):id/*slug', using: 'slug_id', via: :all scrivito_route '/*permalink', using: 'permalink', via: all ]) end @legacy_routing = enabled end # @api public # # The +inject_preset_routes+ configuration is enabled by default and adds the default # Scrivito routing to your application routes. It can be disabled by setting it to # +false+ which lets you use {RoutingExtensions#scrivito_route scrivito_route} to # customize the routing used by Scrivito. def self.inject_preset_routes=(value) @inject_preset_routes = value end def self.inject_preset_routes @inject_preset_routes end def self.scrivito_route_enabled? inject_preset_routes == false end def self.with_scrivito_route_enabled begin initial_value = inject_preset_routes self.inject_preset_routes = false yield ensure self.inject_preset_routes = initial_value end end def self.choose_homepage_callback=(value) @choose_homepage_callback = value end def self.choose_homepage_callback @choose_homepage_callback end def self.check_batch_size=(value) @check_batch_size = value end def self.check_batch_size @check_batch_size end # # Set the default {Scrivito::Binary#transform image transformation}. # # @api public # # When delivering binary Objs, the default image transformation will be applied. # # If not changed the default image transformation is an empty transformation (an empty # +Hash+). Set it to +false+ to disabled the default image transformation completely. # # @param [Hash] value the {Scrivito::Binary#transform transformation definition} # # @see Scrivito::Binary#transform # def self.default_image_transformation=(value) @default_image_transformation = value end def self.default_image_transformation @default_image_transformation end # @api public # # A callback that can be provided for determining the CMS object to be used when visiting # the homepage. See {Scrivito::RoutingExtensions#scrivito_route scrivito_route} for # details on how to define routes. The callback is called once per request and receives # the rack environment as its only parameter. By default, the CMS object at the root # path (+/+) is used as the homepage. # # @yield Rack environment of the current request # # @example # Scrivito.configure do |config| # config.choose_homepage do |env| # Obj.root # Replace with code to set the homepage # end # end def self.choose_homepage(&block) self.choose_homepage_callback = block end def self.obj_formats @obj_formats ||= { '_default' => proc do |obj, user| { id: obj.id, obj_class: obj.obj_class, 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 self.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 self.reset_editing_auth_callback! @editing_auth_callback = nil end def self.migration_path 'scrivito/migrate' end private_class_method def self.default_editing_auth_callback if Rails.env.development? || Rails.env.test? ->(_) { User.system_user } end end private_class_method def self.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 private_class_method def self.calculate_endpoint_uri url = endpoint url = "https://#{url}" unless url.match(/^http/) url = "#{url}/tenants/#{tenant}" URI.parse(url) end end Configuration.set_defaults! class InvalidFormatNameError < StandardError end end