From 1ce6e4b4f78b633296db099acf8b18577906a6a4 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Sat, 20 Aug 2016 23:10:36 +0200 Subject: muser: Add delete_user() Signed-off-by: Florian Pritz --- application/libraries/Duser/drivers/Duser_db.php | 1 + application/models/mfile.php | 12 +++++ application/models/mmultipaste.php | 12 +++++ application/models/muser.php | 54 ++++++++++++++++++++++ application/test/tests/test_models_muser.php | 57 ++++++++++++++++++++++++ 5 files changed, 136 insertions(+) diff --git a/application/libraries/Duser/drivers/Duser_db.php b/application/libraries/Duser/drivers/Duser_db.php index 1144f40f2..062da9e54 100644 --- a/application/libraries/Duser/drivers/Duser_db.php +++ b/application/libraries/Duser/drivers/Duser_db.php @@ -17,6 +17,7 @@ class Duser_db extends Duser_Driver { 'can_reset_password', 'can_register_new_users', 'can_change_email', + 'can_delete_account', ); public function login($username, $password) diff --git a/application/models/mfile.php b/application/models/mfile.php index 6b7b38d41..748d187a3 100644 --- a/application/models/mfile.php +++ b/application/models/mfile.php @@ -202,6 +202,18 @@ class Mfile extends CI_Model { } } + public function delete_by_user($userid) + { + $query = $this->db->select("id") + ->where("user", $userid) + ->get("files")->result_array(); + $ids = array_map(function ($a) {return $a['id'];}, $query); + + foreach ($ids as $id) { + $this->delete_id($id); + } + } + public function delete_id($id) { $filedata = $this->get_filedata($id); diff --git a/application/models/mmultipaste.php b/application/models/mmultipaste.php index deb01978e..d44454f52 100644 --- a/application/models/mmultipaste.php +++ b/application/models/mmultipaste.php @@ -108,6 +108,18 @@ class Mmultipaste extends CI_Model { return $this->config->item("upload_path")."/special/multipaste-tarballs/".substr(md5($id), 0, 3)."/$id.tar.gz"; } + public function delete_by_user($userid) + { + $query = $this->db->select("url_id") + ->where("user_id", $userid) + ->get("multipaste")->result_array(); + $ids = array_map(function ($a) {return $a['url_id'];}, $query); + + foreach ($ids as $id) { + $this->delete_id($id); + } + } + public function delete_id($id) { $this->db->where('url_id', $id) diff --git a/application/models/muser.php b/application/models/muser.php index 7a4b65e4b..48e618fb1 100644 --- a/application/models/muser.php +++ b/application/models/muser.php @@ -182,6 +182,47 @@ class Muser extends CI_Model { ->insert('users'); } + /** + * Delete a user. + * + * @param username + * @param password + * @return true on sucess, false otherwise + */ + public function delete_user($username, $password) + { + $this->duser->require_implemented("can_delete_account"); + + if ($this->duser->test_login_credentials($username, $password)) { + $userid = $this->get_userid_by_name($username); + assert($userid !== null); + + $this->db->delete('profiles', array('user' => $userid)); + + $this->load->model("mfile"); + $this->load->model("mmultipaste"); + $this->mfile->delete_by_user($userid); + $this->mmultipaste->delete_by_user($userid); + + # null out user data to keep referer information traceable + # If referer information was relinked, one user could create many + # accounts, delete the account that was used to invite them and + # then cause trouble so that the account that invited him gets + # banned because the admin thinks that account invited abusers + $this->db->set(array( + 'username' => null, + 'password' => null, + 'email' => null, + )) + ->where(array('username' => $username)) + ->update('users'); + + return true; + } + + return false; + } + function get_userid() { if (!$this->logged_in()) { @@ -191,6 +232,19 @@ class Muser extends CI_Model { return $this->session->userdata("userid"); } + public function get_userid_by_name($username) + { + $query = $this->db->select('id') + ->from('users') + ->where('username', $username) + ->get()->row_array(); + if ($query) { + return $query['id']; + } + + return null; + } + function get_email($userid) { return $this->duser->get_email($userid); diff --git a/application/test/tests/test_models_muser.php b/application/test/tests/test_models_muser.php index 1c5dc98b6..af0e58834 100644 --- a/application/test/tests/test_models_muser.php +++ b/application/test/tests/test_models_muser.php @@ -52,5 +52,62 @@ class test_models_muser extends \test\Test { $this->t->is($CI->muser->valid_email("joebob.com"), false, "missing @"); } + public function test_delete_user() + { + $CI =& get_instance(); + $CI->muser->add_user("userdeltest1", "supersecret", "tester@localhost.lan", null); + $this->t->is($CI->muser->username_exists("userdeltest1"), true, "User should exist after creation"); + + $ret = $CI->muser->delete_user("userdeltest1", "wrongpassword"); + $this->t->is($ret, false, "Deletion should fail with incorrect password"); + + $ret = $CI->muser->delete_user("userdeltest1", ""); + $this->t->is($ret, false, "Deletion should fail with empty password"); + + $this->t->is($CI->muser->username_exists("userdeltest1"), true, "User should exist after failed deletions"); + + $ret = $CI->muser->delete_user("userdeltest1", "supersecret"); + $this->t->is($ret, true, "Deletion should succeed with correct data"); + $this->t->is($CI->muser->username_exists("userdeltest1"), false, "User should not exist after deletion"); + } + + public function test_delete_user_verifyFilesDeleted() + { + $CI =& get_instance(); + + $id = "testid1"; + $id2 = "testid2"; + $content = "test content"; + $filename = "some cool name"; + $username = "testuser1"; + $password = "testpass"; + + $CI->muser->add_user($username, $password, "tester@localhost.lan", null); + $userid = $CI->muser->get_userid_by_name($username); + + $CI->muser->add_user("joe", "joeisawesome", "tester2@localhost.lan", null); + $userid2 = $CI->muser->get_userid_by_name("joe"); + + \service\files::add_file_data($userid, $id, $content, $filename); + \service\files::add_file_data($userid2, $id2, $content, $filename); + + $mid = \service\files::create_multipaste([$id], $userid, [3,6])['url_id']; + $mid2 = \service\files::create_multipaste([$id2], $userid2, [3,6])['url_id']; + + $this->t->is($CI->mfile->id_exists($id), true, "File exists after being added"); + $this->t->is($CI->mmultipaste->id_exists($mid), true, "Multipaste exists after creation"); + $this->t->is($CI->mfile->id_exists($id2), true, "File2 exists after being added"); + $this->t->is($CI->mmultipaste->id_exists($mid2), true, "Multipaste2 exists after creation"); + + $ret = $CI->muser->delete_user($username, $password); + $this->t->is($ret, true, "Delete user"); + + $this->t->is($CI->mfile->id_exists($id), false, "File should be gone after deletion of user"); + $this->t->is($CI->mmultipaste->id_exists($mid), false, "Multipaste should be gone after deletion of user"); + $this->t->is($CI->mfile->id_exists($id2), true, "File2 owned by different user should still exist after deletion from other user"); + $this->t->is($CI->mmultipaste->id_exists($mid2), true, "Multipaste2 owned by different user should still exist after deletion from other user"); + } + + } -- cgit v1.2.3-24-g4f1b