forked from mirror/go-sqlite3
Update User Authentication
* Update bindings * Add user authentication sql functions Reference #579
This commit is contained in:
parent
4a33fcc1d2
commit
0e289439a2
30
sqlite3.go
30
sqlite3.go
|
@ -1292,9 +1292,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register Authentication Functions into connection
|
// Register: authenticate
|
||||||
//
|
|
||||||
// Register Authentication function
|
|
||||||
// Authenticate will perform an authentication of the provided username
|
// Authenticate will perform an authentication of the provided username
|
||||||
// and password against the database.
|
// 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
|
// If the SQLITE_USER table is not present in the database file, then
|
||||||
// this interface is a harmless no-op returnning SQLITE_OK.
|
// 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
|
return nil, err
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Register AuthUserAdd
|
// Register: auth_user_add
|
||||||
// AuthUserAdd can be used (by an admin user only)
|
// auth_user_add can be used (by an admin user only)
|
||||||
// to create a new user. When called on a no-authentication-required
|
// to create a new user. When called on a no-authentication-required
|
||||||
// database, this routine converts the database into an authentication-
|
// database, this routine converts the database into an authentication-
|
||||||
// required database, automatically makes the added user an
|
// 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
|
// The AuthUserAdd only works for the "main" database, not
|
||||||
// for any ATTACH-ed databases. Any call to AuthUserAdd by a
|
// for any ATTACH-ed databases. Any call to AuthUserAdd by a
|
||||||
// non-admin user results in an error.
|
// 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
|
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 or admin privilege. Any user can change their own
|
||||||
// login credentials. Only an admin user can change another users login
|
// login credentials. Only an admin user can change another users login
|
||||||
// credentials or admin privilege setting. No user may change their own
|
// credentials or admin privilege setting. No user may change their own
|
||||||
// admin privilege setting.
|
// 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
|
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,
|
// to delete a user. The currently logged-in user cannot be deleted,
|
||||||
// which guarantees that there is always an admin user and hence that
|
// which guarantees that there is always an admin user and hence that
|
||||||
// the database cannot be converted into a no-authentication-required
|
// the database cannot be converted into a no-authentication-required
|
||||||
// database.
|
// 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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1369,7 +1375,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if User Authentication is Enabled
|
// Check if User Authentication is Enabled
|
||||||
authExists := conn.AuthIsEnabled()
|
authExists := conn.AuthEnabled()
|
||||||
if !authExists {
|
if !authExists {
|
||||||
if err := conn.AuthUserAdd(authUser, authPass, true); err != nil {
|
if err := conn.AuthUserAdd(authUser, authPass, true); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -42,7 +42,7 @@ _sqlite3_user_delete(sqlite3* db, const char* zUsername)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_sqlite3_auth_is_enabled(sqlite3* db)
|
_sqlite3_auth_enabled(sqlite3* db)
|
||||||
{
|
{
|
||||||
int exists = -1;
|
int exists = -1;
|
||||||
|
|
||||||
|
@ -87,6 +87,26 @@ var (
|
||||||
// If the SQLITE_USER table is not present in the database file, then
|
// If the SQLITE_USER table is not present in the database file, then
|
||||||
// this interface is a harmless no-op returnning SQLITE_OK.
|
// this interface is a harmless no-op returnning SQLITE_OK.
|
||||||
func (c *SQLiteConn) Authenticate(username, password string) error {
|
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
|
// Allocate C Variables
|
||||||
cuser := C.CString(username)
|
cuser := C.CString(username)
|
||||||
cpass := C.CString(password)
|
cpass := C.CString(password)
|
||||||
|
@ -97,15 +117,7 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
|
||||||
C.free(unsafe.Pointer(cpass))
|
C.free(unsafe.Pointer(cpass))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rv := C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password)))
|
return int(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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthUserAdd can be used (by an admin user only)
|
// 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)
|
rv := c.authUserAdd(username, password, isAdmin)
|
||||||
switch rv {
|
switch rv {
|
||||||
case C.SQLITE_AUTH:
|
case C.SQLITE_ERROR, C.SQLITE_AUTH:
|
||||||
return ErrAdminRequired
|
return ErrAdminRequired
|
||||||
case C.SQLITE_OK:
|
case C.SQLITE_OK:
|
||||||
return nil
|
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 {
|
func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
|
||||||
// Allocate C Variables
|
// Allocate C Variables
|
||||||
cuser := C.CString(username)
|
cuser := C.CString(username)
|
||||||
|
@ -158,6 +183,34 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
|
||||||
isAdmin = 1
|
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
|
// Allocate C Variables
|
||||||
cuser := C.CString(username)
|
cuser := C.CString(username)
|
||||||
cpass := C.CString(password)
|
cpass := C.CString(password)
|
||||||
|
@ -168,15 +221,7 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
|
||||||
C.free(unsafe.Pointer(cpass))
|
C.free(unsafe.Pointer(cpass))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rv := C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(isAdmin))
|
return int(C._sqlite3_user_change(c.db, cuser, cpass, C.int(len(password)), C.int(admin)))
|
||||||
if rv == C.SQLITE_AUTH {
|
|
||||||
return ErrAdminRequired
|
|
||||||
}
|
|
||||||
if rv != C.SQLITE_OK {
|
|
||||||
return c.lastError()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthUserDelete can be used (by an admin user only)
|
// 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
|
// the database cannot be converted into a no-authentication-required
|
||||||
// database.
|
// database.
|
||||||
func (c *SQLiteConn) AuthUserDelete(username string) error {
|
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
|
// Allocate C Variables
|
||||||
cuser := C.CString(username)
|
cuser := C.CString(username)
|
||||||
|
|
||||||
|
@ -193,20 +261,12 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
|
||||||
C.free(unsafe.Pointer(cuser))
|
C.free(unsafe.Pointer(cuser))
|
||||||
}()
|
}()
|
||||||
|
|
||||||
rv := C._sqlite3_user_delete(c.db, cuser)
|
return int(C._sqlite3_user_delete(c.db, cuser))
|
||||||
if rv == SQLITE_AUTH {
|
|
||||||
return ErrAdminRequired
|
|
||||||
}
|
|
||||||
if rv != C.SQLITE_OK {
|
|
||||||
return c.lastError()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check is database is protected by user authentication
|
// AuthEnabled checks if the database is protected by user authentication
|
||||||
func (c *SQLiteConn) AuthIsEnabled() (exists bool) {
|
func (c *SQLiteConn) AuthEnabled() (exists bool) {
|
||||||
rv := C._sqlite3_auth_is_enabled(c.db)
|
rv := c.authEnabled()
|
||||||
if rv == 1 {
|
if rv == 1 {
|
||||||
exists = true
|
exists = true
|
||||||
}
|
}
|
||||||
|
@ -214,4 +274,16 @@ func (c *SQLiteConn) AuthIsEnabled() (exists bool) {
|
||||||
return
|
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
|
// EOF
|
||||||
|
|
|
@ -29,6 +29,19 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
|
||||||
return nil
|
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)
|
// AuthUserAdd can be used (by an admin user only)
|
||||||
// to create a new user. When called on a no-authentication-required
|
// to create a new user. When called on a no-authentication-required
|
||||||
// database, this routine converts the database into an authentication-
|
// 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
|
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
|
// AuthUserChange can be used to change a users
|
||||||
// login credentials or admin privilege. Any user can change their own
|
// login credentials or admin privilege. Any user can change their own
|
||||||
// login credentials. Only an admin user can change another users login
|
// 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
|
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)
|
// AuthUserDelete can be used (by an admin user only)
|
||||||
// to delete a user. The currently logged-in user cannot be deleted,
|
// to delete a user. The currently logged-in user cannot be deleted,
|
||||||
// which guarantees that there is always an admin user and hence that
|
// 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check is database is protected by user authentication
|
// authUserDelete can be used to delete a user.
|
||||||
func (c *SQLiteConn) AuthIsEnabled() (exists bool) {
|
//
|
||||||
return
|
// 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
|
// EOF
|
||||||
|
|
Loading…
Reference in New Issue