Skip to content

Commit 0e28943

Browse files
committed
Update User Authentication
* Update bindings * Add user authentication sql functions Reference #579
1 parent 4a33fcc commit 0e28943

File tree

3 files changed

+207
-47
lines changed

3 files changed

+207
-47
lines changed

sqlite3.go

+18-12
Original file line numberDiff line numberDiff line change
@@ -1292,9 +1292,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
12921292
return nil, err
12931293
}
12941294

1295-
// Register Authentication Functions into connection
1296-
//
1297-
// Register Authentication function
1295+
// Register: authenticate
12981296
// Authenticate will perform an authentication of the provided username
12991297
// and password against the database.
13001298
//
@@ -1308,38 +1306,46 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
13081306
//
13091307
// If the SQLITE_USER table is not present in the database file, then
13101308
// this interface is a harmless no-op returnning SQLITE_OK.
1311-
if err := conn.RegisterFunc("authenticate", conn.Authenticate, false); err != nil {
1309+
if err := conn.RegisterFunc("authenticate", conn.authenticate, false); err != nil {
13121310
return nil, err
13131311
}
13141312
//
1315-
// Register AuthUserAdd
1316-
// AuthUserAdd can be used (by an admin user only)
1313+
// Register: auth_user_add
1314+
// auth_user_add can be used (by an admin user only)
13171315
// to create a new user. When called on a no-authentication-required
13181316
// database, this routine converts the database into an authentication-
13191317
// required database, automatically makes the added user an
13201318
// administrator, and logs in the current connection as that user.
13211319
// The AuthUserAdd only works for the "main" database, not
13221320
// for any ATTACH-ed databases. Any call to AuthUserAdd by a
13231321
// non-admin user results in an error.
1324-
if err := conn.RegisterFunc("auth_user_add", conn.AuthUserAdd, false); err != nil {
1322+
if err := conn.RegisterFunc("auth_user_add", conn.authUserAdd, false); err != nil {
13251323
return nil, err
13261324
}
13271325
//
1328-
// AuthUserChange can be used to change a users
1326+
// Register: auth_user_change
1327+
// auth_user_change can be used to change a users
13291328
// login credentials or admin privilege. Any user can change their own
13301329
// login credentials. Only an admin user can change another users login
13311330
// credentials or admin privilege setting. No user may change their own
13321331
// admin privilege setting.
1333-
if err := conn.RegisterFunc("auth_user_change", conn.AuthUserChange, false); err != nil {
1332+
if err := conn.RegisterFunc("auth_user_change", conn.authUserChange, false); err != nil {
13341333
return nil, err
13351334
}
13361335
//
1337-
// AuthUserDelete can be used (by an admin user only)
1336+
// Register: auth_user_delete
1337+
// auth_user_delete can be used (by an admin user only)
13381338
// to delete a user. The currently logged-in user cannot be deleted,
13391339
// which guarantees that there is always an admin user and hence that
13401340
// the database cannot be converted into a no-authentication-required
13411341
// database.
1342-
if err := conn.RegisterFunc("auth_user_delete", conn.AuthUserDelete, false); err != nil {
1342+
if err := conn.RegisterFunc("auth_user_delete", conn.authUserDelete, false); err != nil {
1343+
return nil, err
1344+
}
1345+
1346+
// Register: auth_enabled
1347+
// auth_enabled can be used to check if user authentication is enabled
1348+
if err := conn.RegisterFunc("auth_enabled", conn.authEnabled, false); err != nil {
13431349
return nil, err
13441350
}
13451351

@@ -1369,7 +1375,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
13691375
}
13701376

13711377
// Check if User Authentication is Enabled
1372-
authExists := conn.AuthIsEnabled()
1378+
authExists := conn.AuthEnabled()
13731379
if !authExists {
13741380
if err := conn.AuthUserAdd(authUser, authPass, true); err != nil {
13751381
return nil, err

sqlite3_opt_userauth.go

+104-32
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ _sqlite3_user_delete(sqlite3* db, const char* zUsername)
4242
}
4343
4444
static int
45-
_sqlite3_auth_is_enabled(sqlite3* db)
45+
_sqlite3_auth_enabled(sqlite3* db)
4646
{
4747
int exists = -1;
4848
@@ -87,6 +87,26 @@ var (
8787
// If the SQLITE_USER table is not present in the database file, then
8888
// this interface is a harmless no-op returnning SQLITE_OK.
8989
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 {
90110
// Allocate C Variables
91111
cuser := C.CString(username)
92112
cpass := C.CString(password)
@@ -97,15 +117,7 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
97117
C.free(unsafe.Pointer(cpass))
98118
}()
99119

100-
rv := C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password)))
101-
if rv == C.SQLITE_AUTH {
102-
return ErrUnauthorized
103-
}
104-
if rv != C.SQLITE_OK {
105-
return c.lastError()
106-
}
107-
108-
return nil
120+
return int(C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password))))
109121
}
110122

111123
// AuthUserAdd can be used (by an admin user only)
@@ -124,7 +136,7 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
124136

125137
rv := c.authUserAdd(username, password, isAdmin)
126138
switch rv {
127-
case C.SQLITE_AUTH:
139+
case C.SQLITE_ERROR, C.SQLITE_AUTH:
128140
return ErrAdminRequired
129141
case C.SQLITE_OK:
130142
return nil
@@ -133,6 +145,19 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
133145
}
134146
}
135147

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)
136161
func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
137162
// Allocate C Variables
138163
cuser := C.CString(username)
@@ -158,6 +183,34 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
158183
isAdmin = 1
159184
}
160185

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 {
161214
// Allocate C Variables
162215
cuser := C.CString(username)
163216
cpass := C.CString(password)
@@ -168,15 +221,7 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
168221
C.free(unsafe.Pointer(cpass))
169222
}()
170223

171-
rv := C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(isAdmin))
172-
if rv == C.SQLITE_AUTH {
173-
return ErrAdminRequired
174-
}
175-
if rv != C.SQLITE_OK {
176-
return c.lastError()
177-
}
178-
179-
return nil
224+
return int(C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(admin)))
180225
}
181226

182227
// AuthUserDelete can be used (by an admin user only)
@@ -185,6 +230,29 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
185230
// the database cannot be converted into a no-authentication-required
186231
// database.
187232
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 {
188256
// Allocate C Variables
189257
cuser := C.CString(username)
190258

@@ -193,25 +261,29 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
193261
C.free(unsafe.Pointer(cuser))
194262
}()
195263

196-
rv := C._sqlite3_user_delete(c.db, cuser)
197-
if rv == SQLITE_AUTH {
198-
return ErrAdminRequired
199-
}
200-
if rv != C.SQLITE_OK {
201-
return c.lastError()
202-
}
203-
204-
return nil
264+
return int(C._sqlite3_user_delete(c.db, cuser))
205265
}
206266

207-
// Check is database is protected by user authentication
208-
func (c *SQLiteConn) AuthIsEnabled() (exists bool) {
209-
rv := C._sqlite3_auth_is_enabled(c.db)
267+
// AuthEnabled checks if the database is protected by user authentication
268+
func (c *SQLiteConn) AuthEnabled() (exists bool) {
269+
rv := c.authEnabled()
210270
if rv == 1 {
211271
exists = true
212272
}
213273

214274
return
215275
}
216276

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+
217289
// EOF

sqlite3_opt_userauth_omit.go

+85-3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
2929
return nil
3030
}
3131

32+
// authenticate provides the actual authentication to SQLite.
33+
// This is not exported for usage in Go.
34+
// It is however exported for usage within SQL by the user.
35+
//
36+
// Returns:
37+
// C.SQLITE_OK (0)
38+
// C.SQLITE_ERROR (1)
39+
// C.SQLITE_AUTH (23)
40+
func (c *SQLiteConn) authenticate(username, password string) int {
41+
// NOOP
42+
return 0
43+
}
44+
3245
// AuthUserAdd can be used (by an admin user only)
3346
// to create a new user. When called on a no-authentication-required
3447
// database, this routine converts the database into an authentication-
@@ -42,6 +55,24 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
4255
return nil
4356
}
4457

58+
// authUserAdd enables the User Authentication if not enabled.
59+
// Otherwise it will add a user.
60+
//
61+
// When user authentication is already enabled then this function
62+
// can only be called by an admin.
63+
//
64+
// This is not exported for usage in Go.
65+
// It is however exported for usage within SQL by the user.
66+
//
67+
// Returns:
68+
// C.SQLITE_OK (0)
69+
// C.SQLITE_ERROR (1)
70+
// C.SQLITE_AUTH (23)
71+
func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
72+
// NOOP
73+
return 0
74+
}
75+
4576
// AuthUserChange can be used to change a users
4677
// login credentials or admin privilege. Any user can change their own
4778
// login credentials. Only an admin user can change another users login
@@ -52,6 +83,27 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
5283
return nil
5384
}
5485

86+
// authUserChange allows to modify a user.
87+
// Users can change their own password.
88+
//
89+
// Only admins can change passwords for other users
90+
// and modify the admin flag.
91+
//
92+
// The admin flag of the current logged in user cannot be changed.
93+
// THis ensures that their is always an admin.
94+
//
95+
// This is not exported for usage in Go.
96+
// It is however exported for usage within SQL by the user.
97+
//
98+
// Returns:
99+
// C.SQLITE_OK (0)
100+
// C.SQLITE_ERROR (1)
101+
// C.SQLITE_AUTH (23)
102+
func (c *SQLiteConn) authUserChange(username, password string, admin int) int {
103+
// NOOP
104+
return 0
105+
}
106+
55107
// AuthUserDelete can be used (by an admin user only)
56108
// to delete a user. The currently logged-in user cannot be deleted,
57109
// which guarantees that there is always an admin user and hence that
@@ -62,9 +114,39 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
62114
return nil
63115
}
64116

65-
// Check is database is protected by user authentication
66-
func (c *SQLiteConn) AuthIsEnabled() (exists bool) {
67-
return
117+
// authUserDelete can be used to delete a user.
118+
//
119+
// This function can only be executed by an admin.
120+
//
121+
// This is not exported for usage in Go.
122+
// It is however exported for usage within SQL by the user.
123+
//
124+
// Returns:
125+
// C.SQLITE_OK (0)
126+
// C.SQLITE_ERROR (1)
127+
// C.SQLITE_AUTH (23)
128+
func (c *SQLiteConn) authUserDelete(username string) int {
129+
// NOOP
130+
return 0
131+
}
132+
133+
// AuthEnabled checks if the database is protected by user authentication
134+
func (c *SQLiteConn) AuthEnabled() (exists bool) {
135+
// NOOP
136+
return false
137+
}
138+
139+
// authEnabled perform the actual check for user authentication.
140+
//
141+
// This is not exported for usage in Go.
142+
// It is however exported for usage within SQL by the user.
143+
//
144+
// Returns:
145+
// 0 - Disabled
146+
// 1 - Enabled
147+
func (c *SQLiteConn) authEnabled() int {
148+
// NOOP
149+
return 0
68150
}
69151

70152
// EOF

0 commit comments

Comments
 (0)