added a small bcrypt secret to protect edit pages
This commit is contained in:
parent
6fe2cda71a
commit
acc7d0da1a
33
library/borrowform.py
Normal file
33
library/borrowform.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
"""Form object declaration."""
|
||||||
|
from flask_wtf import FlaskForm
|
||||||
|
from wtforms import (
|
||||||
|
StringField,
|
||||||
|
SubmitField,
|
||||||
|
)
|
||||||
|
from wtforms import validators
|
||||||
|
from wtforms.validators import Length
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class BorrowForm(FlaskForm):
|
||||||
|
"""Borrow a book form."""
|
||||||
|
|
||||||
|
borrowed = StringField(
|
||||||
|
"Fill in your name if you're going to borrow this publication.",
|
||||||
|
[
|
||||||
|
validators.InputRequired(),
|
||||||
|
Length(
|
||||||
|
min=3, message="Just so we know who is borrowing this book."
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
secret = StringField(
|
||||||
|
"Librarians secret:",
|
||||||
|
[
|
||||||
|
validators.InputRequired(),
|
||||||
|
Length(
|
||||||
|
min=2, message="Fill in the secret to unlock to library."
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
submit = SubmitField("Borrow")
|
@ -1,6 +1,6 @@
|
|||||||
Id,Publication,Author,Year,Custodian,Fields,Type,Publishers,License,LicenseShort,Highlights,Comments,Currently borrowed by
|
Id,Publication,Author,Year,Custodian,Fields,Type,Publishers,License,LicenseShort,Highlights,Comments,Currently borrowed by
|
||||||
1,The Economics of Anarchism,Anarcho,2012,Varia,"Economics, Anarchism",Zine,theanarchistlibrary.org,Anti-copyright,Anti-copyright,"The labourer retains, even after he has recieved his wages, a natural right in the thing he has produced",,No one
|
1,The Economics of Anarchism,Anarcho,2012,Varia,"Economics, Anarchism",Zine,theanarchistlibrary.org,Anti-copyright,Anti-copyright,"The labourer retains, even after he has recieved his wages, a natural right in the thing he has produced",,No one
|
||||||
2,Identity Politics - An Anthology,The Anarchist Library,,Varia,Identity politics,Zine,Paper Jam Collective,No license mentioned,No license mentioned,,me,
|
2,Identity Politics - An Anthology,The Anarchist Library,,Varia,Identity politics,Zine,Paper Jam Collective,No license mentioned,No license mentioned,,me,Danny
|
||||||
3,The mythology of work,CrimeThinc.com,,Varia,"Work, Anticapitalism",Zine,CrimeThinc.com,No license mentioned,No license mentioned,,"A selection from 'Work', a 376-page analysis of contemporary capitalism",
|
3,The mythology of work,CrimeThinc.com,,Varia,"Work, Anticapitalism",Zine,CrimeThinc.com,No license mentioned,No license mentioned,,"A selection from 'Work', a 376-page analysis of contemporary capitalism",
|
||||||
4,Forget Shorter Showers - Why Personal Change Does Not Equal Political Change,Derrick Jensen,2009,Varia,Environmental justice,Zine,,No license mentioned,No license mentioned,Green consumerism isn't enough.,,
|
4,Forget Shorter Showers - Why Personal Change Does Not Equal Political Change,Derrick Jensen,2009,Varia,Environmental justice,Zine,,No license mentioned,No license mentioned,Green consumerism isn't enough.,,
|
||||||
5,Choreo-Graphic-Hypothesis,"<meta-author=""Joana Chicau"";>",2018,Varia,"Live Coding, Choreography",Paperback,Self published: Joana Chicau,Free Art License 1.3,Free Art License,"Theatrical actions are not necessary to the performance, Avoid if at all possible",,
|
5,Choreo-Graphic-Hypothesis,"<meta-author=""Joana Chicau"";>",2018,Varia,"Live Coding, Choreography",Paperback,Self published: Joana Chicau,Free Art License 1.3,Free Art License,"Theatrical actions are not necessary to the performance, Avoid if at all possible",,
|
||||||
@ -52,3 +52,4 @@ Id,Publication,Author,Year,Custodian,Fields,Type,Publishers,License,LicenseShort
|
|||||||
60,Networks of one's own #1: Etherbox,"Michael Murtaugh, An Mertens, Roel Roscam Abbing, Femke Snelting",2018,Varia,"Networks, Digital Infrastructures, DIY, DIWO, Executable publication, Experimental Publishing, wireless",Paperback,Constant Verlag,Copyleft,Copyleft,,,
|
60,Networks of one's own #1: Etherbox,"Michael Murtaugh, An Mertens, Roel Roscam Abbing, Femke Snelting",2018,Varia,"Networks, Digital Infrastructures, DIY, DIWO, Executable publication, Experimental Publishing, wireless",Paperback,Constant Verlag,Copyleft,Copyleft,,,
|
||||||
61,Mots de la cage aux ours - woorden uit de berenkuil,Constant,2012,Varia,"words, language, Bruxelles",Softcover,Constant,Copyleft,Copyleft,,,
|
61,Mots de la cage aux ours - woorden uit de berenkuil,Constant,2012,Varia,"words, language, Bruxelles",Softcover,Constant,Copyleft,Copyleft,,,
|
||||||
62,Snake rituals and switching circuits,Florian Cramer,2009,Danny,"mass communication, personal communication, new media",paperback,Piet Zwart Institute,Creative Commons Attribution-Share Alike 3.0,Creative Commons,The function of a medium is ultimately decided by its users and not by its creators,,
|
62,Snake rituals and switching circuits,Florian Cramer,2009,Danny,"mass communication, personal communication, new media",paperback,Piet Zwart Institute,Creative Commons Attribution-Share Alike 3.0,Creative Commons,The function of a medium is ultimately decided by its users and not by its creators,,
|
||||||
|
63,Magium issue 1: On Eating in isolation,Alice Strete,2020,Varia,"food, sharing, personal stories, consumption",zine,Self Published,Free Art License,Free Art License,,,Danny
|
||||||
|
|
@ -5,6 +5,7 @@ import flask
|
|||||||
from requests import get
|
from requests import get
|
||||||
from icalendar import Calendar
|
from icalendar import Calendar
|
||||||
import datetime
|
import datetime
|
||||||
|
import bcrypt
|
||||||
from flask import (
|
from flask import (
|
||||||
render_template,
|
render_template,
|
||||||
redirect,
|
redirect,
|
||||||
@ -12,6 +13,7 @@ from flask import (
|
|||||||
)
|
)
|
||||||
from rnrfeed.rnrfeeder import getevents, getlatestevent
|
from rnrfeed.rnrfeeder import getevents, getlatestevent
|
||||||
from uploadform import PublicationForm
|
from uploadform import PublicationForm
|
||||||
|
from borrowform import BorrowForm
|
||||||
from csvparser.csvparser import (
|
from csvparser.csvparser import (
|
||||||
getlicenses,
|
getlicenses,
|
||||||
getpublications,
|
getpublications,
|
||||||
@ -19,6 +21,7 @@ from csvparser.csvparser import (
|
|||||||
getyears,
|
getyears,
|
||||||
getfullpublication,
|
getfullpublication,
|
||||||
writepublication,
|
writepublication,
|
||||||
|
editborrowedby,
|
||||||
)
|
)
|
||||||
from flask_wtf.csrf import CSRFProtect
|
from flask_wtf.csrf import CSRFProtect
|
||||||
|
|
||||||
@ -50,7 +53,8 @@ def index():
|
|||||||
def upload():
|
def upload():
|
||||||
uploadform = PublicationForm()
|
uploadform = PublicationForm()
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
if uploadform.validate_on_submit():
|
if (uploadform.validate_on_submit() and
|
||||||
|
checksecret(uploadform.secret.data)):
|
||||||
id = writepublication(uploadform)
|
id = writepublication(uploadform)
|
||||||
return redirect(str(id), code=303)
|
return redirect(str(id), code=303)
|
||||||
else:
|
else:
|
||||||
@ -59,12 +63,29 @@ def upload():
|
|||||||
return render_template("upload.html", uploadform=uploadform)
|
return render_template("upload.html", uploadform=uploadform)
|
||||||
|
|
||||||
|
|
||||||
@APP.route("/<publicationID>")
|
@APP.route("/<publicationID>", methods=["GET", "POST"])
|
||||||
def show_book(publicationID):
|
def show_book(publicationID):
|
||||||
"""route for a publication, still needs to be made"""
|
"""route for a publication, still needs to be made"""
|
||||||
fullpublication = getfullpublication(publicationID)
|
fullpublication = getfullpublication(publicationID)
|
||||||
# parse csv, render template with full list.
|
borrowform = BorrowForm()
|
||||||
return render_template("publication.html", fullpublication=fullpublication)
|
if request.method == 'POST':
|
||||||
|
if (borrowform.validate_on_submit() and
|
||||||
|
checksecret(borrowform.secret.data)):
|
||||||
|
editborrowedby(publicationID, borrowform.borrowed.data)
|
||||||
|
fullpublication["Borrowed"] = borrowform.borrowed.data
|
||||||
|
return render_template(
|
||||||
|
"publication.html",
|
||||||
|
fullpublication=fullpublication,
|
||||||
|
publicationID=publicationID,
|
||||||
|
borrowform=borrowform
|
||||||
|
)
|
||||||
|
# return a full publication with or without form errors
|
||||||
|
return render_template(
|
||||||
|
"publication.html",
|
||||||
|
fullpublication=fullpublication,
|
||||||
|
publicationID=publicationID,
|
||||||
|
borrowform=borrowform
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@APP.route("/pastevents")
|
@APP.route("/pastevents")
|
||||||
@ -100,6 +121,15 @@ def upcoming_or_latest():
|
|||||||
return dict(upcoming=upcoming)
|
return dict(upcoming=upcoming)
|
||||||
|
|
||||||
|
|
||||||
|
def checksecret(secret):
|
||||||
|
with open("secret") as f:
|
||||||
|
secrethash = f.readline().rstrip()
|
||||||
|
if bcrypt.checkpw(secret.encode("utf-8"), secrethash.encode("utf-8")):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
APP.debug = True
|
APP.debug = True
|
||||||
APP.run(port=5000)
|
APP.run(port=5000)
|
||||||
|
1
library/secret
Normal file
1
library/secret
Normal file
@ -0,0 +1 @@
|
|||||||
|
$2b$12$kZC/e1smAiBCntQxLUpsZ.H0Y5VkWG/YLt18wIdGmONtijkXYaVsO
|
@ -69,6 +69,7 @@ body:after {
|
|||||||
|
|
||||||
#bookshelf > div > a {
|
#bookshelf > div > a {
|
||||||
color: black;
|
color: black;
|
||||||
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#publication {
|
#publication {
|
||||||
@ -87,7 +88,7 @@ body:after {
|
|||||||
|
|
||||||
.event {
|
.event {
|
||||||
margin: 0 1em 1em;
|
margin: 0 1em 1em;
|
||||||
max-width: 90%;
|
max-width: calc(90% - 3em);
|
||||||
margin-top: 3em;
|
margin-top: 3em;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
.uploadform-field {
|
.uploadform-field {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 1em;
|
padding: 1em 0em 1em 0em;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=text], select {
|
input[type=text], select {
|
||||||
@ -25,7 +25,6 @@ input[type=text], select {
|
|||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 4px;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,12 +33,16 @@ input[type=submit] {
|
|||||||
text-align: right;
|
text-align: right;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 1em 3em;
|
padding: 1em 3em;
|
||||||
margin: 1em 1em;
|
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 4px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=submit]:hover {
|
input[type=submit]:hover {
|
||||||
background-color: #404d81;
|
background-color: #404d81;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fieldset{
|
||||||
|
border:0 none;
|
||||||
|
padding-top: 0em;
|
||||||
|
padding-left: 0em;
|
||||||
|
}
|
||||||
|
@ -47,8 +47,30 @@
|
|||||||
<td><p>{{ fullpublication["Comments"] }}</p></td>
|
<td><p>{{ fullpublication["Comments"] }}</p></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Currently borrowed by</td>
|
<td>Currently borrowed by:</td>
|
||||||
<td>No one</td>
|
<td><p>{{ fullpublication["Borrowed"] }}</p></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<form class="borrow" method="POST" action="/{{ publicationID }}">
|
||||||
|
{{ borrowform.csrf_token }}
|
||||||
|
<fieldset class="borrowform-field">
|
||||||
|
{{ borrowform.borrowed.label }}
|
||||||
|
{{ borrowform.borrowed }}
|
||||||
|
{% for message in borrowform.borrowed.errors %}
|
||||||
|
<div class="error">{{ message }}</div>
|
||||||
|
{% endfor %}
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="borrowform-field">
|
||||||
|
{{ borrowform.secret.label }}
|
||||||
|
{{ borrowform.secret }}
|
||||||
|
{% for message in borrowform.secret.errors %}
|
||||||
|
<div class="error">{{ message }}</div>
|
||||||
|
{% endfor %}
|
||||||
|
</fieldset>
|
||||||
|
{{ borrowform.submit }}
|
||||||
|
<form>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -89,6 +89,14 @@
|
|||||||
{{ uploadform.borrowed }}
|
{{ uploadform.borrowed }}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset class="borrowform-field">
|
||||||
|
{{ uploadform.secret.label }}
|
||||||
|
{{ uploadform.secret }}
|
||||||
|
{% for message in uploadform.secret.errors %}
|
||||||
|
<div class="error">{{ message }}</div>
|
||||||
|
{% endfor %}
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
{{ uploadform.submit }}
|
{{ uploadform.submit }}
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
@ -77,4 +77,13 @@ class PublicationForm(FlaskForm):
|
|||||||
highlights = TextField("Highlights from the publication:")
|
highlights = TextField("Highlights from the publication:")
|
||||||
comments = TextField("Comments on the publication:")
|
comments = TextField("Comments on the publication:")
|
||||||
borrowed = StringField("Currently borrowed by:")
|
borrowed = StringField("Currently borrowed by:")
|
||||||
|
secret = StringField(
|
||||||
|
"Librarians secret:",
|
||||||
|
[
|
||||||
|
validators.InputRequired(),
|
||||||
|
Length(
|
||||||
|
min=2, message="Fill in the secret to unlock to library."
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
submit = SubmitField("Submit")
|
submit = SubmitField("Submit")
|
||||||
|
@ -3,3 +3,4 @@ feedparser
|
|||||||
flask
|
flask
|
||||||
flask_wtf
|
flask_wtf
|
||||||
requests
|
requests
|
||||||
|
bcrypt
|
||||||
|
Loading…
Reference in New Issue
Block a user