cubicweb/web/webconfig.py
changeset 12019 9759aefa047b
parent 12017 281a6219bdc9
child 12268 d84bc85f7f70
equal deleted inserted replaced
12018:7c66cabacd56 12019:9759aefa047b
    76       }),
    76       }),
    77 
    77 
    78     ))
    78     ))
    79 
    79 
    80 
    80 
    81 class WebConfiguration(CubicWebConfiguration):
    81 class BaseWebConfiguration(CubicWebConfiguration):
    82     """the WebConfiguration is a singleton object handling instance's
    82     """Base class for web configurations"""
    83     configuration and preferences
       
    84     """
       
    85     cubicweb_appobject_path = CubicWebConfiguration.cubicweb_appobject_path | set(['web.views'])
    83     cubicweb_appobject_path = CubicWebConfiguration.cubicweb_appobject_path | set(['web.views'])
    86     cube_appobject_path = CubicWebConfiguration.cube_appobject_path | set(['views'])
    84     cube_appobject_path = CubicWebConfiguration.cube_appobject_path | set(['views'])
    87 
    85 
    88     options = merge_options(CubicWebConfiguration.options + (
    86     options = merge_options(CubicWebConfiguration.options + (
    89         ('repository-uri',
    87         ('repository-uri',
   113         ('query-log-file',
   111         ('query-log-file',
   114          {'type' : 'string',
   112          {'type' : 'string',
   115           'default': None,
   113           'default': None,
   116           'help': 'web instance query log file',
   114           'help': 'web instance query log file',
   117           'group': 'web', 'level': 3,
   115           'group': 'web', 'level': 3,
   118           }),
       
   119         # web configuration
       
   120         ('datadir-url',
       
   121          {'type': 'string', 'default': None,
       
   122           'help': ('base url for static data, if different from "${base-url}/data/".  '
       
   123                    'If served from a different domain, that domain should allow '
       
   124                    'cross-origin requests.'),
       
   125           'group': 'web',
       
   126           }),
       
   127         ('auth-mode',
       
   128          {'type' : 'choice',
       
   129           'choices' : ('cookie', 'http'),
       
   130           'default': 'cookie',
       
   131           'help': 'authentication mode (cookie / http)',
       
   132           'group': 'web', 'level': 3,
       
   133           }),
       
   134         ('realm',
       
   135          {'type' : 'string',
       
   136           'default': 'cubicweb',
       
   137           'help': 'realm to use on HTTP authentication mode',
       
   138           'group': 'web', 'level': 3,
       
   139           }),
       
   140         ('http-session-time',
       
   141          {'type' : 'time',
       
   142           'default': 0,
       
   143           'help': "duration of the cookie used to store session identifier. "
       
   144           "If 0, the cookie will expire when the user exist its browser. "
       
   145           "Should be 0 or greater than repository\'s session-time.",
       
   146           'group': 'web', 'level': 2,
       
   147           }),
   116           }),
   148         ('cleanup-anonymous-session-time',
   117         ('cleanup-anonymous-session-time',
   149          {'type' : 'time',
   118          {'type' : 'time',
   150           'default': '5min',
   119           'default': '5min',
   151           'help': 'Same as cleanup-session-time but specific to anonymous '
   120           'help': 'Same as cleanup-session-time but specific to anonymous '
   152           'sessions. You can have a much smaller timeout here since it will be '
   121           'sessions. You can have a much smaller timeout here since it will be '
   153           'transparent to the user. Default to 5min.',
   122           'transparent to the user. Default to 5min.',
   154           'group': 'web', 'level': 3,
   123           'group': 'web', 'level': 3,
   155           }),
   124           }),
   156         ('submit-mail',
   125     ))
   157          {'type' : 'string',
       
   158           'default': None,
       
   159           'help': ('Mail used as recipient to report bug in this instance, '
       
   160                    'if you want this feature on'),
       
   161           'group': 'web', 'level': 2,
       
   162           }),
       
   163 
       
   164         ('language-mode',
       
   165          {'type' : 'choice',
       
   166           'choices': ('http-negotiation', 'url-prefix', ''),
       
   167           'default': 'http-negotiation',
       
   168           'help': ('source for interface\'s language detection. '
       
   169                    'If set to "http-negotiation" the Accept-Language HTTP header will be used,'
       
   170                    ' if set to "url-prefix", the URL will be inspected for a short language prefix.'),
       
   171           'group': 'web', 'level': 2,
       
   172           }),
       
   173 
       
   174         ('print-traceback',
       
   175          {'type' : 'yn',
       
   176           'default': CubicWebConfiguration.mode != 'system',
       
   177           'help': 'print the traceback on the error page when an error occurred',
       
   178           'group': 'web', 'level': 2,
       
   179           }),
       
   180 
       
   181         ('captcha-font-file',
       
   182          {'type' : 'string',
       
   183           'default': join(CubicWebConfiguration.shared_dir(), 'data', 'porkys.ttf'),
       
   184           'help': 'True type font to use for captcha image generation (you \
       
   185 must have the python imaging library installed to use captcha)',
       
   186           'group': 'web', 'level': 3,
       
   187           }),
       
   188         ('captcha-font-size',
       
   189          {'type' : 'int',
       
   190           'default': 25,
       
   191           'help': 'Font size to use for captcha image generation (you must \
       
   192 have the python imaging library installed to use captcha)',
       
   193           'group': 'web', 'level': 3,
       
   194           }),
       
   195 
       
   196         ('concat-resources',
       
   197          {'type' : 'yn',
       
   198           'default': False,
       
   199           'help': 'use modconcat-like URLS to concat and serve JS / CSS files',
       
   200           'group': 'web', 'level': 2,
       
   201           }),
       
   202         ('anonymize-jsonp-queries',
       
   203          {'type': 'yn',
       
   204           'default': True,
       
   205           'help': 'anonymize the connection before executing any jsonp query.',
       
   206           'group': 'web', 'level': 1
       
   207           }),
       
   208         ('generate-staticdir',
       
   209          {'type': 'yn',
       
   210           'default': False,
       
   211           'help': 'Generate the static data resource directory on upgrade.',
       
   212           'group': 'web', 'level': 2,
       
   213           }),
       
   214         ('staticdir-path',
       
   215          {'type': 'string',
       
   216           'default': None,
       
   217           'help': 'The static data resource directory path.',
       
   218           'group': 'web', 'level': 2,
       
   219           }),
       
   220         ('access-control-allow-origin',
       
   221          {'type' : 'csv',
       
   222           'default': (),
       
   223           'help':('comma-separated list of allowed origin domains or "*" for any domain'),
       
   224           'group': 'web', 'level': 2,
       
   225           }),
       
   226         ('access-control-allow-methods',
       
   227          {'type' : 'csv',
       
   228           'default': (),
       
   229           'help': ('comma-separated list of allowed HTTP methods'),
       
   230           'group': 'web', 'level': 2,
       
   231           }),
       
   232         ('access-control-max-age',
       
   233          {'type' : 'int',
       
   234           'default': None,
       
   235           'help': ('maximum age of cross-origin resource sharing (in seconds)'),
       
   236           'group': 'web', 'level': 2,
       
   237           }),
       
   238         ('access-control-expose-headers',
       
   239          {'type' : 'csv',
       
   240           'default': (),
       
   241           'help':('comma-separated list of HTTP headers the application declare in response to a preflight request'),
       
   242           'group': 'web', 'level': 2,
       
   243           }),
       
   244         ('access-control-allow-headers',
       
   245          {'type' : 'csv',
       
   246           'default': (),
       
   247           'help':('comma-separated list of HTTP headers the application may set in the response'),
       
   248           'group': 'web', 'level': 2,
       
   249           }),
       
   250         ))
       
   251 
       
   252     def __init__(self, *args, **kwargs):
       
   253         super(WebConfiguration, self).__init__(*args, **kwargs)
       
   254         self.uiprops = None
       
   255         self.datadir_url = None
       
   256 
       
   257     def fckeditor_installed(self):
       
   258         if self.uiprops is None:
       
   259             return False
       
   260         return exists(self.uiprops.get('FCKEDITOR_PATH', ''))
       
   261 
       
   262     def cwproperty_definitions(self):
       
   263         for key, pdef in super(WebConfiguration, self).cwproperty_definitions():
       
   264             if key == 'ui.fckeditor' and not self.fckeditor_installed():
       
   265                 continue
       
   266             yield key, pdef
       
   267 
       
   268     @deprecated('[3.22] call req.cnx.repo.get_versions() directly')
       
   269     def vc_config(self):
       
   270         return self.repository().get_versions()
       
   271 
   126 
   272     def anonymous_user(self):
   127     def anonymous_user(self):
   273         """return a login and password to use for anonymous users.
   128         """return a login and password to use for anonymous users.
   274 
   129 
   275         None may be returned for both if anonymous connection is not
   130         None may be returned for both if anonymous connection is not
   283         except KeyError:
   138         except KeyError:
   284             user, passwd = None, None
   139             user, passwd = None, None
   285         except UnicodeDecodeError:
   140         except UnicodeDecodeError:
   286             raise ConfigurationError("anonymous information should only contains ascii")
   141             raise ConfigurationError("anonymous information should only contains ascii")
   287         return user, passwd
   142         return user, passwd
       
   143 
       
   144 
       
   145 
       
   146 class WebConfiguration(BaseWebConfiguration):
       
   147     """the WebConfiguration is a singleton object handling instance's
       
   148     configuration and preferences
       
   149     """
       
   150     options = merge_options(BaseWebConfiguration.options + (
       
   151         # web configuration
       
   152         ('datadir-url',
       
   153          {'type': 'string', 'default': None,
       
   154           'help': ('base url for static data, if different from "${base-url}/data/".  '
       
   155                    'If served from a different domain, that domain should allow '
       
   156                    'cross-origin requests.'),
       
   157           'group': 'web',
       
   158           }),
       
   159         ('auth-mode',
       
   160          {'type' : 'choice',
       
   161           'choices' : ('cookie', 'http'),
       
   162           'default': 'cookie',
       
   163           'help': 'authentication mode (cookie / http)',
       
   164           'group': 'web', 'level': 3,
       
   165           }),
       
   166         ('realm',
       
   167          {'type' : 'string',
       
   168           'default': 'cubicweb',
       
   169           'help': 'realm to use on HTTP authentication mode',
       
   170           'group': 'web', 'level': 3,
       
   171           }),
       
   172         ('http-session-time',
       
   173          {'type' : 'time',
       
   174           'default': 0,
       
   175           'help': "duration of the cookie used to store session identifier. "
       
   176           "If 0, the cookie will expire when the user exist its browser. "
       
   177           "Should be 0 or greater than repository\'s session-time.",
       
   178           'group': 'web', 'level': 2,
       
   179           }),
       
   180         ('submit-mail',
       
   181          {'type' : 'string',
       
   182           'default': None,
       
   183           'help': ('Mail used as recipient to report bug in this instance, '
       
   184                    'if you want this feature on'),
       
   185           'group': 'web', 'level': 2,
       
   186           }),
       
   187 
       
   188         ('language-mode',
       
   189          {'type' : 'choice',
       
   190           'choices': ('http-negotiation', 'url-prefix', ''),
       
   191           'default': 'http-negotiation',
       
   192           'help': ('source for interface\'s language detection. '
       
   193                    'If set to "http-negotiation" the Accept-Language HTTP header will be used,'
       
   194                    ' if set to "url-prefix", the URL will be inspected for a short language prefix.'),
       
   195           'group': 'web', 'level': 2,
       
   196           }),
       
   197 
       
   198         ('print-traceback',
       
   199          {'type' : 'yn',
       
   200           'default': CubicWebConfiguration.mode != 'system',
       
   201           'help': 'print the traceback on the error page when an error occurred',
       
   202           'group': 'web', 'level': 2,
       
   203           }),
       
   204 
       
   205         ('captcha-font-file',
       
   206          {'type' : 'string',
       
   207           'default': join(CubicWebConfiguration.shared_dir(), 'data', 'porkys.ttf'),
       
   208           'help': 'True type font to use for captcha image generation (you \
       
   209 must have the python imaging library installed to use captcha)',
       
   210           'group': 'web', 'level': 3,
       
   211           }),
       
   212         ('captcha-font-size',
       
   213          {'type' : 'int',
       
   214           'default': 25,
       
   215           'help': 'Font size to use for captcha image generation (you must \
       
   216 have the python imaging library installed to use captcha)',
       
   217           'group': 'web', 'level': 3,
       
   218           }),
       
   219 
       
   220         ('concat-resources',
       
   221          {'type' : 'yn',
       
   222           'default': False,
       
   223           'help': 'use modconcat-like URLS to concat and serve JS / CSS files',
       
   224           'group': 'web', 'level': 2,
       
   225           }),
       
   226         ('anonymize-jsonp-queries',
       
   227          {'type': 'yn',
       
   228           'default': True,
       
   229           'help': 'anonymize the connection before executing any jsonp query.',
       
   230           'group': 'web', 'level': 1
       
   231           }),
       
   232         ('generate-staticdir',
       
   233          {'type': 'yn',
       
   234           'default': False,
       
   235           'help': 'Generate the static data resource directory on upgrade.',
       
   236           'group': 'web', 'level': 2,
       
   237           }),
       
   238         ('staticdir-path',
       
   239          {'type': 'string',
       
   240           'default': None,
       
   241           'help': 'The static data resource directory path.',
       
   242           'group': 'web', 'level': 2,
       
   243           }),
       
   244         ('access-control-allow-origin',
       
   245          {'type' : 'csv',
       
   246           'default': (),
       
   247           'help':('comma-separated list of allowed origin domains or "*" for any domain'),
       
   248           'group': 'web', 'level': 2,
       
   249           }),
       
   250         ('access-control-allow-methods',
       
   251          {'type' : 'csv',
       
   252           'default': (),
       
   253           'help': ('comma-separated list of allowed HTTP methods'),
       
   254           'group': 'web', 'level': 2,
       
   255           }),
       
   256         ('access-control-max-age',
       
   257          {'type' : 'int',
       
   258           'default': None,
       
   259           'help': ('maximum age of cross-origin resource sharing (in seconds)'),
       
   260           'group': 'web', 'level': 2,
       
   261           }),
       
   262         ('access-control-expose-headers',
       
   263          {'type' : 'csv',
       
   264           'default': (),
       
   265           'help':('comma-separated list of HTTP headers the application declare in response to a preflight request'),
       
   266           'group': 'web', 'level': 2,
       
   267           }),
       
   268         ('access-control-allow-headers',
       
   269          {'type' : 'csv',
       
   270           'default': (),
       
   271           'help':('comma-separated list of HTTP headers the application may set in the response'),
       
   272           'group': 'web', 'level': 2,
       
   273           }),
       
   274         ))
       
   275 
       
   276     def __init__(self, *args, **kwargs):
       
   277         super(WebConfiguration, self).__init__(*args, **kwargs)
       
   278         self.uiprops = None
       
   279         self.datadir_url = None
       
   280 
       
   281     def fckeditor_installed(self):
       
   282         if self.uiprops is None:
       
   283             return False
       
   284         return exists(self.uiprops.get('FCKEDITOR_PATH', ''))
       
   285 
       
   286     def cwproperty_definitions(self):
       
   287         for key, pdef in super(WebConfiguration, self).cwproperty_definitions():
       
   288             if key == 'ui.fckeditor' and not self.fckeditor_installed():
       
   289                 continue
       
   290             yield key, pdef
       
   291 
       
   292     @deprecated('[3.22] call req.cnx.repo.get_versions() directly')
       
   293     def vc_config(self):
       
   294         return self.repository().get_versions()
   288 
   295 
   289     @cachedproperty
   296     @cachedproperty
   290     def _instance_salt(self):
   297     def _instance_salt(self):
   291         """This random key/salt is used to sign content to be sent back by
   298         """This random key/salt is used to sign content to be sent back by
   292         browsers, eg. in the error report form.
   299         browsers, eg. in the error report form.