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