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.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 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 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 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 reset_editing_auth_callback! 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 # attr_accessor :ui_locale # @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. attr_accessor :legacy_routing def 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. attr_accessor :inject_preset_routes def scrivito_route_enabled? inject_preset_routes == false end def 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 attr_accessor :choose_homepage_callback, :check_batch_size # # Set the default {Scrivito::Binary#transform image transformation}. # # @api public # # When delivering binary Objs, the default image transformation will be applied if # {Scrivito::BasicObj#apply_image_transformation? Obj#apply_image_transformation?} returns # +true+. # # 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 # @see Scrivito::BasicObj#apply_image_transformation? # attr_writer :default_image_transformation attr_reader :default_image_transformation # 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.root Obj.root} 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: 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 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