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 |
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 |