aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGert-Jan Timmer <gjr.timmer@gmail.com>2018-06-01 11:28:04 +0200
committerGert-Jan Timmer <gjr.timmer@gmail.com>2018-06-01 11:28:04 +0200
commit0e289439a27f126dcc2fa96b2dd2d4cc9ecbbf7c (patch)
tree6616049900fbb9a6c45bf26a92a35d151b3aa1e6
parentStash (diff)
downloadgolite-0e289439a27f126dcc2fa96b2dd2d4cc9ecbbf7c.tar.gz
golite-0e289439a27f126dcc2fa96b2dd2d4cc9ecbbf7c.tar.xz
Update User Authentication
* Update bindings * Add user authentication sql functions Reference #579
-rw-r--r--sqlite3.go30
-rw-r--r--sqlite3_opt_userauth.go136
-rw-r--r--sqlite3_opt_userauth_omit.go88
3 files changed, 207 insertions, 47 deletions
diff --git a/sqlite3.go b/sqlite3.go
index 79b96ab..4b33726 100644
--- a/sqlite3.go
+++ b/sqlite3.go
@@ -1292,9 +1292,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
return nil, err
}
- // Register Authentication Functions into connection
- //
- // Register Authentication function
+ // Register: authenticate
// Authenticate will perform an authentication of the provided username
// and password against the database.
//
@@ -1308,12 +1306,12 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
//
// If the SQLITE_USER table is not present in the database file, then
// this interface is a harmless no-op returnning SQLITE_OK.
- if err := conn.RegisterFunc("authenticate", conn.Authenticate, false); err != nil {
+ if err := conn.RegisterFunc("authenticate", conn.authenticate, false); err != nil {
return nil, err
}
//
- // Register AuthUserAdd
- // AuthUserAdd can be used (by an admin user only)
+ // Register: auth_user_add
+ // auth_user_add can be used (by an admin user only)
// to create a new user. When called on a no-authentication-required
// database, this routine converts the database into an authentication-
// required database, automatically makes the added user an
@@ -1321,25 +1319,33 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
// The AuthUserAdd only works for the "main" database, not
// for any ATTACH-ed databases. Any call to AuthUserAdd by a
// non-admin user results in an error.
- if err := conn.RegisterFunc("auth_user_add", conn.AuthUserAdd, false); err != nil {
+ if err := conn.RegisterFunc("auth_user_add", conn.authUserAdd, false); err != nil {
return nil, err
}
//
- // AuthUserChange can be used to change a users
+ // Register: auth_user_change
+ // auth_user_change can be used to change a users
// login credentials or admin privilege. Any user can change their own
// login credentials. Only an admin user can change another users login
// credentials or admin privilege setting. No user may change their own
// admin privilege setting.
- if err := conn.RegisterFunc("auth_user_change", conn.AuthUserChange, false); err != nil {
+ if err := conn.RegisterFunc("auth_user_change", conn.authUserChange, false); err != nil {
return nil, err
}
//
- // AuthUserDelete can be used (by an admin user only)
+ // Register: auth_user_delete
+ // auth_user_delete can be used (by an admin user only)
// to delete a user. The currently logged-in user cannot be deleted,
// which guarantees that there is always an admin user and hence that
// the database cannot be converted into a no-authentication-required
// database.
- if err := conn.RegisterFunc("auth_user_delete", conn.AuthUserDelete, false); err != nil {
+ if err := conn.RegisterFunc("auth_user_delete", conn.authUserDelete, false); err != nil {
+ return nil, err
+ }
+
+ // Register: auth_enabled
+ // auth_enabled can be used to check if user authentication is enabled
+ if err := conn.RegisterFunc("auth_enabled", conn.authEnabled, false); err != nil {
return nil, err
}
@@ -1369,7 +1375,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
}
// Check if User Authentication is Enabled
- authExists := conn.AuthIsEnabled()
+ authExists := conn.AuthEnabled()
if !authExists {
if err := conn.AuthUserAdd(authUser, authPass, true); err != nil {
return nil, err
diff --git a/sqlite3_opt_userauth.go b/sqlite3_opt_userauth.go
index 197938b..94203b3 100644
--- a/sqlite3_opt_userauth.go
+++ b/sqlite3_opt_userauth.go
@@ -42,7 +42,7 @@ _sqlite3_user_delete(sqlite3* db, const char* zUsername)
}
static int
-_sqlite3_auth_is_enabled(sqlite3* db)
+_sqlite3_auth_enabled(sqlite3* db)
{
int exists = -1;
@@ -87,6 +87,26 @@ var (
// If the SQLITE_USER table is not present in the database file, then
// this interface is a harmless no-op returnning SQLITE_OK.
func (c *SQLiteConn) Authenticate(username, password string) error {
+ rv := c.authenticate(username, password)
+ switch rv {
+ case C.SQLITE_ERROR, C.SQLITE_AUTH:
+ return ErrUnauthorized
+ case C.SQLITE_OK:
+ return nil
+ default:
+ return c.lastError()
+ }
+}
+
+// authenticate provides the actual authentication to SQLite.
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+// C.SQLITE_OK (0)
+// C.SQLITE_ERROR (1)
+// C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authenticate(username, password string) int {
// Allocate C Variables
cuser := C.CString(username)
cpass := C.CString(password)
@@ -97,15 +117,7 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
C.free(unsafe.Pointer(cpass))
}()
- rv := C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password)))
- if rv == C.SQLITE_AUTH {
- return ErrUnauthorized
- }
- if rv != C.SQLITE_OK {
- return c.lastError()
- }
-
- return nil
+ return int(C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password))))
}
// AuthUserAdd can be used (by an admin user only)
@@ -124,7 +136,7 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
rv := c.authUserAdd(username, password, isAdmin)
switch rv {
- case C.SQLITE_AUTH:
+ case C.SQLITE_ERROR, C.SQLITE_AUTH:
return ErrAdminRequired
case C.SQLITE_OK:
return nil
@@ -133,6 +145,19 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
}
}
+// authUserAdd enables the User Authentication if not enabled.
+// Otherwise it will add a user.
+//
+// When user authentication is already enabled then this function
+// can only be called by an admin.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+// C.SQLITE_OK (0)
+// C.SQLITE_ERROR (1)
+// C.SQLITE_AUTH (23)
func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
// Allocate C Variables
cuser := C.CString(username)
@@ -158,6 +183,34 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
isAdmin = 1
}
+ rv := c.authUserChange(username, password, isAdmin)
+ switch rv {
+ case C.SQLITE_ERROR, C.SQLITE_AUTH:
+ return ErrAdminRequired
+ case C.SQLITE_OK:
+ return nil
+ default:
+ return c.lastError()
+ }
+}
+
+// authUserChange allows to modify a user.
+// Users can change their own password.
+//
+// Only admins can change passwords for other users
+// and modify the admin flag.
+//
+// The admin flag of the current logged in user cannot be changed.
+// THis ensures that their is always an admin.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+// C.SQLITE_OK (0)
+// C.SQLITE_ERROR (1)
+// C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authUserChange(username, password string, admin int) int {
// Allocate C Variables
cuser := C.CString(username)
cpass := C.CString(password)
@@ -168,15 +221,7 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
C.free(unsafe.Pointer(cpass))
}()
- rv := C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(isAdmin))
- if rv == C.SQLITE_AUTH {
- return ErrAdminRequired
- }
- if rv != C.SQLITE_OK {
- return c.lastError()
- }
-
- return nil
+ return int(C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(admin)))
}
// AuthUserDelete can be used (by an admin user only)
@@ -185,6 +230,29 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
// the database cannot be converted into a no-authentication-required
// database.
func (c *SQLiteConn) AuthUserDelete(username string) error {
+ rv := c.authUserDelete(username)
+ switch rv {
+ case C.SQLITE_ERROR, C.SQLITE_AUTH:
+ return ErrAdminRequired
+ case C.SQLITE_OK:
+ return nil
+ default:
+ return c.lastError()
+ }
+}
+
+// authUserDelete can be used to delete a user.
+//
+// This function can only be executed by an admin.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+// C.SQLITE_OK (0)
+// C.SQLITE_ERROR (1)
+// C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authUserDelete(username string) int {
// Allocate C Variables
cuser := C.CString(username)
@@ -193,20 +261,12 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
C.free(unsafe.Pointer(cuser))
}()
- rv := C._sqlite3_user_delete(c.db, cuser)
- if rv == SQLITE_AUTH {
- return ErrAdminRequired
- }
- if rv != C.SQLITE_OK {
- return c.lastError()
- }
-
- return nil
+ return int(C._sqlite3_user_delete(c.db, cuser))
}
-// Check is database is protected by user authentication
-func (c *SQLiteConn) AuthIsEnabled() (exists bool) {
- rv := C._sqlite3_auth_is_enabled(c.db)
+// AuthEnabled checks if the database is protected by user authentication
+func (c *SQLiteConn) AuthEnabled() (exists bool) {
+ rv := c.authEnabled()
if rv == 1 {
exists = true
}
@@ -214,4 +274,16 @@ func (c *SQLiteConn) AuthIsEnabled() (exists bool) {
return
}
+// authEnabled perform the actual check for user authentication.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+// 0 - Disabled
+// 1 - Enabled
+func (c *SQLiteConn) authEnabled() int {
+ return int(C._sqlite3_auth_enabled(c.db))
+}
+
// EOF
diff --git a/sqlite3_opt_userauth_omit.go b/sqlite3_opt_userauth_omit.go
index 3d1c758..302cd57 100644
--- a/sqlite3_opt_userauth_omit.go
+++ b/sqlite3_opt_userauth_omit.go
@@ -29,6 +29,19 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
return nil
}
+// authenticate provides the actual authentication to SQLite.
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+// C.SQLITE_OK (0)
+// C.SQLITE_ERROR (1)
+// C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authenticate(username, password string) int {
+ // NOOP
+ return 0
+}
+
// AuthUserAdd can be used (by an admin user only)
// to create a new user. When called on a no-authentication-required
// database, this routine converts the database into an authentication-
@@ -42,6 +55,24 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
return nil
}
+// authUserAdd enables the User Authentication if not enabled.
+// Otherwise it will add a user.
+//
+// When user authentication is already enabled then this function
+// can only be called by an admin.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+// C.SQLITE_OK (0)
+// C.SQLITE_ERROR (1)
+// C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
+ // NOOP
+ return 0
+}
+
// AuthUserChange can be used to change a users
// login credentials or admin privilege. Any user can change their own
// 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
return nil
}
+// authUserChange allows to modify a user.
+// Users can change their own password.
+//
+// Only admins can change passwords for other users
+// and modify the admin flag.
+//
+// The admin flag of the current logged in user cannot be changed.
+// THis ensures that their is always an admin.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+// C.SQLITE_OK (0)
+// C.SQLITE_ERROR (1)
+// C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authUserChange(username, password string, admin int) int {
+ // NOOP
+ return 0
+}
+
// AuthUserDelete can be used (by an admin user only)
// to delete a user. The currently logged-in user cannot be deleted,
// which guarantees that there is always an admin user and hence that
@@ -62,9 +114,39 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
return nil
}
-// Check is database is protected by user authentication
-func (c *SQLiteConn) AuthIsEnabled() (exists bool) {
- return
+// authUserDelete can be used to delete a user.
+//
+// This function can only be executed by an admin.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+// C.SQLITE_OK (0)
+// C.SQLITE_ERROR (1)
+// C.SQLITE_AUTH (23)
+func (c *SQLiteConn) authUserDelete(username string) int {
+ // NOOP
+ return 0
+}
+
+// AuthEnabled checks if the database is protected by user authentication
+func (c *SQLiteConn) AuthEnabled() (exists bool) {
+ // NOOP
+ return false
+}
+
+// authEnabled perform the actual check for user authentication.
+//
+// This is not exported for usage in Go.
+// It is however exported for usage within SQL by the user.
+//
+// Returns:
+// 0 - Disabled
+// 1 - Enabled
+func (c *SQLiteConn) authEnabled() int {
+ // NOOP
+ return 0
}
// EOF