From e6fd645b6af5c3b71ad07fa7a5533b0c675af544 Mon Sep 17 00:00:00 2001
From: Alexander Olofsson <alexander.olofsson@liu.se>
Date: Fri, 15 Dec 2017 14:00:00 +0100
Subject: [PATCH] Fix up per-user settings

---
 client/App.vue    |  2 +-
 config.js.example | 18 ++++++++++++------
 server/auth.js    |  9 ++++++++-
 server/users.js   | 20 +++++++++++---------
 4 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/client/App.vue b/client/App.vue
index 60ae20c..d340a70 100644
--- a/client/App.vue
+++ b/client/App.vue
@@ -32,7 +32,7 @@
           </div>
         </transition>
 
-        <h2 class="mt-4 mb-3">Existing external users: ({{ external.length }}/{{ user.user_limit }})</h2>
+        <h2 class="mt-4 mb-3">Existing external users: ({{ external.length }}/<span v-if="user.user_limit > 0">{{ user.user_limit }}</span><span v-else>&infin;</span>)</h2>
         <hr/>
         <transition name="fade" mode="out-in">
           <ul class="list-unstyled" is="transition-group" name="flip-list" v-if="external">
diff --git a/config.js.example b/config.js.example
index d9edd4f..ddbb259 100644
--- a/config.js.example
+++ b/config.js.example
@@ -34,21 +34,27 @@ module.exports = {
     reset_password: true
   },
 
-  // Can users deactivate external users created by them
-  can_user_deactivate: false,
-  // Default limit of external users
-  external_limit: 5,
+  user: {
+    // Can users deactivate external users created by them
+    can_deactivate: false,
+    // Default limit of external users
+    external_limit: 5,
+  }
 
   // Apply configuration per user
   //
   // *user* will contain the parameters from https://gitlab.liu.se/help/api/users.md#for-admin
+  // *config* will contain the same as the `user` block
   per_user: function(user, config) {
     if (user.external) {
       // Disallow creation by external users
       config.external_limit = 0
-    } else if (user.username =~ /^[a-z]{4}[0-9]{2}$/) {
+    } else if (user.is_admin) {
       // Unlimited external users
-      config.external_limit = null
+      config.external_limit = -1
+    } else if (user.username =~ /^[a-z]{4}[0-9]{2}$/) {
+      // More external users
+      config.external_limit = 15
     }
   }
 }
diff --git a/server/auth.js b/server/auth.js
index 9eba839..e524b34 100644
--- a/server/auth.js
+++ b/server/auth.js
@@ -15,6 +15,13 @@ var _strategy = new GitLabStrategy({
     baseURL: config.gitlab.url
   }, (access, refresh, profile, cb) => {
     var user = Object.assign({}, profile, { _token: access, _refresh: refresh });
+
+    var userConfig = Object.assign({}, config.user);
+    if (typeof(config.per_user) === 'function') {
+      config.per_user(Object.assign({}, user._json), userConfig);
+    }
+    user.eum_settings = userConfig
+
     cb(null, user);
   }
 );
@@ -40,7 +47,7 @@ router.get('/', (req, res) => {
   console.log('GET: /auth');
 
   if (req.user) {
-    res.send(Object.assign({}, req.user._json, { user_limit: config.external_limit }));
+    res.send(Object.assign({}, req.user._json, { eum_settings: req.user.eum_settings }));
   } else {
     res.status(401).send({ message: 'Not authenticated' });
   }
diff --git a/server/users.js b/server/users.js
index d69bb69..96f9318 100644
--- a/server/users.js
+++ b/server/users.js
@@ -37,17 +37,19 @@ router.post('/', async (req, res) => {
     .filter( key => ['email','username','name','skype','linkedin','twitter','website_url','organization','bio','location','avatar'].includes(key) )
     .reduce( (rs, key) => (rs[key] = req.body[key], rs), {} );
 
-  try {
-    const queryText = 'SELECT * FROM external_users WHERE owner_id = $1';
-    const dbResponse = await db.query(queryText, [req.user.id]);
+  if (req.user.eum_settings.external_limit > 0) {
+    try {
+      const queryText = 'SELECT * FROM external_users WHERE owner_id = $1';
+      const dbResponse = await db.query(queryText, [req.user.id]);
 
-    if (dbResponse.rowCount >= config.external_limit) {
-      return res.status(403).send({ 'message': 'External user limit reached' });
+      if (dbResponse.rowCount >= req.user.eum_settings.external_limit) {
+        return res.status(403).send({ 'message': 'External user limit reached' });
+      }
+    } catch(err) {
+      console.log("> DB Error:");
+      console.log(err);
+      return res.status(500).send({ 'message': "Database error occured" });
     }
-  } catch(err) {
-    console.log("> DB Error:");
-    console.log(err);
-    return res.status(500).send({ 'message': "Database error occured" });
   }
 
   // TODO: Apply further validation on input
-- 
GitLab