OSDN Git Service

add sqlite vendor (#48)
[bytom/vapor.git] / vendor / github.com / mattn / go-sqlite3 / sqlite3_opt_userauth.go
1 // Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
2 //
3 // Use of this source code is governed by an MIT-style
4 // license that can be found in the LICENSE file.
5
6 // +build sqlite_userauth
7
8 package sqlite3
9
10 /*
11 #cgo CFLAGS: -DSQLITE_USER_AUTHENTICATION
12 #cgo LDFLAGS: -lm
13 #ifndef USE_LIBSQLITE3
14 #include <sqlite3-binding.h>
15 #else
16 #include <sqlite3.h>
17 #endif
18 #include <stdlib.h>
19
20 static int
21 _sqlite3_user_authenticate(sqlite3* db, const char* zUsername, const char* aPW, int nPW)
22 {
23   return sqlite3_user_authenticate(db, zUsername, aPW, nPW);
24 }
25
26 static int
27 _sqlite3_user_add(sqlite3* db, const char* zUsername, const char* aPW, int nPW, int isAdmin)
28 {
29   return sqlite3_user_add(db, zUsername, aPW, nPW, isAdmin);
30 }
31
32 static int
33 _sqlite3_user_change(sqlite3* db, const char* zUsername, const char* aPW, int nPW, int isAdmin)
34 {
35   return sqlite3_user_change(db, zUsername, aPW, nPW, isAdmin);
36 }
37
38 static int
39 _sqlite3_user_delete(sqlite3* db, const char* zUsername)
40 {
41   return sqlite3_user_delete(db, zUsername);
42 }
43
44 static int
45 _sqlite3_auth_enabled(sqlite3* db)
46 {
47         int exists = -1;
48
49         sqlite3_stmt *stmt;
50         sqlite3_prepare_v2(db, "select count(type) from sqlite_master WHERE type='table' and name='sqlite_user';", -1, &stmt, NULL);
51
52         while ( sqlite3_step(stmt) == SQLITE_ROW) {
53                 exists = sqlite3_column_int(stmt, 0);
54         }
55
56         sqlite3_finalize(stmt);
57
58         return exists;
59 }
60 */
61 import "C"
62 import (
63         "errors"
64         "unsafe"
65 )
66
67 const (
68         SQLITE_AUTH = C.SQLITE_AUTH
69 )
70
71 var (
72         ErrUnauthorized  = errors.New("SQLITE_AUTH: Unauthorized")
73         ErrAdminRequired = errors.New("SQLITE_AUTH: Unauthorized; Admin Privileges Required")
74 )
75
76 // Authenticate will perform an authentication of the provided username
77 // and password against the database.
78 //
79 // If a database contains the SQLITE_USER table, then the
80 // call to Authenticate must be invoked with an
81 // appropriate username and password prior to enable read and write
82 //access to the database.
83 //
84 // Return SQLITE_OK on success or SQLITE_ERROR if the username/password
85 // combination is incorrect or unknown.
86 //
87 // If the SQLITE_USER table is not present in the database file, then
88 // this interface is a harmless no-op returnning SQLITE_OK.
89 func (c *SQLiteConn) Authenticate(username, password string) error {
90         rv := c.authenticate(username, password)
91         switch rv {
92         case C.SQLITE_ERROR, C.SQLITE_AUTH:
93                 return ErrUnauthorized
94         case C.SQLITE_OK:
95                 return nil
96         default:
97                 return c.lastError()
98         }
99 }
100
101 // authenticate provides the actual authentication to SQLite.
102 // This is not exported for usage in Go.
103 // It is however exported for usage within SQL by the user.
104 //
105 // Returns:
106 //      C.SQLITE_OK (0)
107 //      C.SQLITE_ERROR (1)
108 //  C.SQLITE_AUTH (23)
109 func (c *SQLiteConn) authenticate(username, password string) int {
110         // Allocate C Variables
111         cuser := C.CString(username)
112         cpass := C.CString(password)
113
114         // Free C Variables
115         defer func() {
116                 C.free(unsafe.Pointer(cuser))
117                 C.free(unsafe.Pointer(cpass))
118         }()
119
120         return int(C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password))))
121 }
122
123 // AuthUserAdd can be used (by an admin user only)
124 // to create a new user. When called on a no-authentication-required
125 // database, this routine converts the database into an authentication-
126 // required database, automatically makes the added user an
127 // administrator, and logs in the current connection as that user.
128 // The AuthUserAdd only works for the "main" database, not
129 // for any ATTACH-ed databases. Any call to AuthUserAdd by a
130 // non-admin user results in an error.
131 func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
132         isAdmin := 0
133         if admin {
134                 isAdmin = 1
135         }
136
137         rv := c.authUserAdd(username, password, isAdmin)
138         switch rv {
139         case C.SQLITE_ERROR, C.SQLITE_AUTH:
140                 return ErrAdminRequired
141         case C.SQLITE_OK:
142                 return nil
143         default:
144                 return c.lastError()
145         }
146 }
147
148 // authUserAdd enables the User Authentication if not enabled.
149 // Otherwise it will add a user.
150 //
151 // When user authentication is already enabled then this function
152 // can only be called by an admin.
153 //
154 // This is not exported for usage in Go.
155 // It is however exported for usage within SQL by the user.
156 //
157 // Returns:
158 //      C.SQLITE_OK (0)
159 //      C.SQLITE_ERROR (1)
160 //  C.SQLITE_AUTH (23)
161 func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
162         // Allocate C Variables
163         cuser := C.CString(username)
164         cpass := C.CString(password)
165
166         // Free C Variables
167         defer func() {
168                 C.free(unsafe.Pointer(cuser))
169                 C.free(unsafe.Pointer(cpass))
170         }()
171
172         return int(C._sqlite3_user_add(c.db, cuser, cpass, C.int(len(password)), C.int(admin)))
173 }
174
175 // AuthUserChange can be used to change a users
176 // login credentials or admin privilege.  Any user can change their own
177 // login credentials. Only an admin user can change another users login
178 // credentials or admin privilege setting. No user may change their own
179 // admin privilege setting.
180 func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error {
181         isAdmin := 0
182         if admin {
183                 isAdmin = 1
184         }
185
186         rv := c.authUserChange(username, password, isAdmin)
187         switch rv {
188         case C.SQLITE_ERROR, C.SQLITE_AUTH:
189                 return ErrAdminRequired
190         case C.SQLITE_OK:
191                 return nil
192         default:
193                 return c.lastError()
194         }
195 }
196
197 // authUserChange allows to modify a user.
198 // Users can change their own password.
199 //
200 // Only admins can change passwords for other users
201 // and modify the admin flag.
202 //
203 // The admin flag of the current logged in user cannot be changed.
204 // THis ensures that their is always an admin.
205 //
206 // This is not exported for usage in Go.
207 // It is however exported for usage within SQL by the user.
208 //
209 // Returns:
210 //      C.SQLITE_OK (0)
211 //      C.SQLITE_ERROR (1)
212 //  C.SQLITE_AUTH (23)
213 func (c *SQLiteConn) authUserChange(username, password string, admin int) int {
214         // Allocate C Variables
215         cuser := C.CString(username)
216         cpass := C.CString(password)
217
218         // Free C Variables
219         defer func() {
220                 C.free(unsafe.Pointer(cuser))
221                 C.free(unsafe.Pointer(cpass))
222         }()
223
224         return int(C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(admin)))
225 }
226
227 // AuthUserDelete can be used (by an admin user only)
228 // to delete a user. The currently logged-in user cannot be deleted,
229 // which guarantees that there is always an admin user and hence that
230 // the database cannot be converted into a no-authentication-required
231 // database.
232 func (c *SQLiteConn) AuthUserDelete(username string) error {
233         rv := c.authUserDelete(username)
234         switch rv {
235         case C.SQLITE_ERROR, C.SQLITE_AUTH:
236                 return ErrAdminRequired
237         case C.SQLITE_OK:
238                 return nil
239         default:
240                 return c.lastError()
241         }
242 }
243
244 // authUserDelete can be used to delete a user.
245 //
246 // This function can only be executed by an admin.
247 //
248 // This is not exported for usage in Go.
249 // It is however exported for usage within SQL by the user.
250 //
251 // Returns:
252 //      C.SQLITE_OK (0)
253 //      C.SQLITE_ERROR (1)
254 //  C.SQLITE_AUTH (23)
255 func (c *SQLiteConn) authUserDelete(username string) int {
256         // Allocate C Variables
257         cuser := C.CString(username)
258
259         // Free C Variables
260         defer func() {
261                 C.free(unsafe.Pointer(cuser))
262         }()
263
264         return int(C._sqlite3_user_delete(c.db, cuser))
265 }
266
267 // AuthEnabled checks if the database is protected by user authentication
268 func (c *SQLiteConn) AuthEnabled() (exists bool) {
269         rv := c.authEnabled()
270         if rv == 1 {
271                 exists = true
272         }
273
274         return
275 }
276
277 // authEnabled perform the actual check for user authentication.
278 //
279 // This is not exported for usage in Go.
280 // It is however exported for usage within SQL by the user.
281 //
282 // Returns:
283 //      0 - Disabled
284 //  1 - Enabled
285 func (c *SQLiteConn) authEnabled() int {
286         return int(C._sqlite3_auth_enabled(c.db))
287 }
288
289 // EOF