/* ** Copyright (c) 2012 D. Richard Hipp ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of the Simplified BSD License (also ** known as the "2-Clause License" or "FreeBSD License".) ** ** This program is distributed in the hope that it will be useful, ** but without any warranty; without even the implied warranty of ** merchantability or fitness for a particular purpose. ** ** Author contact information: ** drh@hwaci.com ** http://www.hwaci.com/drh/ ** ******************************************************************************* ** ** This file contains code used to deal with moderator actions for ** Wiki and Tickets. */ #include "config.h" #include "moderate.h" #include /* ** Create a table to represent pending moderation requests, if the ** table does not already exist. */ void moderation_table_create(void){ db_multi_exec( "CREATE TABLE IF NOT EXISTS repository.modreq(\n" " objid INTEGER PRIMARY KEY,\n" /* Record pending approval */ " attachRid INT,\n" /* Object attached */ " tktid TEXT\n" /* Associated ticket id */ ");\n" ); } /* ** Return TRUE if the modreq table exists */ int moderation_table_exists(void){ return db_table_exists("repository", "modreq"); } /* ** Return TRUE if the object specified is being held for moderation. */ int moderation_pending(int rid){ static Stmt q; int rc; if( rid==0 || !moderation_table_exists() ) return 0; db_static_prepare(&q, "SELECT 1 FROM modreq WHERE objid=:objid"); db_bind_int(&q, ":objid", rid); rc = db_step(&q)==SQLITE_ROW; db_reset(&q); return rc; } /* ** If the rid object is being held for moderation, write out ** an "awaiting moderation" message and return true. ** ** If the object is not being held for moderation, simply return ** false without generating any output. */ int moderation_pending_www(int rid){ int pending = moderation_pending(rid); if( pending ){ @ (Awaiting Moderator Approval) } return pending; } /* ** Return TRUE if there any pending moderation requests. */ int moderation_needed(void){ if( !moderation_table_exists() ) return 0; return db_exists("SELECT 1 FROM modreq"); } /* ** Check to see if the object identified by RID is used for anything. */ static int object_used(int rid){ static const char *const aTabField[] = { "modreq", "attachRid", "mlink", "mid", "mlink", "fid", "tagxref", "srcid", "tagxref", "rid", }; int i; for(i=0; iAll Pending Moderation Requests if( moderation_table_exists() ){ blob_init(&sql, timeline_query_for_www(), -1); blob_append_sql(&sql, " AND event.objid IN (SELECT objid FROM modreq)" " ORDER BY event.mtime DESC" ); db_prepare(&q, "%s", blob_sql_text(&sql)); www_print_timeline(&q, 0, 0, 0, 0, 0, 0, 0); db_finalize(&q); } style_finish_page(); } /* ** Disapproves any entries in the modreq table which belong to any ** user whose name is no longer found in the user table. This is only ** intended to be called after user deletion via /setup_uedit. ** ** To figure out whether a name exists it cross-references ** coalesce(event.euser, event.user) with user.login, limiting the ** selection to event entries where objid matches an entry in the ** modreq table. ** ** This is a no-op if called without g.perm.Admin permissions or if ** moderation_table_exists() returns false. */ void moderation_disapprove_for_missing_users(){ Stmt q; if( !g.perm.Admin || !moderation_table_exists() ){ return; } db_begin_transaction(); db_prepare(&q, "SELECT objid FROM event WHERE objid IN " "(SELECT objid FROM modreq) " "AND coalesce(euser,user) NOT IN " "(SELECT login FROM user)" ); while( db_step(&q)==SQLITE_ROW ){ int const objid = db_column_int(&q, 0); moderation_disapprove(objid); } db_finalize(&q); setup_incr_cfgcnt(); db_end_transaction(0); }