Browse Source

fixes #19: ability to delete a group

Davide Alberani 7 years ago
parent
commit
5ff4f725df
3 changed files with 65 additions and 3 deletions
  1. 21 3
      ibt2.py
  2. 34 0
      src/Group.vue
  3. 10 0
      tests/ibt2_tests.py

+ 21 - 3
ibt2.py

@@ -66,6 +66,9 @@ class BaseHandler(tornado.web.RequestHandler):
     arguments = property(lambda self: dict([(k, v[0])
         for k, v in self.request.arguments.iteritems()]))
 
+    # Arguments suitable for a query on MongoDB.
+    clean_arguments = property(lambda self: self._clean_dict(self.arguments))
+
     _re_split_salt = re.compile(r'\$(?P<salt>.+)\$(?P<hash>.+)')
 
     @property
@@ -228,7 +231,7 @@ class AttendeesHandler(BaseHandler):
         if id_:
             output = self.db.getOne(self.collection, {'_id': id_})
         else:
-            output = {self.collection: self.db.query(self.collection, self.arguments)}
+            output = {self.collection: self.db.query(self.collection, self.clean_arguments)}
         self.write(output)
 
     @gen.coroutine
@@ -280,7 +283,7 @@ class DaysHandler(BaseHandler):
 
     @gen.coroutine
     def get(self, day=None, **kwargs):
-        params = self.arguments
+        params = self.clean_arguments
         summary = params.get('summary', False)
         if summary:
             del params['summary']
@@ -366,6 +369,21 @@ class GroupsHandler(BaseHandler):
         merged, doc = self.db.update('groups', {'day': day, 'group': group}, data)
         self.write(doc)
 
+    @gen.coroutine
+    def delete(self, **kwargs):
+        data = self.clean_arguments
+        day = (data.get('day') or '').strip()
+        group = (data.get('group') or '').strip()
+        if not (day and group):
+            return self.build_error(status=404, message='unable to access the resource')
+        if not self.current_user_info.get('isAdmin'):
+            self.build_error(status=401, message='insufficient permissions: must be admin')
+            return False
+        query = {'day': day, 'group': group}
+        howMany = self.db.delete('attendees', query)
+        self.db.delete('groups', query)
+        self.write({'success': True, 'deleted entries': howMany.get('n')})
+
 
 class UsersHandler(BaseHandler):
     """Handle requests for Users."""
@@ -383,7 +401,7 @@ class UsersHandler(BaseHandler):
         else:
             if not self.current_user_info.get('isAdmin'):
                 return self.build_error(status=401, message='insufficient permissions: must be an admin')
-            output = {self.collection: self.db.query(self.collection, self.arguments)}
+            output = {self.collection: self.db.query(self.collection, self.clean_arguments)}
             for user in output['users']:
                 if 'password' in user:
                     del user['password']

+ 34 - 0
src/Group.vue

@@ -16,6 +16,10 @@
                                 <span>edit notes</span>
                                 <md-icon>edit</md-icon>
                             </md-menu-item>
+                            <md-menu-item v-if="loggedInUser.isAdmin" @click="openDeleteGroupDialog()">
+                                <span>delete group</span>
+                                <md-icon>delete</md-icon>
+                            </md-menu-item>
                         </md-menu-content>
                     </md-menu>
                 </md-layout>
@@ -90,6 +94,14 @@
                     :md-cancel-text="noteDialog.cancel"
                     ref="dialogGroupNotes">
         </md-dialog-prompt>
+        <md-dialog-confirm
+                    @close="dialogDeleteGroupClose"
+                    :md-title="deleteDialog.title"
+                    :md-content="deleteDialog.content"
+                    :md-ok-text="deleteDialog.ok"
+                    :md-cancel-text="deleteDialog.cancel"
+                    ref="dialogDeleteGroup">
+        </md-dialog-confirm>
     </md-layout>
 </template>
 <script>
@@ -108,6 +120,7 @@ export default {
             newGroup: '',
             groupNotes: '',
             noteDialog: {title: 'Group notes', ok: 'ok', cancel: 'cancel'},
+            deleteDialog: {title: 'Delete group', content: 'Really delete this group?', ok: 'ok', cancel: 'cancel'},
             expandedNote: false
         }
     },
@@ -115,6 +128,9 @@ export default {
     computed: {
         counter: function() {
             return (this.group.attendees || []).length;
+        },
+        loggedInUser() {
+            return this.$store.state.loggedInUser;
         }
     },
 
@@ -196,6 +212,24 @@ export default {
                 $(this.$refs.groupNotes.$el).find('p').css('white-space', 'nowrap');
                 this.expandedNote = false;
             }
+        },
+
+        openDeleteGroupDialog() {
+            this.$refs.dialogDeleteGroup.open();
+        },
+
+        dialogDeleteGroupClose(type) {
+            if (type != 'ok' || !this.group || !this.group.group || !this.day || !this.loggedInUser.isAdmin) {
+                return;
+            }
+            var data = {day: this.day, group: this.group.group};
+            this.groupsUrl.delete(data).then((response) => {
+                return response.json();
+            }, (response) => {
+                this.$refs.dialogObj.show({text: 'unable to delete this group'});
+            }).then((json) => {
+                this.$emit('updated');
+            });
         }
     },
 

+ 10 - 0
tests/ibt2_tests.py

@@ -208,6 +208,16 @@ class Ibt2Tests(unittest.TestCase):
         rj = r.json()
         self.assertTrue(dictInDict(group, rj['groups'][0]))
 
+    def test_delete_group(self):
+        self.add_attendee({'day': '2017-01-16', 'name': 'A new name', 'group': 'A group'})
+        s = self.login('admin', 'ibt2')
+        r = s.delete(BASE_URL + 'groups', params={'day': '2017-01-16', 'group': 'A group'})
+        r.raise_for_status()
+        rj = r.json()
+        r = requests.get(BASE_URL + 'days/2017-01-16')
+        r.raise_for_status()
+        rj = r.json()
+        self.assertTrue(rj == {})
 
 if __name__ == '__main__':
     unittest.main(verbosity=2)