From dbeb76f57aab441e5e93dcb1919b0b442c889965 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 4 Oct 2011 14:42:59 -0700 Subject: Add the ability to close user registration. --- src/controllers/Users.class.php | 21 ++++++++++++++++++++- src/views/pages/users/new-locked.html.php | 9 +++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/views/pages/users/new-locked.html.php diff --git a/src/controllers/Users.class.php b/src/controllers/Users.class.php index a5d23fc..27efbcd 100644 --- a/src/controllers/Users.class.php +++ b/src/controllers/Users.class.php @@ -22,7 +22,12 @@ class Users extends Controller { switch ($method) { case 'POST': // We're POSTing a new user. - $this->create_user(); + if ($this->registrationOpen()) { + $this->create_user(); + } else { + $this->showView('users/new-locked', array()); + exit(); + } break; case 'HEAD': // fall-through to GET case 'GET': @@ -61,6 +66,10 @@ class Users extends Controller { $this->showView('users/new-logged-in', array()); exit(); } + if (!$this->registrationOpen()) { + $this->showView('users/new-locked', array()); + exit(); + } if (!isset($vars['errors'])) $vars['errors'] = array(); global $mm; $pm = $mm->pluginManager(); $vars['antispam_html'] = $pm->callHook('antispam_html'); @@ -404,4 +413,14 @@ class Users extends Controller { $attribs[] = $this->attrib('auth_name', 'Username'); return $attribs; } + + private function registrationOpen() { + global $mm; $db = $mm->database(); + $val = $db->getSysConf('registration_open'); + switch ($val) { + case 'true': return true; + case 'false': return false; + default: return true; + } + } } diff --git a/src/views/pages/users/new-locked.html.php b/src/views/pages/users/new-locked.html.php new file mode 100644 index 0000000..dc7ad0d --- /dev/null +++ b/src/views/pages/users/new-locked.html.php @@ -0,0 +1,9 @@ +status('403 Forbidden'); +$t->header('Create new user'); + +$t->paragraph("Sorry, new user registration is disabled."); + +$t->footer(); -- cgit v1.2.3-2-g168b From 69b62718a3526c77c666a8259c1c4919a8947a01 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 4 Oct 2011 14:43:44 -0700 Subject: Add a trailing newline to Database.class.php --- src/lib/Database.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Database.class.php b/src/lib/Database.class.php index ab56d09..13d9559 100644 --- a/src/lib/Database.class.php +++ b/src/lib/Database.class.php @@ -396,4 +396,4 @@ class Database { return $out_list; } -} \ No newline at end of file +} -- cgit v1.2.3-2-g168b From 9018599b1a62b898990e3f056eb1179561c366fe Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 4 Oct 2011 23:27:42 -0400 Subject: Use SCSS, tweak styles a bit. --- .gitignore | 1 + Makefile | 11 ++++++++ screen.css | 50 ---------------------------------- screen.scss | 43 +++++++++++++++++++++++++++++ style.css | 65 -------------------------------------------- style.scss | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 144 insertions(+), 115 deletions(-) create mode 100644 Makefile delete mode 100644 screen.css create mode 100644 screen.scss delete mode 100644 style.css create mode 100644 style.scss diff --git a/.gitignore b/.gitignore index 3d2b2cd..b603124 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ xss-check.php *.bak *~ +.sass-cache/* \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4b6eae6 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +RM = rm -f +CP = cp +PATCH = patch +SASS = sass +PHP = php5 + +all: style.css screen.css print.css + +%.css: %.scss + $(SASS) $< $@ + diff --git a/screen.css b/screen.css deleted file mode 100644 index 3705244..0000000 --- a/screen.css +++ /dev/null @@ -1,50 +0,0 @@ -/* If the indentation looks funny, it's using SASS indentation style. - * See . SASS is pretty cool, but I'm too lame actually - * use SASS, because that's one more thing I have to install and run. I already - * have enough trouble saving before I switch to my browser to check it, let - * alone having to run another utility. - * - * To handle the introduction of curly braces (SASS doesn't have any), I've - * handled them as one handles parens in LISP. - * - * On a related note, I actually preffer SCSS to SASS, but I find SASS - * indentation to be more readable when using plain CSS. - */ -body { - background-color: #FFFF00; } - div.infobar, div.main { - margin: 0 auto; - width: 70%; - min-width: 30em; } - div.infobar { - margin-top: .5em; - - background-color: #0000FF; - border: solid #000099; - border-width: 1px 1px 0 1px; - border-top-left-radius: 0.7em; - border-top-right-radius: 0.7em; - box-shadow: 0 1px 0 #AAAAFF inset; } - div.infobar input[type="submit"]:hover, - div.infobar input[type="submit"]:active, - div.infobar input[type="submit"]:focus { - text-decoration: underline; } - div.main { - margin-bottom: 5em; - - background-color: #FFFFFF; - border: solid #AAAA00; - border-width: 0 1px 1px 1px; - padding-top: 1px;/* we don't want this, but it can't be 0 */ } - div.main_sub { - /* 'main_sub' is basically just to add padding to 'main' w/o it - * extending outside 'all'. */ - margin: 2em; } - -a { - color: #555555; } -a:hover, -a:active, -a:focus { - text-decoration: underline; -} diff --git a/screen.scss b/screen.scss new file mode 100644 index 0000000..3705ccb --- /dev/null +++ b/screen.scss @@ -0,0 +1,43 @@ +body { + background-color: #FFFF00; + div.infobar, div.main { + margin: 0 auto; + width: 70%; + min-width: 30em; + } + div.infobar { + margin-top: .5em; + + background-color: #0000FF; + border: solid #000099; + border-width: 1px 1px 0 1px; + border-top-left-radius: 0.7em; + border-top-right-radius: 0.7em; + box-shadow: 0 1px 0 #AAAAFF inset; + input[type="submit"] { + &:hover, &:active, &:focus { + text-decoration: underline; + } + } + } + div.main { + margin-bottom: 5em; + + background-color: #FFFFFF; + border: solid #AAAA00; + border-width: 0 1px 1px 1px; + padding-top: 1px;/* we don't want this, but it can't be 0 */ + } + div.main_sub { + /* 'main_sub' is basically just to add padding to 'main' w/o it + * extending outside 'all'. */ + margin: 2em; + } +} + +a { + color: #555555; + &:hover, &:active, &:focus { + text-decoration: underline; + } +} diff --git a/style.css b/style.css deleted file mode 100644 index 226859d..0000000 --- a/style.css +++ /dev/null @@ -1,65 +0,0 @@ -body { - font-family: sans-serif; - margin: 0; - padding: 0; } - div.infobar { - text-align: right; - padding: .1em 0; } - .loggedin div.infobar * { - margin: 0 1em; } - div.infobar input[type="text"], - div.infobar input[type="password"] { - width: 20%; } - div.infobar input[type="submit"] { - background: transparent; - border: none; - font-size: 1em; - padding: 0; } - div.infobar a { - color: #000000; } - div.main { - } - div.main form fieldset li { - clear: both; - padding: .5em 0; } - div.main form fieldset li label { - width: 25%; - float: left; } - div.main form fieldset li input, - div.main form fieldset li textarea { - width: 30%; - float: left; } - div.main form fieldset li p.form_data { - margin-left: 25%; } - div.main form fieldset li.wide { - clear: both; - padding: .5em 0; } - div.main form fieldset li.wide label { - width: 100%; - float: none; } - div.main form fieldset li.wide input, - div.main form fieldset li.wide textarea { - width: 100%; - float: none; } - -h1 { - text-align: center; } -a { - text-decoration: none; } -input[type="text"], textarea { - font-family: monospace; } -iframe { - width: 100%; - height: 100%; } -table, td { - border: solid 1px black; } -table input { - border: none; - width: 100%; - background: transparent; -} -.error { - font-weight: bold; - color: red; } -.http404 { - color: red; } diff --git a/style.scss b/style.scss new file mode 100644 index 0000000..627df42 --- /dev/null +++ b/style.scss @@ -0,0 +1,89 @@ +body.loggedin { + div.infobar * { + margin: 0 1em; + } +} + +body { + font-family: sans-serif; + margin: 0; + padding: 0; + div.infobar { + text-align: right; + padding: .1em 0; + input[type="text"], + input[type="password"] { + width: 20%; + } + input[type="submit"] { + background: transparent; + border: none; + font-size: 1em; + padding: 0; + } + a { + color: #000000; + } + } + div.main { + form fieldset li { + clear: both; + padding: .5em 0; + label { + width: 25%; + float: left; + } + input, textarea { + width: 60%; + float: left; + } + input[type="password"] { + width: 30%; + } + p.form_data { + margin-left: 25%; + } + &.wide { + clear: both; + padding: .5em 0; + label { + width: 100%; + float: none; + } + input, textarea { + width: 100%; + float: none; + } + } + } + } +} + +h1 { + text-align: center; +} +a { + text-decoration: none; +} +input[type="text"], textarea { + font-family: monospace; +} +iframe { + width: 100%; + height: 100%; +} +table, td { + border: solid 1px black; +} +table input { + border: none; + width: 100%; + background: transparent; +} +.error { + font-weight: bold; + color: red; +} +.http404 { + color: red; +} -- cgit v1.2.3-2-g168b From 9e4c1efb467014ce69886a31168b4adb3c8a8850 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 4 Oct 2011 23:28:32 -0400 Subject: Add some (S)CSS for printing. --- print.scss | 26 ++++++++++++++++++++++++++ src/views/Template.class.php | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 print.scss diff --git a/print.scss b/print.scss new file mode 100644 index 0000000..746527a --- /dev/null +++ b/print.scss @@ -0,0 +1,26 @@ +div.infobar { + display: none; +} + +fieldset { + page-break-inside: auto; + border: solid black; + border-width: 1pt 0 0 1pt; + legend { + background-color: white; + border: solid 1pt black; + } +} + +input[type="password"], input[type="submit"] { + display: none; +} +input[type="text"] { + background: transparent; + border: none; + border-bottom: solid 1pt black; +} +textarea { + border: solid 1pt black; + height: 5em; +} diff --git a/src/views/Template.class.php b/src/views/Template.class.php index 663ec05..bf57e93 100644 --- a/src/views/Template.class.php +++ b/src/views/Template.class.php @@ -138,7 +138,7 @@ class Template { $str.= $this->tag('title', array(), htmlspecialchars($title)); $str.= $this->css('style.css', 'all'); $str.= $this->css('screen.css', 'screen'); - $str.= $this->css('logo-style.css', 'screen'); + $str.= $this->css('print.css', 'print'); $str.= $this->closeTag('head'); $body_class = 'logged'.($logged_in?'in':'out'); -- cgit v1.2.3-2-g168b From f15e53890dc93bfbf710e07a510208ea39774d0a Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Tue, 4 Oct 2011 23:29:08 -0400 Subject: Change the title on user pages from "Users: NAME" to "User: NAME". --- src/views/pages/users/individual.html.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/views/pages/users/individual.html.php b/src/views/pages/users/individual.html.php index 5722977..c630515 100644 --- a/src/views/pages/users/individual.html.php +++ b/src/views/pages/users/individual.html.php @@ -57,7 +57,7 @@ function inputField($user, $arr) { //////////////////////////////////////////////////////////////////////////////// $username = $user->getName(); -$t->header("Users: $username"); +$t->header("User: $username"); $t->tag('h1', array(), ($user->canEdit()?'Edit':'View')." User $username (UID: ".$user->getUID().")"); -- cgit v1.2.3-2-g168b From f618eae020122914c1c349ece78cb755576b4105 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 5 Oct 2011 00:17:16 -0400 Subject: Improve printed formatting. --- .gitignore | 3 +++ print.scss | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/.gitignore b/.gitignore index b603124..30b29a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# we use scss +*.css + msg/* conf.php diff --git a/print.scss b/print.scss index 746527a..d608e93 100644 --- a/print.scss +++ b/print.scss @@ -1,7 +1,18 @@ +body { + font-size: 12pt; +} + div.infobar { display: none; } +h1 { + page-break-before: always; +} +.main_sub h1:first-child { + page-break-before: avoid; +} + fieldset { page-break-inside: auto; border: solid black; -- cgit v1.2.3-2-g168b From 2a71bacfc5536279bbc5e238fb6a07c03e85d12d Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Wed, 5 Oct 2011 00:18:51 -0400 Subject: Edit individual.html to allow showing multiple users at once. Add a hack to the Users.class controller to show all users for the "all" username. Mark "all" as forbiddent in the Auth.class model. --- src/controllers/Users.class.php | 54 +++++++++++++++++++------------ src/models/Auth.class.php | 6 ++-- src/views/pages/users/individual.html.php | 12 +++++-- 3 files changed, 46 insertions(+), 26 deletions(-) diff --git a/src/controllers/Users.class.php b/src/controllers/Users.class.php index 27efbcd..170d25f 100644 --- a/src/controllers/Users.class.php +++ b/src/controllers/Users.class.php @@ -77,26 +77,34 @@ class Users extends Controller { } public function individual($routed, $remainder) { - $username = implode('/', $remainder); - global $mm; // also used for pluginmanager $db = $mm->database(); - $uid = $db->getUID($username); - $user = Auth::getObj($uid); - - if ($user->isGroup()) $uid = false; // ignore groups. - - if ($uid===false) { - $this->http404($routed, $remainder); + $pm = $mm->pluginManager(); + + $username = implode('/', $remainder); + if ($username == 'all') { + $uids = $db->listUsers(); } else { + $uids = array($db->getUID($username)); + } + + $vars = array(); + + if (count($uids)<2) { + $user = Auth::getObj($uid); + + if ($user->isGroup()) $uid = false; // ignore groups. + + if ($uid===false) { + $this->http404($routed, $remainder); + exit(); + } if (!$user->canRead()) { $this->http401($routed, $remainder); exit(); } - $vars = array(); $method = $_SERVER['REQUEST_METHOD']; - switch ($method) { case 'PUT': $_POST = $_PUT; case 'POST': @@ -106,19 +114,23 @@ class Users extends Controller { } break; } - - $config_options = array(); - $mm->pluginManager()->callHook('userConfig', &$config_options); - - $vars['config_options'] = $config_options; - $vars['user'] = $user; - $vars['groups'] = $db->listGroupNames(); - require_once('ContactMethod.class.php'); - $this->showView('users/individual', $vars); } + + $config_options = array(); + $pm->callHook('userConfig', &$config_options); + + $vars['users'] = array(); + foreach ($uids as $uid) { + $vars['users'][] = Auth::getObj($uid); + } + $vars['username'] = $username; + $vars['config_options'] = $config_options; + $vars['groups'] = $db->listGroupNames(); + require_once('ContactMethod.class.php'); + $this->showView('users/individual', $vars); } - public function http404($routed, $rnemainder) { + public function http404($routed, $remainder) { $username = implode('/', $remainder); $this->showView('users/404', array('username'=>$username)); diff --git a/src/models/Auth.class.php b/src/models/Auth.class.php index 25570bf..b51aef9 100644 --- a/src/models/Auth.class.php +++ b/src/models/Auth.class.php @@ -26,12 +26,12 @@ class Auth { // Current rules: // * Not in "$illegal_names" // * Does not contain '.' - // * Less <256 characters - $illegal_names = array('', 'new', 'index'); + // * Fewer than 256 characters + $illegal_names = array('', 'new', 'index', 'all'); return true && (!in_array($name, $illegal_names)) && (strpos($name,'.')===false) - && (strlen($name)<=256); + && (strlen($name)<256); } protected $db = null; diff --git a/src/views/pages/users/individual.html.php b/src/views/pages/users/individual.html.php index c630515..39360b7 100644 --- a/src/views/pages/users/individual.html.php +++ b/src/views/pages/users/individual.html.php @@ -1,6 +1,7 @@ 1) { + $t->header("Users: $username"); +} else { + $t->header("User: $username"); +} + +foreach($users as $user) { $username = $user->getName(); -$t->header("User: $username"); $t->tag('h1', array(), ($user->canEdit()?'Edit':'View')." User $username (UID: ".$user->getUID().")"); @@ -136,4 +143,5 @@ if ($user->canEdit()) { $t->tag('input', array('type'=>'submit', 'value'=>'Save')); } $t->closeTag('form'); +} $t->footer(); -- cgit v1.2.3-2-g168b From e99a2ea7e361fdc5bab219bea6d9b967b5df486c Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 9 Oct 2011 00:51:28 -0400 Subject: Add auth_uid as a parameter for forms in the Users controller. --- src/controllers/Users.class.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/controllers/Users.class.php b/src/controllers/Users.class.php index 170d25f..a4403e3 100644 --- a/src/controllers/Users.class.php +++ b/src/controllers/Users.class.php @@ -359,6 +359,10 @@ class Users extends Controller { $editable = $user->canEdit(); switch ($key) { + case 'auth_uid': + $value = $user->getUID(); + $editable = false; + break; case 'auth_name': $value = $user->getName(); break; @@ -390,6 +394,8 @@ class Users extends Controller { $user = Auth::getObj($uid); switch ($key) { + case 'auth_uid': + break; case 'auth_name': $user->setName($value); break; -- cgit v1.2.3-2-g168b From 4ea4d8c5f718b79851372243244554ee7a039427 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 9 Oct 2011 01:03:21 -0400 Subject: Improve usability of scss. (a lot of form style stuff) --- style.scss | 86 ++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/style.scss b/style.scss index 627df42..7a86e20 100644 --- a/style.scss +++ b/style.scss @@ -1,3 +1,9 @@ +@mixin box-shadow($shadow) { + -webkit-box-shadow: $shadow; + -moz-box-shadow: $shadow; + box-shadow: $shadow; +} + body.loggedin { div.infobar * { margin: 0 1em; @@ -26,33 +32,60 @@ body { } } div.main { - form fieldset li { - clear: both; - padding: .5em 0; - label { - width: 25%; - float: left; - } - input, textarea { - width: 60%; - float: left; - } - input[type="password"] { - width: 30%; - } - p.form_data { - margin-left: 25%; - } - &.wide { + form { + fieldset li { clear: both; padding: .5em 0; label { - width: 100%; - float: none; + width: 25%; + float: left; } input, textarea { - width: 100%; - float: none; + width: 60%; + float: left; + } + input[type="password"] { + width: 30%; + } + p.form_data { + margin-left: 25%; + } + &.wide { + clear: both; + padding: .5em 0; + label { + width: 100%; + float: none; + } + input, textarea { + width: 100%; + float: none; + } + } + } + table { + border: solid 1px black; + border-collapse: collapse; + border-spacing: 0; + td, th { + border: solid 1px black; + padding: 0; + .cell_width { + display: block; + overflow: hidden; + height: 0px; + @extend input[type="text"]; + } + input { + outline: solid 1px black; + width: 100%; + background: transparent; + border: 0; + &:focus { + outline-color: blue; + @include box-shadow(inset 0 0 1pt 1pt rgba(0,0,1,.5)); + } + } } } } @@ -67,19 +100,12 @@ a { } input[type="text"], textarea { font-family: monospace; + font-size: 12pt; } iframe { width: 100%; height: 100%; } -table, td { - border: solid 1px black; -} -table input { - border: none; - width: 100%; - background: transparent; -} .error { font-weight: bold; color: red; -- cgit v1.2.3-2-g168b From f21d82c9eff383d2c1c45c94af5f6c355e3258b2 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 9 Oct 2011 01:05:11 -0400 Subject: Properly use thead and tbody. --- src/views/pages/users/index.html.php | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/views/pages/users/index.html.php b/src/views/pages/users/index.html.php index 7f51592..caedf5c 100644 --- a/src/views/pages/users/index.html.php +++ b/src/views/pages/users/index.html.php @@ -13,14 +13,27 @@ $t->openTag('form', array('action'=>$t->url('users/index'), $t->tag('input', array('type'=>'submit', 'value'=>'Save/Update')); -$t->openTag('table'); +$t->openTag('table', array('class'=>'sortable', 'id'=>'bar')); +$t->openTag('thead'); $t->openTag('tr'); foreach ($attribs as $attrib) { $t->tag('th', array(), $attrib['name']); } -$t->tag('th'); +$t->tag('th', array(), '-'); $t->closeTag('tr'); +$t->closeTag('thead'); + +$t->openTag('tfoot'); +$t->openTag('tr'); +foreach ($attribs as $attrib) { + $t->tag('th', array(), $attrib['name']); +} +$t->tag('th', array(), '-'); +$t->closeTag('tr'); +$t->closeTag('tfoot'); + +$t->openTag('tbody'); foreach ($users as $user) { $t->openTag('tr'); @@ -48,6 +61,7 @@ foreach ($users as $user) { $arr['value'] = 'true'; $arr['type'] = 'checkbox'; } else { + $t->tag('span', array('class'=>'cell_width'), $value); $arr['value'] = $value; $arr['type'] = 'text'; } @@ -66,13 +80,7 @@ foreach ($users as $user) { $t->closeTag('tr'); } -$t->openTag('tr'); -foreach ($attribs as $attrib) { - $t->tag('th', array(), $attrib['name']); -} -$t->tag('th'); -$t->closeTag('tr'); - +$t->closeTag('tbody'); $t->closeTag('table'); $t->tag('input', array('type'=>'submit', -- cgit v1.2.3-2-g168b From 0fd0403876aacecfde74fca0641530875f09200f Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Sun, 9 Oct 2011 03:25:12 -0400 Subject: Move Users->[gs]etConf into a new DB.class.php, add in some wrappers for equivalent stuff with plugin and system config. --- src/controllers/Users.class.php | 73 ++-------------------- src/lib/DB.class.php | 131 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 68 deletions(-) create mode 100644 src/lib/DB.class.php diff --git a/src/controllers/Users.class.php b/src/controllers/Users.class.php index a4403e3..54e4675 100644 --- a/src/controllers/Users.class.php +++ b/src/controllers/Users.class.php @@ -1,6 +1,7 @@ showView('users/500'); } else { Login::login($username, $password); - $this->setConf($uid, 'email', $vars['email']); + DB::set('users', $uid, 'email', $vars['email']); $this->showView('users/created', array('username'=>$username)); } @@ -284,8 +285,7 @@ class Users extends Controller { @$value_base = $old[$uid]; $we_changed_it = $value_base != $value; if ($we_changed_it) { - $user = Auth::getObj($uid); - $value_fork = $this->getConf($user,$key); + $value_fork = DB::get('users', $uid, $key); $value_fork = $value_fork['value']; if ($value_fork===false) $value_fork = 'false'; if ($value_fork===true) $value_fork = 'true'; @@ -305,7 +305,7 @@ class Users extends Controller { } } if ($doit) { - $this->setConf($uid, $key, $value); + DB::set('users', $uid, $key, $value); } if ($forked) { echo "
\n";
@@ -340,79 +340,16 @@ class Users extends Controller {
 		$vars['users'] = array();
 		$uids = $db->listUsers();
 		foreach ($uids as $uid) {
-			$user = Auth::getObj($uid);
 			$vars['users'][$uid] = array();
 			foreach ($vars['attribs'] as $attrib) {
 				$key = $attrib['key'];
-				$props = $this->getConf($user, $key);
+				$props = DB::get('users', $uid, $key);
 				$vars['users'][$uid][$key] = $props;
 			}
 		}
 		$this->showView('users/index', $vars);
 	}
-	
-	private function getConf($user, $key) {
-		$logged_in_user = Auth::getObj(Login::isLoggedIn());
-		$uid = $user->getUID();
-		$post_key = $key."[$uid]";
-		@$value = $_POST[$post_key];
-		$editable = $user->canEdit();
-		
-		switch ($key) {
-		case 'auth_uid':
-			$value = $user->getUID();
-			$editable = false;
-			break;
-		case 'auth_name':
-			$value = $user->getName();
-			break;
-		case 'auth_user':
-			$editable = $editable && $logged_in_user->isAdmin();
-			$value = $user->isUser();
-			break;
-		case 'auth_admin':
-			$editable = $editable && $logged_in_user->isAdmin();
-			$value = $user->isAdmin();
-			break;
-		case 'auth_delete':
-			$editable = $editable && $logged_in_user->isAdmin();
-			$value = false;
-			break;
-		default:
-			$value = $user->getConf($key);
-			if ($value===false) $value='';
-			break;
-		}
 		
-		return array('value'=>$value,
-		             'post_key'=>$post_key,
-		             'editable'=>$editable);
-	}
-	private function setConf($uid, $key, $value) {
-		// So, this rocks because we don't have to check permissions,
-		// the User object does that.
-		$user = Auth::getObj($uid);
-		
-		switch ($key) {
-		case 'auth_uid':
-			break;
-		case 'auth_name':
-			$user->setName($value);
-			break;
-		case 'auth_user':
-			$user->setUser($value=='true');
-			break;
-		case 'auth_admin':
-			$user->setAdmin($value=='true');
-			break;
-		case 'auth_delete':
-			if ($value=='true') $user->delete();
-		default: 
-			$user->setConf($key, $value);
-			break;
-		}
-	}
-	
 	function attrib($key, $name) {
 		return array('key'=>$key, 'name'=>$name);
 	}
diff --git a/src/lib/DB.class.php b/src/lib/DB.class.php
new file mode 100644
index 0000000..9f14161
--- /dev/null
+++ b/src/lib/DB.class.php
@@ -0,0 +1,131 @@
+canEdit();
+		
+		switch ($key) {
+		case 'auth_uid':
+			$value = $user->getUID();
+			$editable = false;
+			break;
+		case 'auth_name':
+			$value = $user->getName();
+			break;
+		case 'auth_user':
+			$editable = $editable && $logged_in_user->isAdmin();
+			$value = $user->isUser();
+			break;
+		case 'auth_admin':
+			$editable = $editable && $logged_in_user->isAdmin();
+			$value = $user->isAdmin();
+			break;
+		case 'auth_delete':
+			$editable = $editable && $logged_in_user->isAdmin();
+			$value = false;
+			break;
+		default:
+			$value = $user->getConf($key);
+			if ($value===false) $value='';
+			break;
+		}
+		
+		return array('value'=>$value,
+		             'post_key'=>$post_key,
+		             'editable'=>$editable);
+	}
+	private static function user_set($uid, $key, $value) {
+		$user = Auth::getObj($uid);
+		
+		switch ($key) {
+		case 'auth_uid':
+			return false;
+			break;
+		case 'auth_name':
+			return $user->setName($value);
+			break;
+		case 'auth_user':
+			return $user->setUser($value=='true');
+			break;
+		case 'auth_admin':
+			return $user->setAdmin($value=='true');
+			break;
+		case 'auth_delete':
+			if ($value=='true') return $user->delete();
+		default: 
+			return $user->setConf($key, $value);
+			break;
+		}
+	}
+	
+	private static function admin_get($plugin, $key) {
+		global $mm; $db = $mm->database();
+		$user = Auth::getObj(Login::isLoggedIn());
+		if ($user->isAdmin()) {
+			$editable = true;
+			switch ($plugin) {
+			case 'system':
+				$value = $db->getSysConf($key);
+				break;
+			default:
+				$value =  $db->getPluginConf($plugin, $key);
+				break;
+			}
+		} else {
+			$editable = false;
+			$value = false;
+		}
+		
+		return array('value'=>$value,
+		             'post_key'=>'to be implemented',// FIXME
+		             'editable'=>$editable);
+	}
+	private static function admin_set($plugin, $key, $value) {
+		global $mm; $db = $mm->database();
+		$user = Auth::getObj(Login::isLoggedIn());
+		if (!$user->isAdmin()) {
+			return false;
+		}
+		switch ($plugin) {
+		case 'system':
+			return $db->setSysConf($key, $value);
+		default:
+			return $db->setPluginConf($plugin, $key, $value);
+		}
+	}
+}
\ No newline at end of file
-- 
cgit v1.2.3-2-g168b