diff --git a/db_schema.sql b/db_schema.sql index b0c5c1fb89e7483d133aad71ebe40184dc3209a9..17034efec052294815572a4a48fc2719a7035de4 100644 --- a/db_schema.sql +++ b/db_schema.sql @@ -105,14 +105,18 @@ CREATE TABLE IF NOT EXISTS `places` ( `campus_room` varchar(20) NOT NULL, `campus_name` varchar(30) NOT NULL ); -CREATE TABLE IF NOT EXISTS `auth` ( +CREATE TABLE IF NOT EXISTS `auth_data` ( `auth_id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + `deleted` INTEGER NOT NULL DEFAULT '0', `course_id` INTEGER, `lecture_id` INTEGER, `video_id` INTEGER, `auth_type` varchar(10), `auth_user` varchar(127), - `auth_passwd` varchar(127) + `auth_passwd` varchar(127), + `time_created` datetime NOT NULL, + `time_updated` datetime NOT NULL, + `created_by` INTEGER DEFAULT NULL ); CREATE TABLE IF NOT EXISTS `site_texts` ( `key` varchar(64) NOT NULL PRIMARY KEY, @@ -218,4 +222,5 @@ CREATE TABLE IF NOT EXISTS `sortlog` ( CREATE VIEW IF NOT EXISTS `courses` AS select * from `courses_data` where (not(`courses_data`.`deleted`)); CREATE VIEW IF NOT EXISTS `lectures` AS select * from `lectures_data` where (not(`lectures_data`.`deleted`)); CREATE VIEW IF NOT EXISTS `videos` AS select * from `videos_data` where (not(`videos_data`.`deleted`)); +CREATE VIEW IF NOT EXISTS `auth` AS select * from `auth_data` where (not(`auth_data`.`deleted`)); COMMIT; diff --git a/server.py b/server.py index 09dc2cda4cef53c7c02fadc83c3c9f2db0bbac14..91add2c26fc11eca021086cedd09a303eea1d8c3 100644 --- a/server.py +++ b/server.py @@ -70,6 +70,7 @@ def mod_required(func): return decorator app.jinja_env.globals['navbar'] = [] +app.jinja_env.globals['acls'] = [] # iconlib can be 'bootstrap' # ( see: http://getbootstrap.com/components/#glyphicons ) # or 'fa' @@ -284,8 +285,8 @@ tabs = { ['created_by', 'time_created', 'time_updated']), 'featured': ('featured', 'id', ['title', 'text', 'internal', 'visible', 'deleted'], ['created_by', 'time_created', 'time_updated']), - 'auth': ('auth', 'auth_id', ['auth_type', 'auth_user', 'auth_passwd'], - ['course_id', 'lecture_id', 'video_id']) + 'auth': ('auth_data', 'auth_id', ['auth_type', 'auth_user', 'auth_passwd', 'deleted'], + ['course_id', 'lecture_id', 'video_id', 'created_by', 'time_created', 'time_updated']) } @app.route('/edit', methods=['GET', 'POST']) diff --git a/static/moderator.js b/static/moderator.js index d71a1f7dfb8817cc4c9137f9f00cf8603c5064ee..9dc8fe8c01392c24d191e9d9bd83b84d6b22e6d7 100644 --- a/static/moderator.js +++ b/static/moderator.js @@ -24,8 +24,76 @@ var moderatorinterface = { } ); } + $('.modeditacl').popover( + { + title: "acls", + html: true, + placement: "left", + trigger: 'click', + container: 'body', + content: function () { + var html = ''; + var id = $(this).data('id'); + var type = $(this).data('type'); + html += '<div width="300px" class="row" data-id="'+id+'" data-type="'+type+'">'; + html += '<select onchange="moderatorinterface.selectacl(this)" size="6" class="col-xs-12 acllist">'; + var idlist = []; + for (i in moderatorinterface.acls) { + if ((moderatorinterface.acls[i][type+'_id'] == id)) { + var auth = {}; + auth.type = moderatorinterface.acls[i]['auth_type']; + auth.user = moderatorinterface.acls[i]['auth_user']; + auth.password = moderatorinterface.acls[i]['auth_passwd']; + auth.id = moderatorinterface.acls[i]['auth_id']; + idlist[idlist.length] = auth.id; + html += '<option data-auth_id="'+auth.id+'">#'+auth.id+' '+auth.type+' '+ ( auth.type == "password" ? ' ("'+auth.user+'":"'+auth.password+'")' : '' ) +'</option>'; + } + console.log(moderatorinterface.acls[i]['deleted']); + } + html += '</select>'; + html += '<select class="col-xs-12 authtype" onchange="moderatorinterface.acltypechange(this)"><option value="public">public</option><option selected value="password">password</option></select>'; + html += '<input class="col-xs-12 passwordinput authuser" type="text" placeholder="username">'; + html += '<input class="col-xs-12 passwordinput authpassword" type="text" placeholder="password">'; + html += '<button class="col-xs-6" onclick="moderatorinterface.addacl(this)">Add</button>'; + //html += '<button class="col-xs-4" onclick="moderatorinterface.delacl(this)">Update</button>'; + html += '<button class="col-xs-6" onclick="moderatorinterface.delacl(this)">Delete</button>'; + html += '</div>'; + return html; + } + } + ); }) }, + selectacl: function (element) { + + }, + delacl: function (element) { + moderatorinterface.set("auth."+$(".acllist option:selected", element.parentElement).data('auth_id')+".deleted",1,true); + }, + addacl: function (element) { + var auth = {}; + auth.type = $(".authtype", element.parentElement).val(); + if (auth.type == "password") { + auth.user = $(".authuser", element.parentElement).val(); + auth.password = $(".authpassword", element.parentElement).val(); + } + moderatorinterface.set('') + dict = {} + dict['auth_type'] = auth.type; + dict['auth_user'] = auth.user; + dict['auth_passwd'] = auth.password; + dict[$(element.parentElement).data('type')+'_id'] = $(element.parentElement).data('id'); + + moderatorinterface.add_new(dict,'auth',true); + var option = $('<option>', { + "text": auth.type+' '+( auth.type == "password" ? ' ("'+auth.user+'":"'+auth.password+'")' : '' ) , + "data-auth": JSON.stringify(auth) + }); + $(".acllist",element.parentElement).append(option); + }, + acltypechange: function (element) { + $(".passwordinput",element.parentElement).toggle(); + }, edit: function (src) { var path = $($(src)[0]).data('path'); var value = $(".editorvalue")[0].value; @@ -49,12 +117,29 @@ var moderatorinterface = { set: function(path,value,reload=false) { var req = {}; req[path] = value; + moderatorinterface.set_multi(req,reload) + }, + set_multi: function(dict,reload=false) { $.ajax({ method: "POST", url: "/edit", dataType: "text", contentType: "application/json", - data: JSON.stringify(req), + data: JSON.stringify(dict), + success: function () { + if (reload) { + window.location.reload(); + } + } + }) + }, + add_new: function(dict,table,reload=false) { + $.ajax({ + method: "POST", + url: "/new/"+table, + dataType: "text", + contentType: "application/json", + data: JSON.stringify(dict), success: function () { if (reload) { window.location.reload(); @@ -73,6 +158,18 @@ var moderatorinterface = { url: url, dataType: "text", }) + }, + acls: [], + setacls: function(value) { + var idlist = []; + for (i in value) { + for (j in value[i]) { + if (idlist.indexOf(value[i][j]['auth_id']) == -1) { + idlist[idlist.length] = value[i][j]['auth_id']; + moderatorinterface.acls[moderatorinterface.acls.length] = value[i][j]; + } + } + } } }; diff --git a/templates/base.html b/templates/base.html index 65e83961a507dff55d92e1099f6ce1a43050db36..718965cc13bc11a20a8ef7a9dde42e6d530c9bf1 100644 --- a/templates/base.html +++ b/templates/base.html @@ -139,4 +139,9 @@ </div> </footer> </body> + {% if ismod() %} + <script> + moderatorinterface.setacls({{acls|tojson|safe}}) + </script> + {% endif %} </html> diff --git a/templates/course.html b/templates/course.html index c016831f1a2975620cc9462bac3f0232e93537d1..d7ab92605378a342e790e7fdfeb907b3bb50d014 100644 --- a/templates/course.html +++ b/templates/course.html @@ -12,7 +12,7 @@ <h1 class="panel-title">{{ valueeditor(['courses',course.id,'title'], course.title)}} <ul class="pull-right list-inline"> <li>{{ valuedeletebtn(['courses',course.id,'deleted']) }}</li> - <li>{{ editacl([]) }}</li> + <li>{{ editacl('course',course.id,course.auth) }}</li> </ul> </h1> </div> diff --git a/templates/macros.html b/templates/macros.html index c4ff0f7a338a1ce7ae13f358fd3aefacdd07229a..701a52a79add13d885adcc6c07580bf99c58c3c4 100644 --- a/templates/macros.html +++ b/templates/macros.html @@ -152,7 +152,7 @@ $('#embedcodebtn').popover( {{ valuedeletebtn(['lectures',lecture.id,'deleted']) }} </li> <li> - {{ editacl([]) }} + {{ editacl('lecture', lecture.id, lecture.auth) }} </li> </ul> </div> @@ -182,16 +182,17 @@ $('#embedcodebtn').popover( {% endif %} {% endmacro %} -{% macro editacl(acl) %} - {% if not acl %} +{% macro editacl(type,id,acl) %} + {{ acls.append(acl) }} + {% if (not acl) %} {% if ismod() %} - <button class="btn btn-default" onclick=""> - <span class="fa fa-unlock" aria-hidden="true" style="color: green;"></span> - </button> + <button class="btn btn-default modeditacl" data-type="{{ type }}" data-id="{{ id }}"> + <span class="fa fa-unlock" aria-hidden="true" style="color: green;"></span> + </button> {% endif %} {% else %} {% if ismod() %} - <button class="btn btn-default" onclick=""> + <button class="btn btn-default modeditacl" data-type="{{ type }}" data-id="{{ id }}" onclick=""> {% else %} <a> {% endif %} @@ -201,7 +202,6 @@ $('#embedcodebtn').popover( {% else %} </a> {% endif %} - {% endif %} {% endmacro %}