Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download
Views: 39538
1
###############################################################################
2
#
3
# CoCalc: Collaborative Calculation in the Cloud
4
#
5
# Copyright (C) 2016, Sagemath Inc.
6
#
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#
20
###############################################################################
21
22
###
23
Given a query, do some validation on it, and also possibly fill in fields
24
in the query that are determined by functional calls in the schema.
25
If validation fails, this returns an error message; if validation succeeds,
26
it returns undefined. The input query may be mutated in place.
27
###
28
29
misc = require('./misc')
30
schema = require('./schema')
31
32
exports.validate_client_query = validate_client_query = (query, account_id) ->
33
if misc.is_array(query)
34
# it's an array of queries; validate each separately.
35
for q in query
36
err = validate_client_query(q)
37
if err?
38
return err
39
return
40
41
warn = (err) ->
42
console.warn("invalid client query: #{err}; query=#{misc.to_json(query)}")
43
return err
44
45
v = misc.keys(query)
46
if v.length != 1
47
return warn('must specify exactly one key in the query')
48
table = v[0]
49
# Check that the table is in the schema
50
user_query = schema.SCHEMA[table]?.user_query
51
if not user_query?
52
return warn("no user queries of '#{table}' allowed")
53
pattern = query[table]
54
if misc.is_array(pattern)
55
# get queries are an array or a pattern with a null leaf
56
if pattern.length > 1
57
return warn('array of length > 1 not yet implemented')
58
pattern = pattern[0]
59
is_set_query = false
60
else
61
# set queries do not have any null leafs
62
is_set_query = not misc.has_null_leaf(pattern)
63
64
if is_set_query
65
S = user_query.set
66
if not S?
67
return warn("no user set queries of '#{table}' allowed")
68
else
69
S = user_query.get
70
if not S?
71
return warn("no user get queries of '#{table}' allowed")
72
73
for k,v of pattern
74
# Verify that every key of the pattern is in the schema
75
f = S.fields[k]
76
if f == undefined # crucial: we don't just need "f?" to be true
77
if is_set_query
78
return warn("not allowed to set key '#{k}' of '#{table}'")
79
else
80
return warn("not allowed to access key '#{k}' of '#{table}'")
81
82
# Fill in any function call parts of the pattern
83
for k, f of S.fields
84
if typeof(f) == 'function'
85
pattern[k] = f(pattern, schema.client_db, account_id)
86
87
if S.required_fields?
88
for k, v of S.required_fields
89
if not pattern[k]?
90
return warn("field '#{k}' must be set")
91
92
return
93
94