/
snis.lua
166 lines (129 loc) · 4.09 KB
/
snis.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
local cjson = require "cjson"
local Set = require "pl.Set"
local function invalidate_cache(self, old_entity, err, err_t)
if err then
return nil, err, err_t
end
if old_entity then
self:post_crud_event("update", old_entity)
end
end
local _SNIs = {}
-- Truthy if all the names on the list don't exist on the db or exist but are
-- associated to the given certificate
-- if the cert id is nil, all encountered snis will return an error
function _SNIs:check_list_is_new(name_list, valid_cert_id)
for i=1, #name_list do
local name = name_list[i]
local row, err, err_t = self:select_by_name(name)
if err then
return nil, err, err_t
end
if row and row.certificate.id ~= valid_cert_id then
local msg = name ..
" already associated with existing " ..
"certificate '" .. row.certificate.id .. "'"
local err_t = self.errors:schema_violation({ snis = msg })
return nil, tostring(err_t), err_t
end
end
return true
end
-- Creates one instance of SNI for each name in name_list
-- All created instances will be associated to the given certificate
function _SNIs:insert_list(cert_pk, name_list)
for _, name in ipairs(name_list) do
local _, err, err_t = self:insert({
name = name,
certificate = cert_pk,
})
if err then
return nil, err, err_t
end
end
return true
end
-- Deletes all SNIs on the given name list
function _SNIs:delete_list(name_list)
local err_list = {}
local errors_len = 0
local first_err_t = nil
for i = 1, #name_list do
local ok, err, err_t = self:delete_by_name(name_list[i])
if not ok then
errors_len = errors_len + 1
err_list[errors_len] = err
first_err_t = first_err_t or err_t
end
end
if errors_len > 0 then
return nil, table.concat(err_list, ","), first_err_t
end
return true
end
-- Returns the name list for a given certificate
function _SNIs:list_for_certificate(cert_pk)
local name_list = setmetatable({}, cjson.empty_array_mt)
local rows, err, err_t = self:page_for_certificate(cert_pk)
if err then
return nil, err, err_t
end
for i = 1, #rows do
name_list[i] = rows[i].name
end
table.sort(name_list)
return name_list
end
-- Replaces the names of a given certificate
-- It does not try to insert SNIs which are already inserted
-- It does not try to delete SNIs which don't exist
function _SNIs:update_list(cert_pk, new_list)
-- Get the names currently associated to the certificate
local current_list, err, err_t = self:list_for_certificate(cert_pk)
if not current_list then
return nil, err, err_t
end
local delete_list = Set.values(Set(current_list) - Set(new_list))
local insert_list = Set.values(Set(new_list) - Set(current_list))
local ok, err, err_t = self:insert_list(cert_pk, insert_list)
if not ok then
return nil, err, err_t
end
-- ignoring errors here
-- returning 4xx here risks invalid states and is confusing to the user
self:delete_list(delete_list)
return true
end
-- invalidates the *old* name when updating it to a new name
function _SNIs:update(pk, entity)
local _, err, err_t = invalidate_cache(self, self:select(pk))
if err then
return nil, err, err_t
end
return self.super.update(self, pk, entity)
end
-- invalidates the *old* name when updating it to a new name
function _SNIs:update_by_name(name, entity)
local _, err, err_t = invalidate_cache(self, self:select_by_name(name))
if err then
return nil, err, err_t
end
return self.super.update_by_name(self, name, entity)
end
-- invalidates the *old* name when updating it to a new name
function _SNIs:upsert(pk, entity)
local _, err, err_t = invalidate_cache(self, self:select(pk))
if err then
return nil, err, err_t
end
return self.super.upsert(self, pk, entity)
end
-- invalidates the *old* name when updating it to a new name
function _SNIs:upsert_by_name(name, entity)
local _, err, err_t = invalidate_cache(self, self:select_by_name(name))
if err then
return nil, err, err_t
end
return self.super.upsert_by_name(self, name, entity)
end
return _SNIs