############################################################################### # # authorizer.eagle -- # # Written by Joe Mistachkin. # Released to the public domain, use at your own risk! # ############################################################################### package require Eagle package require Eagle.Library package require Eagle.Test runTestPrologue ############################################################################### package require System.Data.SQLite.Test runSQLiteTestPrologue ############################################################################### runTest {test authorizer-1.1 {SQLiteConnection Authorize event} -setup { proc onAuthorize { sender e } { # # NOTE: Filter out the "noise" by allowing all standard # events on the "sqlite_*" tables. # set noiseActionCodes [list \ CreateTable CreateIndex Read Insert Update Delete] if {[$e ActionCode] in $noiseActionCodes && \ [string match sqlite_* [$e Argument1]]} then { return } # # NOTE: Filter out all "non-primary" events to make the test # results more deterministic in the face of different # query plans. # if {[$e ActionCode] ne $::filter} then { return } # # NOTE: Record the authorizer arguments exactly as we received # them. # lappend ::data [list \ [$e UserData] [$e ActionCode] [$e Argument1] \ [$e Argument2] [$e Database] [$e Context]] # # NOTE: Deny all attempts to create a table named "tDeny". # if {[$e ActionCode] eq "CreateTable" && \ [$e Argument1] eq "tDeny"} then { $e ReturnCode Deny } } setupDb [set fileName authorizer-1.1.db] } -body { set connection [getDbConnection] set callback onAuthorize object invoke $connection add_Authorize $callback set results [list] set sql [list \ CreateTable {CREATE TABLE t1(x);} \ CreateIndex {CREATE INDEX i1 ON t1(x);} \ CreateTrigger {CREATE TRIGGER tr1 BEFORE INSERT ON t1 BEGIN SELECT RAISE(IGNORE); END;} \ CreateView {CREATE VIEW v1 AS SELECT * FROM t1;} \ CreateTempTable {CREATE TEMPORARY TABLE t2(x);} \ CreateTempIndex {CREATE INDEX i2 ON t2(x);} \ CreateTempTrigger {CREATE TEMPORARY TRIGGER tr2 BEFORE INSERT ON t2 BEGIN SELECT RAISE(IGNORE); END;} \ CreateTempView {CREATE TEMPORARY VIEW v2 AS SELECT * FROM t2;} \ Pragma {PRAGMA journal_mode=WAL;} \ Function {SELECT julianday('now');} \ Read {SELECT x FROM t1;} \ Select {SELECT * FROM t1;} \ Insert {INSERT INTO t1(x) VALUES(1);} \ Update {UPDATE t1 SET x = x - 1;} \ Delete {DELETE FROM t1;} \ AlterTable {ALTER TABLE t1 ADD COLUMN y;} \ Reindex {REINDEX t1;} \ Analyze {ANALYZE t1;} \ DropTempView {DROP VIEW v2;} \ DropTempTrigger {DROP TRIGGER tr2;} \ DropTempIndex {DROP INDEX i2;} \ DropTempTable {DROP TABLE t2;} \ DropView {DROP VIEW v1;} \ DropTrigger {DROP TRIGGER tr1;} \ DropIndex {DROP INDEX i1;} \ Recursive {WITH t4(x) AS ( VALUES(1) UNION ALL SELECT t1.x FROM t1, t4 WHERE t1.x = t4.x ) SELECT x FROM t4;} \ DropTable {DROP TABLE t1;} \ Transaction {BEGIN; SELECT 0; COMMIT;} \ Savepoint {SAVEPOINT s1; RELEASE SAVEPOINT s1;} \ Attach {ATTACH DATABASE ':memory:' AS d1;} \ Detach {DETACH DATABASE d1;} \ CreateVtable {CREATE VIRTUAL TABLE t3 USING fts4(x TEXT);} \ DropVtable {DROP TABLE t3;} \ CreateTable {CREATE TABLE tDeny(x);}] foreach {name value} $sql { set filter $name; set data [list] set code [catch {sql execute $db $value} result] set result [lindex [split [string map [list \r\n \n] $result] \n] 0] lappend results [list $name $data $code $result] } lappend results [isTableInDb tDeny] set results } -cleanup { catch {object invoke $connection remove_Authorize $callback} catch {object removecallback $callback} cleanupDb $fileName freeDbConnection unset -nocomplain result code data filter value name sql results callback \ connection db fileName rename onAuthorize "" } -constraints \ {eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -result \ {{CreateTable {{0 CreateTable t1 {} main {}}} 0 0} {CreateIndex {{0 CreateIndex\ i1 t1 main {}}} 0 0} {CreateTrigger {{0 CreateTrigger tr1 t1 main {}}} 0 0}\ {CreateView {{0 CreateView v1 {} main {}}} 0 0} {CreateTempTable {{0\ CreateTempTable t2 {} temp {}}} 0 0} {CreateTempIndex {{0 CreateTempIndex i2 t2\ temp {}}} 0 0} {CreateTempTrigger {{0 CreateTempTrigger tr2 t2 temp {}}} 0 0}\ {CreateTempView {{0 CreateTempView v2 {} temp {}}} 0 0} {Pragma {{0 Pragma\ journal_mode WAL {} {}}} 0 0} {Function {{0 Function {} julianday {} {}}} 0 0}\ {Read {{0 Read t1 x main {}}} 0 0} {Select {{0 Select {} {} {} {}}} 0 0}\ {Insert {{0 Insert t1 {} main {}}} 0 0} {Update {{0 Update t1 x main {}}} 0 0}\ {Delete {{0 Delete t1 {} main {}}} 0 0} {AlterTable {{0 AlterTable main t1 {}\ {}}} 0 0} {Reindex {{0 Reindex i1 {} main {}}} 0 0} {Analyze {{0 Analyze t1 {}\ main {}}} 0 0} {DropTempView {{0 DropTempView v2 {} temp {}}} 0 0}\ {DropTempTrigger {{0 DropTempTrigger tr2 t2 temp {}}} 0 0} {DropTempIndex {{0\ DropTempIndex i2 t2 temp {}}} 0 0} {DropTempTable {{0 DropTempTable t2 {} temp\ {}}} 0 0} {DropView {{0 DropView v1 {} main {}}} 0 0} {DropTrigger {{0\ DropTrigger tr1 t1 main {}}} 0 0} {DropIndex {{0 DropIndex i1 t1 main {}}} 0 0}\ {Recursive {{0 Recursive {} {} {} {}}} 0 0} {DropTable {{0 DropTable t1 {} main\ {}}} 0 0} {Transaction {{0 Transaction BEGIN {} {} {}} {0 Transaction COMMIT {}\ {} {}}} 0 0} {Savepoint {{0 Savepoint BEGIN s1 {} {}} {0 Savepoint RELEASE s1\ {} {}}} 0 0} {Attach {{0 Attach :memory: {} {} {}}} 0 0} {Detach {{0 Detach d1\ {} {} {}}} 0 0} {CreateVtable {{0 CreateVtable t3 fts4 main {}}} 0 0}\ {DropVtable {{0 DropVtable t3 fts4 main {}}} 0 0} {CreateTable {{0 CreateTable\ tDeny {} main {}}} 1 {System.Data.SQLite.SQLiteException (0x80004005):\ authorization denied}} False}} ############################################################################### runSQLiteTestEpilogue runTestEpilogue