mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
* add DateTime sans mgo * change all uses of strfmt.DateTime to common.DateTime, remove test strfmt usage * remove api tests, system-test dep on api test multiple reasons to remove the api tests: * awkward dependency with fn_go meant generating bindings on a branched fn to vendor those to test new stuff. this is at a minimum not at all intuitive, worth it, nor a fun way to spend the finite amount of time we have to live. * api tests only tested a subset of functionality that the server/ api tests already test, and we risk having tests where one tests some thing and the other doesn't. let's not. we have too many test suites as it is, and these pretty much only test that we updated the fn_go bindings, which is actually a hassle as noted above and the cli will pretty quickly figure out anyway. * fn_go relies on openapi, which relies on mgo, which is deprecated and we'd like to remove as a dependency. openapi is a _huge_ dep built in a NIH fashion, that cannot simply remove the mgo dep as users may be using it. we've now stolen their date time and otherwise killed usage of it in fn core, for fn_go it still exists but that's less of a problem. * update deps removals: * easyjson * mgo * go-openapi * mapstructure * fn_go * purell * go-validator also, had to lock docker. we shouldn't use docker on master anyway, they strongly advise against that. had no luck with latest version rev, so i locked it to what we were using before. until next time. the rest is just playing dep roulette, those end up removing a ton tho * fix exec test to work * account for john le cache
290 lines
7.4 KiB
Go
290 lines
7.4 KiB
Go
// Copyright (C) 2018 G.J.R. Timmer <gjr.timmer@gmail.com>.
|
|
//
|
|
// Use of this source code is governed by an MIT-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build sqlite_userauth
|
|
|
|
package sqlite3
|
|
|
|
/*
|
|
#cgo CFLAGS: -DSQLITE_USER_AUTHENTICATION
|
|
#cgo LDFLAGS: -lm
|
|
#ifndef USE_LIBSQLITE3
|
|
#include <sqlite3-binding.h>
|
|
#else
|
|
#include <sqlite3.h>
|
|
#endif
|
|
#include <stdlib.h>
|
|
|
|
static int
|
|
_sqlite3_user_authenticate(sqlite3* db, const char* zUsername, const char* aPW, int nPW)
|
|
{
|
|
return sqlite3_user_authenticate(db, zUsername, aPW, nPW);
|
|
}
|
|
|
|
static int
|
|
_sqlite3_user_add(sqlite3* db, const char* zUsername, const char* aPW, int nPW, int isAdmin)
|
|
{
|
|
return sqlite3_user_add(db, zUsername, aPW, nPW, isAdmin);
|
|
}
|
|
|
|
static int
|
|
_sqlite3_user_change(sqlite3* db, const char* zUsername, const char* aPW, int nPW, int isAdmin)
|
|
{
|
|
return sqlite3_user_change(db, zUsername, aPW, nPW, isAdmin);
|
|
}
|
|
|
|
static int
|
|
_sqlite3_user_delete(sqlite3* db, const char* zUsername)
|
|
{
|
|
return sqlite3_user_delete(db, zUsername);
|
|
}
|
|
|
|
static int
|
|
_sqlite3_auth_enabled(sqlite3* db)
|
|
{
|
|
int exists = -1;
|
|
|
|
sqlite3_stmt *stmt;
|
|
sqlite3_prepare_v2(db, "select count(type) from sqlite_master WHERE type='table' and name='sqlite_user';", -1, &stmt, NULL);
|
|
|
|
while ( sqlite3_step(stmt) == SQLITE_ROW) {
|
|
exists = sqlite3_column_int(stmt, 0);
|
|
}
|
|
|
|
sqlite3_finalize(stmt);
|
|
|
|
return exists;
|
|
}
|
|
*/
|
|
import "C"
|
|
import (
|
|
"errors"
|
|
"unsafe"
|
|
)
|
|
|
|
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.
|
|
//
|
|
// If a database contains the SQLITE_USER table, then the
|
|
// call to Authenticate must be invoked with an
|
|
// appropriate username and password prior to enable read and write
|
|
//access to the database.
|
|
//
|
|
// Return SQLITE_OK on success or SQLITE_ERROR if the username/password
|
|
// combination is incorrect or unknown.
|
|
//
|
|
// 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)
|
|
|
|
// Free C Variables
|
|
defer func() {
|
|
C.free(unsafe.Pointer(cuser))
|
|
C.free(unsafe.Pointer(cpass))
|
|
}()
|
|
|
|
return int(C._sqlite3_user_authenticate(c.db, cuser, cpass, C.int(len(password))))
|
|
}
|
|
|
|
// 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-
|
|
// required database, automatically makes the added user an
|
|
// administrator, and logs in the current connection as that user.
|
|
// 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.
|
|
func (c *SQLiteConn) AuthUserAdd(username, password string, admin bool) error {
|
|
isAdmin := 0
|
|
if admin {
|
|
isAdmin = 1
|
|
}
|
|
|
|
rv := c.authUserAdd(username, password, isAdmin)
|
|
switch rv {
|
|
case C.SQLITE_ERROR, C.SQLITE_AUTH:
|
|
return ErrAdminRequired
|
|
case C.SQLITE_OK:
|
|
return nil
|
|
default:
|
|
return c.lastError()
|
|
}
|
|
}
|
|
|
|
// 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)
|
|
cpass := C.CString(password)
|
|
|
|
// Free C Variables
|
|
defer func() {
|
|
C.free(unsafe.Pointer(cuser))
|
|
C.free(unsafe.Pointer(cpass))
|
|
}()
|
|
|
|
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
|
|
// 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.
|
|
func (c *SQLiteConn) AuthUserChange(username, password string, admin bool) error {
|
|
isAdmin := 0
|
|
if admin {
|
|
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)
|
|
|
|
// Free C Variables
|
|
defer func() {
|
|
C.free(unsafe.Pointer(cuser))
|
|
C.free(unsafe.Pointer(cpass))
|
|
}()
|
|
|
|
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)
|
|
// 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.
|
|
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)
|
|
|
|
// Free C Variables
|
|
defer func() {
|
|
C.free(unsafe.Pointer(cuser))
|
|
}()
|
|
|
|
return int(C._sqlite3_user_delete(c.db, cuser))
|
|
}
|
|
|
|
// AuthEnabled checks if the database is protected by user authentication
|
|
func (c *SQLiteConn) AuthEnabled() (exists bool) {
|
|
rv := c.authEnabled()
|
|
if rv == 1 {
|
|
exists = true
|
|
}
|
|
|
|
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
|