-
Notifications
You must be signed in to change notification settings - Fork 0
/
cameraPermission.go
189 lines (180 loc) · 5.86 KB
/
cameraPermission.go
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
package database
import "database/sql"
// Stores the n:m relation between users and their camera-permissions
func createHasCameraPermissionsTable() error {
if _, err := db.Exec(`
CREATE TABLE
IF NOT EXISTS
hasCameraPermission(
Username VARCHAR(20),
Camera VARCHAR(50),
FOREIGN KEY (Username)
REFERENCES user(Username),
FOREIGN KEY (Camera)
REFERENCES camera(Id)
)`); err != nil {
log.Error("Failed to create hasCameraPermissionsTable: Executing query failed: ", err.Error())
return err
}
return nil
}
// Returns the camera-permissions of an arbitrary user in the form of a slice of strings
// Each slice element references a camera's id to which the user has access to
func GetUserCameraPermissions(username string) ([]string, error) {
query, err := db.Prepare(`
SELECT
Camera
FROM hasCameraPermission
WHERE Username=?
`)
if err != nil {
log.Error("Could not list user camera permissions: failed to prepare query: ", err.Error())
return make([]string, 0), err
}
defer query.Close()
res, err := query.Query(username)
if err != nil {
log.Error("Could not list user switch camera: failed to execute query: ", err.Error())
return make([]string, 0), err
}
defer res.Close()
permissions := make([]string, 0)
for res.Next() {
var permission string
err := res.Scan(&permission)
if err != nil {
log.Error("Could get userCameraPermissions. Failed to scan query: ", err.Error())
return permissions, err
}
permissions = append(permissions, permission)
}
return permissions, nil
}
// Adds a given cameraId to an arbitrary user's camera permissions
// The existence of the camera and the user should be validated beforehand
func AddUserCameraPermission(username string, cameraId string) (modified bool, err error) {
query, err := db.Prepare(`
INSERT INTO
hasCameraPermission(
Username,
Camera
)
VALUES(?, ?)
`)
if err != nil {
log.Error("Failed to add camera permission to user: preparing query failed: ", err.Error())
return false, err
}
defer query.Close()
res, err := query.Exec(username, cameraId)
if err != nil {
log.Error("Failed to add camera permission to user: executing query failed: ", err.Error())
return false, err
}
rowsAffected, err := res.RowsAffected()
if err != nil {
log.Error("Failed to add camera permission to user: failed to retrieve rows affected count: ", err.Error())
return false, err
}
return rowsAffected == 1, nil
}
// Removes a camera permission of an arbitrary user
// An invalid user or an invalid camera id will lead to no deletions
func RemoveUserCameraPermission(username string, cameraId string) (modified bool, err error) {
query, err := db.Prepare(`
DELETE FROM
hasCameraPermission
WHERE Username=? AND Camera=?
`)
if err != nil {
log.Error("Failed to remove user camera permission: preparing query failed: ", err.Error())
return false, err
}
defer query.Close()
res, err := query.Exec(username, cameraId)
if err != nil {
log.Error("Failed to remove user camera permission: executing query failed: ", err.Error())
return false, err
}
rowsAffected, err := res.RowsAffected()
if err != nil {
log.Error("Failed to add camera permission to user: failed to retrieve rows affected count: ", err.Error())
return false, err
}
return rowsAffected == 1, nil
}
// Deletes all occurrences of a given camera-id in the camera permissions
// => Used if a camera is deleted
func RemoveCameraFromPermissions(cameraId string) error {
query, err := db.Prepare(`
DELETE FROM
hasCameraPermission
WHERE Camera=?
`)
if err != nil {
log.Error("Failed to remove camera from permissions: preparing query failed: ", err.Error())
return err
}
defer query.Close()
if _, err := query.Exec(cameraId); err != nil {
log.Error("Failed to remove camera from permissions: executing query failed: ", err.Error())
return err
}
return nil
}
// Removes all camera permissions of a given user, used when deleting a user
// Providing an invalid user will lead to no deletions
func RemoveAllCameraPermissionsOfUser(username string) error {
query, err := db.Prepare(`
DELETE FROM
hasCameraPermission
WHERE Username=?
`)
if err != nil {
log.Error("Failed to remove all camera permissions of user: preparing query failed: ", err.Error())
return err
}
defer query.Close()
if _, err := query.Exec(username); err != nil {
log.Error("Failed to remove all camera permissions of user: executing query failed: ", err.Error())
return err
}
return nil
}
// Returns a boolean indicating whether the user has access to a given camera or not.
// This function just regards database occurrences and does not cover special rules for which the `userHasCameraPermission` function accounts
// => Used in userHasCameraPermission
func UserHasCameraPermissionQuery(username string, cameraId string) (bool, error) {
query, err := db.Prepare(`
SELECT
Camera
FROM hasCameraPermission
WHERE Username=? AND Camera=?
`)
if err != nil {
log.Error("Failed to check user camera permission: preparing query failed: ", err.Error())
return false, err
}
defer query.Close()
if err := query.QueryRow(username, cameraId).Scan(&cameraId); err != nil {
if err == sql.ErrNoRows {
return false, nil
}
log.Error("Failed to check user camera permission: executing query failed: ")
}
return true, nil
}
// Returns a boolean indicating whether a user is in possession of a given camera permission
// Also accounts for the special case that a usaer does not have explicit permission to a camera,
// but is in possession of the `manageRooms` or `*` permission, which grants the user access
func UserHasCameraPermission(username string, cameraId string) (bool, error) {
hasPermission, err := UserHasCameraPermissionQuery(username, cameraId)
if err != nil {
return false, err
}
if hasPermission {
return true, nil
}
// If there is no matching permission, check for the '* | modifyRooms' permissions
return UserHasPermission(username, PermissionModifyRooms)
}