Merge branch 'master' of github.com:shish/shimmie2

This commit is contained in:
Shish 2012-02-15 08:54:02 +00:00
commit c70d81c97d
7 changed files with 190 additions and 102 deletions

View file

@ -195,7 +195,9 @@ class IPBan extends Extension {
$reason = $row[$prefix.'reason'];
$admin = User::by_id($row[$prefix.'banner_id']);
$date = date("Y-m-d", $row[$prefix.'end_timestamp']);
print "IP <b>$ip</b> has been banned until <b>$date</b> by <b>{$admin->name}</b> because of <b>$reason</b>";
header("HTTP/1.0 403 Forbidden");
print "IP <b>$ip</b> has been banned until <b>$date</b> by <b>{$admin->name}</b> because of <b>$reason</b>\n";
print "<p>If you couldn't possibly be guilty of what you're banned for, the person we banned probably had a dynamic IP address and so do you. See <a href='http://whatismyipaddress.com/dynamic-static'>http://whatismyipaddress.com/dynamic-static</a> for more information.\n";
$contact_link = $config->get_string("contact_link");
if(!empty($contact_link)) {

View file

@ -30,5 +30,47 @@ _d("WH_SPLITS", 1); // int how many levels of subfolders to put in
_d("VERSION", 'trunk'); // string shimmie version
_d("SCORE_VERSION", 's2hack/'.VERSION); // string SCore version
_d("TIMEZONE", null); // string timezone
_d("EXTRA_USER_CLASSES", serialize(array())); // array extra classes that a user can be*
/**
* Defining extra user classes:
* see core/userclass.class.php for flags
*
* This is a kind of ugly way of doing things...
*
define("EXTRA_USER_CLASSES", serialize(array(
// a regular user, with some extra powers
array(
"moderator", # name for the new class
"user", # class to base it on
array( # parts of the base class to override
"lock_image" => True,
"view_ip" => True,
"ban_ip" => True,
"delete_image" => True,
"delete_comment" => True,
"manage_alias_list" => True,
"mass_tag_edit" => True,
"edit_image_tag" => True,
"edit_image_source" => True,
"edit_image_owner" => True,
"view_image_report" => True,
)
),
// an admin, minus the ability to create / remove other admins
array(
"manager", # name for the new class
"admin", # class to base it on
array( # parts of the base class to override
"override_config" => False,
"change_password" => False,
"change_user_info" => False,
"delete_user" => False,
"manage_extension_list" => False,
)
),
)));
*/
?>

View file

@ -15,7 +15,7 @@ class User {
var $name;
var $email;
var $join_date;
var $admin;
var $class;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Initialisation *
@ -31,12 +31,14 @@ class User {
* would be to use User::by_id, User::by_session, etc
*/
public function User($row) {
global $_user_classes;
$this->id = int_escape($row['id']);
$this->name = $row['name'];
$this->email = $row['email'];
$this->join_date = $row['joindate'];
$this->admin = ($row['admin'] == 'Y');
$this->passhash = $row['pass'];
$this->class = $_user_classes[$row["class"]];
}
public static function by_session(/*string*/ $name, /*string*/ $session) {
@ -92,87 +94,7 @@ class User {
* useful user object functions start here
*/
public function can($ability) {
global $config;
// TODO: make this into an editable database table
$user_classes = array(
"anonymous" => array(
"change_setting" => False, # web-level settings, eg the config table
"override_config" => False, # sys-level config, eg config.php
"big_search" => False, # more than 3 tags (speed mode only)
"lock_image" => False,
"view_ip" => False, # view IP addresses associated with things
"ban_ip" => False,
"change_password" => False,
"change_user_info" => False,
"delete_user" => False,
"delete_image" => False,
"delete_comment" => False,
"replace_image" => False,
"manage_extension_list" => False,
"manage_alias_list" => False,
"edit_image_tag" => $config->get_bool("tag_edit_anon"),
"edit_image_source" => $config->get_bool("source_edit_anon"),
"edit_image_owner" => False,
"mass_tag_edit" => False,
"report_image" => $config->get_bool('report_image_anon'),
"view_image_report" => False,
),
"user" => array(
"change_setting" => False,
"override_config" => False,
"big_search" => True,
"lock_image" => False,
"view_ip" => False,
"ban_ip" => False,
"change_password" => False,
"change_user_info" => False,
"delete_user" => False,
"delete_image" => False,
"delete_comment" => False,
"change_image_owner" => False,
"replace_image" => False,
"manage_extension_list" => False,
"manage_alias_list" => False,
"edit_image_tag" => True,
"edit_image_source" => True,
"edit_image_owner" => False,
"mass_tag_edit" => False,
"report_image" => True,
"view_image_report" => False,
),
"admin" => array(
"change_setting" => True,
"override_config" => True,
"big_search" => True,
"lock_image" => True,
"view_ip" => True,
"ban_ip" => True,
"change_password" => True,
"change_user_info" => True,
"delete_user" => True,
"delete_image" => True,
"delete_comment" => True,
"replace_image" => True,
"manage_extension_list" => True,
"manage_alias_list" => True,
"edit_image_tag" => True,
"edit_image_source" => True,
"edit_image_owner" => True,
"mass_tag_edit" => True,
"report_image" => True,
"view_image_report" => True,
),
);
return $user_classes[$this->get_class()][$ability];
}
// FIXME: this should be a column in the users table
public function get_class() {
if($this->is_admin()) return "admin";
else if($this->is_logged_in()) return "user";
else return"anonymous";
return $this->class->can($ability);
}
@ -202,15 +124,14 @@ class User {
* @retval bool
*/
public function is_admin() {
return $this->admin;
return ($this->class->name === "admin");
}
public function set_admin(/*bool*/ $admin) {
assert(is_bool($admin));
public function set_class(/*string*/ $class) {
assert(is_string($class));
global $database;
$yn = $admin ? 'Y' : 'N';
$database->Execute("UPDATE users SET admin=:yn WHERE id=:id", array("yn"=>$yn, "id"=>$this->id));
log_info("core-user", 'Made '.$this->name.' admin='.$yn);
$database->Execute("UPDATE users SET class=:class WHERE id=:id", array("class"=>$class, "id"=>$this->id));
log_info("core-user", 'Set class for '.$this->name.' to '.$class);
}
public function set_password(/*string*/ $password) {

94
core/userclass.class.php Normal file
View file

@ -0,0 +1,94 @@
<?php
$_user_classes = array();
class UserClass {
var $name = null;
var $parent = null;
var $abilities = array();
public function __construct($name, $parent=null, $abilities=array()) {
$this->name = $name;
$this->parent = $parent;
$this->abilities = $abilities;
}
public function can(/*string*/ $ability) {
global $config;
if(array_key_exists($ability, $this->abilities)) {
$val = $this->abilities[$ability];
if(is_bool($val)) return $val;
else return $config->get_bool($val, false);
}
else if(!is_null($this->parent)) {
return $this->parent->can($ability);
}
else {
die("Unknown ability: ".html_escape($ability));
}
}
}
$_user_class_base = new UserClass("base", null, array(
"change_setting" => False, # web-level settings, eg the config table
"override_config" => False, # sys-level config, eg config.php
"big_search" => False, # more than 3 tags (speed mode only)
"lock_image" => False,
"view_ip" => False, # view IP addresses associated with things
"ban_ip" => False,
"change_password" => False,
"change_user_info" => False,
"delete_user" => False,
"delete_image" => False,
"delete_comment" => False,
"replace_image" => False,
"manage_extension_list" => False,
"manage_alias_list" => False,
"edit_image_tag" => False,
"edit_image_source" => False,
"edit_image_owner" => False,
"mass_tag_edit" => False,
"report_image" => False,
"view_image_report" => False,
));
$_user_classes["anonymous"] = new UserClass("anonymous", $_user_class_base, array(
"edit_image_tag" => "tag_edit_anon",
"edit_image_source" => "source_edit_anon",
"report_image" => "report_image_anon",
));
$_user_classes["user"] = new UserClass("user", $_user_class_base, array(
"big_search" => True,
"edit_image_tag" => True,
"edit_image_source" => True,
"report_image" => True,
));
$_user_classes["admin"] = new UserClass("admin", $_user_class_base, array(
"change_setting" => True,
"override_config" => True,
"big_search" => True,
"lock_image" => True,
"view_ip" => True,
"ban_ip" => True,
"change_password" => True,
"change_user_info" => True,
"delete_user" => True,
"delete_image" => True,
"delete_comment" => True,
"replace_image" => True,
"manage_extension_list" => True,
"manage_alias_list" => True,
"edit_image_tag" => True,
"edit_image_source" => True,
"edit_image_owner" => True,
"mass_tag_edit" => True,
"report_image" => True,
"view_image_report" => True,
));
foreach(unserialize(EXTRA_USER_CLASSES) as $class_info) {
$name = $class_info[0];
$base = $_user_classes[$class_info[1]];
$abilities = $class_info[2];
$_user_classes[$name] = new UserClass($name, $base, $abilities);
}
?>

View file

@ -25,18 +25,21 @@ class Upgrade extends Extension {
// now done again as v9 with PDO
if($config->get_int("db_version") < 8) {
// if this fails, don't try again
$config->set_bool("in_upgrade", true);
$config->set_int("db_version", 8);
$database->execute($database->engine->scoreql_to_sql(
"ALTER TABLE images ADD COLUMN locked SCORE_BOOL NOT NULL DEFAULT SCORE_BOOL_N"
));
log_info("upgrade", "Database at version 8");
$config->set_bool("in_upgrade", false);
}
if($config->get_int("db_version") < 9) {
$config->set_bool("in_upgrade", true);
$config->set_int("db_version", 9);
if($database->db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {
$tables = $database->get_col("SHOW TABLES");
foreach($tables as $table) {
@ -44,21 +47,34 @@ class Upgrade extends Extension {
$database->execute("ALTER TABLE $table TYPE=INNODB");
}
}
$config->set_int("db_version", 9);
log_info("upgrade", "Database at version 9");
$config->set_bool("in_upgrade", false);
}
if($config->get_int("db_version") < 10) {
$config->set_bool("in_upgrade", true);
$config->set_int("db_version", 10);
log_info("upgrade", "Adding foreign keys to images");
$database->Execute("ALTER TABLE images ADD CONSTRAINT foreign_images_owner_id FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE RESTRICT");
$config->set_int("db_version", 10);
log_info("upgrade", "Database at version 10");
$config->set_bool("in_upgrade", false);
}
if($config->get_int("db_version") < 11) {
$config->set_bool("in_upgrade", true);
$config->set_int("db_version", 11);
log_info("upgrade", "Converting user flags to classes");
$database->execute("ALTER TABLE users ADD COLUMN class VARCHAR(32) NOT NULL default :user", array("user" => "user"));
$database->execute("UPDATE users SET class = :name WHERE id=:id", array("name"=>"anonymous", "id"=>$config->get_int('anon_id')));
$database->execute("UPDATE users SET class = :name WHERE admin=:admin", array("name"=>"admin", "admin"=>'Y'));
log_info("upgrade", "Database at version 11");
$config->set_bool("in_upgrade", false);
}
}
public function get_priority() {return 5;}

View file

@ -131,7 +131,7 @@ class UserPage extends Extension {
}
}
else if($event->get_arg(0) == "set_more") {
$this->set_more_wrapper($page);
$this->set_more_wrapper();
}
else if($event->get_arg(0) == "list") {
// select users.id,name,joindate,admin,
@ -411,10 +411,8 @@ class UserPage extends Extension {
}
}
private function set_more_wrapper(Page $page) {
global $user;
global $config;
global $database;
private function set_more_wrapper() {
global $config, $database, $page, $user;
$page->set_title("Error");
$page->set_heading("Error");
@ -427,10 +425,14 @@ class UserPage extends Extension {
"You need to specify the account number to edit"));
}
else {
$admin = (isset($_POST['admin']) && ($_POST['admin'] == "on"));
global $_user_classes;
$class = $_POST['class'];
if(!array_key_exists($class, $_user_classes)) {
throw Exception("Invalid user class: ".html_escape($class));
}
$duser = User::by_id($_POST['id']);
$duser->set_admin($admin);
$duser->set_class($class);
$page->set_mode("redirect");
if($duser->id == $user->id) {

View file

@ -179,7 +179,17 @@ class UserPageTheme extends Themelet {
$html .= "
<p>".make_form(make_link("user_admin/set_more"))."
<input type='hidden' name='id' value='$i_user_id'>
Admin: <input name='admin' type='checkbox'$h_is_admin>
Class: <select name='class'>
";
global $_user_classes;
foreach($_user_classes as $name => $values) {
$h_name = html_escape($name);
$h_title = html_escape(ucwords($name));
$h_selected = ($name == $duser->class->name ? " selected" : "");
$html .= "<option value='$h_name'$h_selected>$h_title</option>\n";
}
$html .= "
</select>
<input type='submit' value='Set'>
</form>
@ -191,7 +201,8 @@ class UserPageTheme extends Themelet {
".make_form(make_link("user_admin/delete_user_with_images"))."
<input type='hidden' name='id' value='$i_user_id'>
<input type='submit' value='Delete User with images' onclick='confirm(\"Delete the user with his uploaded images?\");' />
</form>";
</form>
";
}
}
return $html;