mirror of https://github.com/mattn/go-sqlite3.git
parent
f7f8019102
commit
4a33fcc1d2
|
@ -1308,7 +1308,7 @@ 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, true); err != nil {
|
||||
if err := conn.RegisterFunc("authenticate", conn.Authenticate, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//
|
||||
|
@ -1321,7 +1321,7 @@ 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, true); err != nil {
|
||||
if err := conn.RegisterFunc("auth_user_add", conn.AuthUserAdd, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//
|
||||
|
@ -1330,7 +1330,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
|||
// 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, true); err != nil {
|
||||
if err := conn.RegisterFunc("auth_user_change", conn.AuthUserChange, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//
|
||||
|
@ -1339,7 +1339,7 @@ func (d *SQLiteDriver) Open(dsn string) (driver.Conn, error) {
|
|||
// 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, true); err != nil {
|
||||
if err := conn.RegisterFunc("auth_user_delete", conn.AuthUserDelete, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ _sqlite3_auth_is_enabled(sqlite3* db)
|
|||
*/
|
||||
import "C"
|
||||
import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
|
@ -67,6 +68,11 @@ const (
|
|||
SQLITE_AUTH = C.SQLITE_AUTH
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUnauthorized = errors.New("SQLITE_AUTH: Unauthorized")
|
||||
ErrAdminRequired = errors.New("SQLITE_AUTH: Unauthorized; Admin Privileges Required")
|
||||
)
|
||||
|
||||
// Authenticate will perform an authentication of the provided username
|
||||
// and password against the database.
|
||||
//
|
||||
|
@ -92,6 +98,9 @@ func (c *SQLiteConn) Authenticate(username, password string) error {
|
|||
}()
|
||||
|
||||
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()
|
||||
}
|
||||
|
@ -113,6 +122,18 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
|
|||
isAdmin = 1
|
||||
}
|
||||
|
||||
rv := c.authUserAdd(username, password, isAdmin)
|
||||
switch rv {
|
||||
case C.SQLITE_AUTH:
|
||||
return ErrAdminRequired
|
||||
case C.SQLITE_OK:
|
||||
return nil
|
||||
default:
|
||||
return c.lastError()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *SQLiteConn) authUserAdd(username, password string, admin int) int {
|
||||
// Allocate C Variables
|
||||
cuser := C.CString(username)
|
||||
cpass := C.CString(password)
|
||||
|
@ -123,12 +144,7 @@ func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
|
|||
C.free(unsafe.Pointer(cpass))
|
||||
}()
|
||||
|
||||
rv := C._sqlite3_user_add(c.db, cuser, cpass, C.int(len(password)), C.int(isAdmin))
|
||||
if rv != C.SQLITE_OK {
|
||||
return c.lastError()
|
||||
}
|
||||
|
||||
return nil
|
||||
return int(C._sqlite3_user_add(c.db, cuser, cpass, C.int(len(password)), C.int(admin)))
|
||||
}
|
||||
|
||||
// AuthUserChange can be used to change a users
|
||||
|
@ -153,6 +169,9 @@ func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error
|
|||
}()
|
||||
|
||||
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()
|
||||
}
|
||||
|
@ -175,6 +194,9 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
|
|||
}()
|
||||
|
||||
rv := C._sqlite3_user_delete(c.db, cuser)
|
||||
if rv == SQLITE_AUTH {
|
||||
return ErrAdminRequired
|
||||
}
|
||||
if rv != C.SQLITE_OK {
|
||||
return c.lastError()
|
||||
}
|
||||
|
|
|
@ -62,4 +62,9 @@ func (c *SQLiteConn) AuthUserDelete(username string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Check is database is protected by user authentication
|
||||
func (c *SQLiteConn) AuthIsEnabled() (exists bool) {
|
||||
return
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -9,6 +9,7 @@ package sqlite3
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
@ -23,11 +24,6 @@ func TestAuthCreateDatabase(t *testing.T) {
|
|||
}
|
||||
defer db.Close()
|
||||
|
||||
// Ping database
|
||||
if err := db.Ping(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var exists bool
|
||||
err = db.QueryRow("select count(type) from sqlite_master WHERE type='table' and name='sqlite_user';").Scan(&exists)
|
||||
if err != nil {
|
||||
|
@ -38,3 +34,51 @@ func TestAuthCreateDatabase(t *testing.T) {
|
|||
t.Fatal("failed to enable User Authentication")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthorization(t *testing.T) {
|
||||
tempFilename := TempFilename(t)
|
||||
fmt.Println(tempFilename)
|
||||
//defer os.Remove(tempFilename)
|
||||
|
||||
db, err := sql.Open("sqlite3", "file:"+tempFilename+"?_auth&_auth_user=admin&_auth_pass=admin")
|
||||
if err != nil {
|
||||
t.Fatal("Failed to open database:", err)
|
||||
}
|
||||
|
||||
if _, err := db.Exec("select auth_user_add('user', 'user', false);"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var uname string
|
||||
if err := db.QueryRow("select uname from sqlite_user where uname = 'user';").Scan(&uname); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if uname != "user" {
|
||||
t.Fatal("Failed to create normal user")
|
||||
}
|
||||
db.Close()
|
||||
|
||||
// Re-Open Database as User
|
||||
// Add User should now fail because we are not admin
|
||||
db, err = sql.Open("sqlite3", "file:"+tempFilename+"?_auth_user=user&_auth_pass=user")
|
||||
if err != nil {
|
||||
t.Fatal("Failed to open database:", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// Try to create normal user
|
||||
var rv string
|
||||
if err := db.QueryRow("select auth_user_add('user2', 'user2', false);").Scan(&rv); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fmt.Printf("RV: %v\n", rv)
|
||||
// if rv != SQLITE_AUTH {
|
||||
// t.Fatal("Succeeded creating user while not admin")
|
||||
// }
|
||||
|
||||
// // Try to create admin user
|
||||
// if _, err := db.Exec("select auth_user_add('admin2', 'admin2', true);"); err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue