Commit 5c764bdb authored by buttle's avatar buttle

Added change author

parent 640503c9
......@@ -31,8 +31,8 @@ babel = Babel(app)
csrf = CSRFProtect()
csrf.init_app(app)
app.config['APP_VERSION'] = 28
app.config['SCHEMA_VERSION'] = 12
app.config['APP_VERSION'] = 29
app.config['SCHEMA_VERSION'] = 13
app.config['RESERVED_SLUGS'] = ['static', 'admin', 'admins', 'user', 'users', 'form', 'forms', 'site', 'sites', 'update']
# DPL = Data Protection Law
......
......@@ -22,6 +22,7 @@ from flask_babel import gettext
from GNGforms import app
from GNGforms.persistence import Site
import smtplib, socket
from threading import Thread
def createSmtpObj():
config=g.site.data["smtpConfig"]
......
......@@ -150,5 +150,11 @@ def migrateMongoSchema(schemaVersion):
mongo.db.forms.update_one({"_id": form["_id"]}, {"$set": {"restrictedAccess": False}})
schemaVersion=12
if schemaVersion == 12:
# Add admin prefs. to forms
for form in mongo.db.forms.find():
mongo.db.forms.update_one({"_id": form["_id"]}, {"$set": {"adminPreferences": { "public": True }}})
schemaVersion=13
# this can't be a good migration setup :(
return schemaVersion
......@@ -194,7 +194,8 @@ class User(object):
@property
def forms(self):
return Form().findAll(editor=str(self._id))
#return Form().findAll(editor=str(self._id))
return [Form(_id=form['_id']) for form in Form().findAll(editor=str(self._id))]
@property
def admin(self):
......@@ -340,7 +341,21 @@ class Form(object):
@property
def author(self):
return self.form['author']
@author.setter
def author(self, value):
self.form["author"]=value
def changeAuthor(self, new_author):
if new_author.enabled:
if self.author in self.editors:
del self.editors[self.author]
self.author=str(new_author._id)
if self.addEditor(new_author):
self.save()
return True
return False
@property
def user(self):
return User(_id=self.form['author'])
......@@ -393,15 +408,22 @@ class Form(object):
@property
def enabled(self):
if not self.form['adminPreferences']['public']:
return False
return self.form['enabled']
def newEditorPreferences(cls):
return {'notification': {'newEntry': False, 'expiredForm': True}}
def addEditor(self, editor_id):
def addEditor(self, editor):
if not editor.enabled:
return False
editor_id=str(editor._id)
if not editor_id in self.form['editors']:
self.form['editors'][editor_id]=Form().newEditorPreferences()
mongo.db.forms.update_one({'_id': self.form['_id']}, {"$set": {"editors": self.form['editors']}})
return True
return False
def removeEditor(self, editor_id):
if editor_id == self.author:
......@@ -569,13 +591,18 @@ class Form(object):
return "%s/%s/%s" % (self.url, part, self.form['sharedEntries']['key'])
def toggleEnabled(self):
if self.expired:
if self.expired or self.form['adminPreferences']['public']==False:
return False
else:
self.form['enabled'] = False if self.form['enabled'] else True
mongo.db.forms.save(self.form)
return self.form['enabled']
def toggleAdminFormPublic(self):
self.form['adminPreferences']['public'] = False if self.form['adminPreferences']['public'] else True
mongo.db.forms.save(self.form)
return self.form['adminPreferences']['public']
def toggleSharedEntries(self):
self.form['sharedEntries']['enabled'] = False if self.form['sharedEntries']['enabled'] else True
mongo.db.forms.save(self.form)
......
{% extends "base.html" %}
{% block content %}
<div class="container">
<div class="row col-md-3"></div>
<div class="row col-md-7" style="font-size:1.5em">
<input class="btn-primary btn btn-sm" type="button" value="{%trans%}Return to form{%endtrans%}" onClick="location.href='/forms/view/{{ form._id }}'">
{{ form.slug }}
<hr />
</div>
<div class="row col-md-2"></div>
</div>
<div class="container">
<div class="row col-md-3"></div>
<div class="row col-md-5">
<div style="font-size:1.5em; padding-bottom:1em;">
{%trans%}Change author{%endtrans%}
</div>
<table class="table table-striped table-condensed">
<tr>
<td>{%trans%}Current author{%endtrans%}</td>
<td>{{ form.user.username }}</td>
</tr>
</table>
{%trans%}You are going to change the author of this form.{%endtrans%}<br />
{%trans%}Are you sure?{%endtrans%}
<p>&nbsp;</p>
<form action="/admin/forms/change-author/{{form._id}}" method="POST">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
<input name="new_author_username" type="text" placeholder="{%trans%}New author's username{%endtrans%}" class="form-control" required />
<p></p>
<input class="btn-primary btn btn-md" type="submit" value="{%trans%}Change author{%endtrans%}" />
</form>
{% if editors|length > 1 %}
<p>&nbsp;</p>
<div style="font-size:1.5em;">
{%trans%}Editors{%endtrans%}
</div>
<div>
{%trans%}Users listed here have the <b>same permissions</b> as the author{%endtrans%}
</div>
<p style="padding-top:1.2em;"></p>
<table class="table table-condensed">
{% for editor in editors %}
<tr id="editor_{{editor._id}}">
<td>{{ editor.username }}</td>
<td>{{ editor.email }}</td>
<td class="text-right">
{% if editor._id|string == form.author %}
({%trans%}Author{%endtrans%})
{% else %}
<input class="btn btn-xs btn-danger" type="button" value="{%trans%}Remove{%endtrans%}" onClick="js:removeEditor('{{editor._id}}');">
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
</div>
<div class="row col-md-4"></div>
</div>
<script>
var csrftoken = "{{ csrf_token() }}";
function removeEditor(editor_id){
$.ajax({
url : "/forms/remove-editor/{{form._id}}/"+editor_id,
type: "POST",
dataType: "json",
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type)) {
xhr.setRequestHeader("X-CSRFToken", csrftoken)
}
},
success: function(data, textStatus, jqXHR)
{
if (data == editor_id) {
$('#editor_'+editor_id).hide();
}
}
});
}
</script>
{% endblock %}
......@@ -11,7 +11,7 @@
{%trans%}Delete user{%endtrans%}
</div>
<hr />
{% set formCount=user.forms.count() %}
{% set formCount=user.forms|length %}
{%trans%}You are going to delete a user{%endtrans%}
{% if formCount %}
{%trans%}and their forms{%endtrans%}
......
......@@ -55,7 +55,7 @@
</td>
</tr>
<tr>
<td>{%trans%}Published{%endtrans%}</td>
<td>{%trans%}Public{%endtrans%}</td>
<td>
{% if form.editors[g.current_user._id|string] is defined %}
<div id="toggle_enabled" class="btn-group btn-toggle">
......@@ -63,10 +63,7 @@
<button id="enabled_false" class="btn btn-xs btn-default {% if not form.isPublic() %}btn-primary{% endif %}">{%trans%}False{%endtrans%}</button>
</div>
{% else %}
{{ form.isPublic() }}
{% if not form.user.enabled %}
<span style="color:red">({%trans%}user disabled{%endtrans%})</span>
{% endif %}
{{ form.isPublic() }}
{% endif %}
</td>
</tr>
......@@ -93,7 +90,12 @@
</td>
</tr>
<tr>
<td>{%trans%}Public URL{%endtrans%}</td>
<td>
{%trans%}Public URL{%endtrans%}
{% if not form.data['adminPreferences']['public'] %}
<span style="color:red">({%trans%}disabled{%endtrans%})</span>
{% endif %}
</td>
<td>
{% if form.isPublic() %}
<a id="formLink" href="{{ form.url }}">{{ form.url }}</a>
......@@ -148,12 +150,19 @@
</tr>
{% endif %}
<tr>
<td>{%trans%}Author{%endtrans%}</td>
<td>
{%trans%}Author{%endtrans%}
{% if not form.user.enabled %}
<span style="color:red">({%trans%}disabled{%endtrans%})</span>
{% endif %}
</td>
<td>
{% if g.isAdmin %}
<td><a href="/admin/users/{{ form.user._id }}">{{ form.user.username }}</a></td>
<a href="/admin/users/{{ form.user._id }}">{{ form.user.username }}</a>
{% else %}
<td>{{ form.user.username }}</td>
{{ form.user.username }}
{% endif %}
</td>
</tr>
<tr>
<td>{%trans%}Created{%endtrans%}</td>
......@@ -178,6 +187,19 @@
<input class="btn-danger btn btn-sm" type="button" value="{%trans%}Delete form and entries{%endtrans%}" onClick="location.href='/forms/delete/{{ form._id }}'">
{% endif %}
{% endif %}
{% if g.isAdmin %}
<div style="font-size:1.5em; padding-top:1em;">
{%trans%}Admin options{%endtrans%}
</div>
<hr />
<input class="btn-primary btn btn-sm" type="button" value="{%trans%}Change author{%endtrans%}" onClick="location.href='/admin/forms/change-author/{{form._id}}'" >
{% if form.data['adminPreferences']['public'] %}
<input class="btn-danger btn btn-sm" type="button" value="{%trans%}Disable form{%endtrans%}" onClick="location.href='/admin/forms/toggle-public/{{form._id}}'" >
{% else %}
<input class="btn-primary btn btn-sm" type="button" value="{%trans%}Enable form{%endtrans%}" onClick="location.href='/admin/forms/toggle-public/{{form._id}}'" >
{% endif %}
{% endif %}
</div>
</div>
......
......@@ -48,7 +48,7 @@
<tr>
<td>{%trans%}Validated email{%endtrans%}</td>
<td> {% if user.data.validatedEmail %}
<span style="color:green">{%trans%}True{%endtrans%}</span>
<span>{%trans%}True{%endtrans%}</span>
{% else %}
<span style="color:red">{%trans%}False{%endtrans%}</span>
{% endif %}
......@@ -65,7 +65,7 @@
</tr>
</table>
{% if g.isAdmin and not user._id == g.current_user._id %}
{% if user.forms.count() %}
{% if user.forms|length %}
<input class="btn-danger btn btn-sm" type="button" value="{%trans%}Delete user and authored forms{%endtrans%}" onClick="location.href='/admin/users/delete/{{user._id}}'">
{% else %}
<input class="btn-danger btn btn-sm" type="button" value="{%trans%}Delete user{%endtrans%}" onClick="location.href='/admin/users/delete/{{user._id}}'">
......@@ -87,7 +87,7 @@
<th>{%trans%}Created{%endtrans%}</th>
<th>{%trans%}Author{%endtrans%}</th>
<th>{%trans%}Editors{%endtrans%}</th>
<th>{%trans%}Enabled{%endtrans%}</th>
<th>{%trans%}Public{%endtrans%}</th>
<th>{%trans%}Entries{%endtrans%}</th>
</tr>
</thead>
......
......@@ -37,7 +37,7 @@
<td>{{user.data.created}}</td>
<td>{{user.enabled}}</td>
<td>{{user.email}}</td>
<td>{{user.forms.count()}}</td>
<td>{{user.forms|length}}</td>
<td>{{user.isAdmin()}}</td>
</tr>
{% endfor %}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -24,9 +24,9 @@ from GNGforms import app, mongo, babel
from threading import Thread
from flask_babel import gettext, refresh
from GNGforms.persistence import *
from .session import *
from .utils import *
from .email import *
from GNGforms.session import *
from GNGforms.utils import *
from GNGforms.email import *
from form_templates import formTemplates
import pprint
......@@ -275,17 +275,17 @@ def add_editor(_id):
if not isValidEmail(request.form['email']):
return redirect(make_url_for('share_form', _id=queriedForm._id))
newEditor=User(hostname=g.site.hostname, email=request.form['email'], validatedEmail=True)
if not newEditor:
newEditor=User(hostname=g.site.hostname, email=request.form['email'])
if not newEditor or newEditor.enabled==False:
flash(gettext("Can't find a user with that email"), 'warning')
return redirect(make_url_for('share_form', _id=queriedForm._id))
if str(newEditor._id) in queriedForm.editors:
flash(gettext("%s is already an editor" % newEditor.email), 'warning')
return redirect(make_url_for('share_form', _id=queriedForm._id))
queriedForm.addEditor(str(newEditor._id))
flash(gettext("New editor added ok"), 'success')
queriedForm.addLog(gettext("Added editor %s" % newEditor.email))
if queriedForm.addEditor(newEditor):
flash(gettext("New editor added ok"), 'success')
queriedForm.addLog(gettext("Added editor %s" % newEditor.email))
return redirect(make_url_for('share_form', _id=queriedForm._id))
......@@ -530,7 +530,8 @@ def save_form(_id=None):
"afterSubmitText": afterSubmitText,
"log": [],
"requireDataConsent": g.site.isPersonalDataConsentEnabled(),
"restrictedAccess": False
"restrictedAccess": False,
"adminPreferences": { "public": True }
}
newForm=Form().insert(newFormData)
clearSessionFormData()
......@@ -901,14 +902,11 @@ def new_user(token=None):
if not user:
flash(gettext("Opps! An error ocurred when creating the user"), 'error')
return render_template('new-user.html')
if invite:
invite.delete()
@after_this_request
def send_newuser_email(response):
smtpSendNewUserNotification(User().getNotifyNewUserEmails(), user.username)
return response
invite.delete()
thread = Thread(target=smtpSendNewUserNotification(User().getNotifyNewUserEmails(), user.username))
thread.start()
if validatedEmail == True:
# login an invited user
......@@ -1377,7 +1375,40 @@ def list_forms():
forms = [Form(_id=form['_id']) for form in Form().findAll()]
return render_template('list-forms.html', forms=forms)
@app.route('/admin/forms/toggle-public/<string:_id>', methods=['GET'])
@admin_required
def toggle_form_public_admin_prefs(_id):
queriedForm = Form(_id=_id)
if not queriedForm:
flash(gettext("Can't find that form"), 'warning')
return redirect(make_url_for('my_forms'))
queriedForm.toggleAdminFormPublic()
return redirect(make_url_for('inspect_form', _id=_id))
@app.route('/admin/forms/change-author/<string:_id>', methods=['GET', 'POST'])
@admin_required
def change_author(_id):
queriedForm = Form(_id=_id)
if not queriedForm:
flash(gettext("Form is not available"), 'warning')
return redirect(make_url_for('my_forms'))
if request.method == 'POST':
if 'new_author_username' in request.form:
new_author=User(username=request.form['new_author_username'], hostname=g.site.hostname)
if new_author:
if new_author.enabled:
old_author=queriedForm.user # we really need to find better property names than author and user
if queriedForm.changeAuthor(new_author):
queriedForm.addLog(gettext("Changed author from %s to %s" % (old_author.username, new_author.username)))
flash(gettext("Changed author OK"), 'success')
return redirect(make_url_for('inspect_form', _id=queriedForm._id))
else:
flash(gettext("Cannot use %s. The user is not enabled" % request.form['new_author_username']), 'warning')
else:
flash(gettext("Can't find username %s" % request.form['new_author_username']), 'warning')
editors=[User(_id=user_id) for user_id in queriedForm.editors]
return render_template('change-author.html', form=queriedForm, editors=editors)
"""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment