server/querier.py
branchstable
changeset 5419 0b7805928a27
parent 5168 1ab032df5ca3
child 5421 8167de96c523
equal deleted inserted replaced
5418:4f0047cfecb5 5419:0b7805928a27
    46     """check that Password entities are not selected"""
    46     """check that Password entities are not selected"""
    47     for solution in rqlst.solutions:
    47     for solution in rqlst.solutions:
    48         if 'Password' in solution.itervalues():
    48         if 'Password' in solution.itervalues():
    49             raise Unauthorized('Password selection is not allowed')
    49             raise Unauthorized('Password selection is not allowed')
    50 
    50 
    51 def check_read_access(schema, user, rqlst, solution):
    51 def term_etype(session, term, solution, args):
       
    52     """return the entity type for the given term (a VariableRef or a Constant
       
    53     node)
       
    54     """
       
    55     try:
       
    56         return solution[term.name]
       
    57     except AttributeError:
       
    58         return session.describe(term.eval(args))[0]
       
    59 
       
    60 def check_read_access(session, rqlst, solution, args):
    52     """check that the given user has credentials to access data read the
    61     """check that the given user has credentials to access data read the
    53     query
    62     query
    54 
    63 
    55     return a dict defining necessary local checks (due to use of rql expression
    64     return a dict defining necessary local checks (due to use of rql expression
    56     in the schema), keys are variable names and values associated rql expression
    65     in the schema), keys are variable names and values associated rql expression
    57     for the associated variable with the given solution
    66     for the associated variable with the given solution
    58     """
    67     """
       
    68     # use `term_etype` since we've to deal with rewritten constants here,
       
    69     # when used as an external source by another repository.
       
    70     # XXX what about local read security w/ those rewritten constants...
       
    71     schema = session.repo.schema
    59     if rqlst.where is not None:
    72     if rqlst.where is not None:
    60         for rel in rqlst.where.iget_nodes(Relation):
    73         for rel in rqlst.where.iget_nodes(Relation):
    61             # XXX has_text may have specific perm ?
    74             # XXX has_text may have specific perm ?
    62             if rel.r_type in READ_ONLY_RTYPES:
    75             if rel.r_type in READ_ONLY_RTYPES:
    63                 continue
    76                 continue
    64             rschema = schema.rschema(rel.r_type)
    77             rschema = schema.rschema(rel.r_type)
    65             if rschema.final:
    78             if rschema.final:
    66                 eschema = schema.eschema(solution[rel.children[0].name])
    79                 eschema = schema.eschema(term_etype(session, rel.children[0],
       
    80                                                     solution, args))
    67                 rdef = eschema.rdef(rschema)
    81                 rdef = eschema.rdef(rschema)
    68             else:
    82             else:
    69                 rdef = rschema.rdef(solution[rel.children[0].name],
    83                 rdef = rschema.rdef(term_etype(session, rel.children[0],
    70                                     solution[rel.children[1].children[0].name])
    84                                                solution, args),
    71             if not user.matching_groups(rdef.get_groups('read')):
    85                                     term_etype(session, rel.children[1].children[0],
       
    86                                                solution, args))
       
    87             if not session.user.matching_groups(rdef.get_groups('read')):
    72                 # XXX rqlexpr not allowed
    88                 # XXX rqlexpr not allowed
    73                 raise Unauthorized('read', rel.r_type)
    89                 raise Unauthorized('read', rel.r_type)
    74     localchecks = {}
    90     localchecks = {}
    75     # iterate on defined_vars and not on solutions to ignore column aliases
    91     # iterate on defined_vars and not on solutions to ignore column aliases
    76     for varname in rqlst.defined_vars:
    92     for varname in rqlst.defined_vars:
    77         eschema = schema.eschema(solution[varname])
    93         eschema = schema.eschema(solution[varname])
    78         if eschema.final:
    94         if eschema.final:
    79             continue
    95             continue
    80         if not user.matching_groups(eschema.get_groups('read')):
    96         if not session.user.matching_groups(eschema.get_groups('read')):
    81             erqlexprs = eschema.get_rqlexprs('read')
    97             erqlexprs = eschema.get_rqlexprs('read')
    82             if not erqlexprs:
    98             if not erqlexprs:
    83                 ex = Unauthorized('read', solution[varname])
    99                 ex = Unauthorized('read', solution[varname])
    84                 ex.var = varname
   100                 ex.var = varname
    85                 raise ex
   101                 raise ex
   317         the empty tuple key.
   333         the empty tuple key.
   318 
   334 
   319         note: rqlst should not have been simplified at this point
   335         note: rqlst should not have been simplified at this point
   320         """
   336         """
   321         session = self.session
   337         session = self.session
   322         user = session.user
       
   323         schema = self.schema
       
   324         msgs = []
   338         msgs = []
   325         neweids = session.transaction_data.get('neweids', ())
   339         neweids = session.transaction_data.get('neweids', ())
   326         varkwargs = {}
   340         varkwargs = {}
   327         if not session.transaction_data.get('security-rqlst-cache'):
   341         if not session.transaction_data.get('security-rqlst-cache'):
   328             for var in rqlst.defined_vars.itervalues():
   342             for var in rqlst.defined_vars.itervalues():
   340         localchecks = {}
   354         localchecks = {}
   341         restricted_vars = set()
   355         restricted_vars = set()
   342         newsolutions = []
   356         newsolutions = []
   343         for solution in rqlst.solutions:
   357         for solution in rqlst.solutions:
   344             try:
   358             try:
   345                 localcheck = check_read_access(schema, user, rqlst, solution)
   359                 localcheck = check_read_access(session, rqlst, solution, self.args)
   346             except Unauthorized, ex:
   360             except Unauthorized, ex:
   347                 msg = 'remove %s from solutions since %s has no %s access to %s'
   361                 msg = 'remove %s from solutions since %s has no %s access to %s'
   348                 msg %= (solution, user.login, ex.args[0], ex.args[1])
   362                 msg %= (solution, session.user.login, ex.args[0], ex.args[1])
   349                 msgs.append(msg)
   363                 msgs.append(msg)
   350                 LOGGER.info(msg)
   364                 LOGGER.info(msg)
   351             else:
   365             else:
   352                 newsolutions.append(solution)
   366                 newsolutions.append(solution)
   353                 # try to benefit of rqlexpr.check cache for entities which
   367                 # try to benefit of rqlexpr.check cache for entities which