and i think that's it, we now support user accounts (lite)git commit -m 'and i think that\'s it, we now support user accounts litegit status sweet.'! sweet.
This commit is contained in:
parent
54157c6e9c
commit
c5b5c7833c
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@
|
|||||||
__pycache__
|
__pycache__
|
||||||
data
|
data
|
||||||
*.ipynb
|
*.ipynb
|
||||||
|
secret_key.txt
|
||||||
|
|||||||
38
serve.py
38
serve.py
@ -7,8 +7,8 @@ ideas:
|
|||||||
- special single-image search just for paper similarity
|
- special single-image search just for paper similarity
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
import time
|
import time
|
||||||
import pickle
|
|
||||||
from random import shuffle
|
from random import shuffle
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -17,6 +17,7 @@ from sklearn import svm
|
|||||||
from flask import Flask, request, redirect, url_for
|
from flask import Flask, request, redirect, url_for
|
||||||
from flask import render_template
|
from flask import render_template
|
||||||
from flask import g # global session-level object
|
from flask import g # global session-level object
|
||||||
|
from flask import session
|
||||||
|
|
||||||
from aslite.db import get_papers_db, get_metas_db, get_tags_db
|
from aslite.db import get_papers_db, get_metas_db, get_tags_db
|
||||||
from aslite.db import load_features
|
from aslite.db import load_features
|
||||||
@ -24,9 +25,20 @@ from aslite.db import load_features
|
|||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# inits and globals
|
# inits and globals
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
RET_NUM = 100 # number of papers to return per page
|
RET_NUM = 100 # number of papers to return per page
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# set the secret key so we can cryptographically sign cookies and maintain sessions
|
||||||
|
if os.path.isfile('secret_key.txt'):
|
||||||
|
# example of generating a good key on your system is:
|
||||||
|
# import secrets; secrets.token_urlsafe(16)
|
||||||
|
sk = open('secret_key.txt').read().strip()
|
||||||
|
else:
|
||||||
|
print("WARNING: no secret key found, using default devkey")
|
||||||
|
sk = 'devkey'
|
||||||
|
app.secret_key = sk
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# globals that manage the (lazy) loading of various state for a request
|
# globals that manage the (lazy) loading of various state for a request
|
||||||
|
|
||||||
@ -51,8 +63,7 @@ def get_metas():
|
|||||||
|
|
||||||
@app.before_request
|
@app.before_request
|
||||||
def before_request():
|
def before_request():
|
||||||
g.user = 'root' # current default user, as we have no accounts db at this time just yet
|
g.user = session.get('user', None)
|
||||||
#g.user = None # if noone is logged in, will be the default state shortly
|
|
||||||
|
|
||||||
@app.teardown_request
|
@app.teardown_request
|
||||||
def close_connection(error=None):
|
def close_connection(error=None):
|
||||||
@ -355,3 +366,22 @@ def delete_tag(tag=None):
|
|||||||
|
|
||||||
print("deleted tag %s for user %s" % (tag, g.user))
|
print("deleted tag %s for user %s" % (tag, g.user))
|
||||||
return "ok: " + str(d) # return back the user library for debugging atm
|
return "ok: " + str(d) # return back the user library for debugging atm
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# endpoints to log in and out
|
||||||
|
|
||||||
|
@app.route('/login', methods=['POST'])
|
||||||
|
def login():
|
||||||
|
|
||||||
|
# the user is logged out but wants to log in, ok
|
||||||
|
if g.user is None and request.form['username']:
|
||||||
|
username = request.form['username']
|
||||||
|
if len(username) > 0: # one more paranoid check
|
||||||
|
session['user'] = username
|
||||||
|
|
||||||
|
return redirect(url_for('profile'))
|
||||||
|
|
||||||
|
@app.route('/logout')
|
||||||
|
def logout():
|
||||||
|
session.pop('user', None)
|
||||||
|
return redirect(url_for('profile'))
|
||||||
|
|||||||
@ -180,4 +180,47 @@ body {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
top: 10px;
|
top: 10px;
|
||||||
|
}
|
||||||
|
#profile-warning {
|
||||||
|
margin: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 16px;
|
||||||
|
background-color: #fdd;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
#profile-warning p {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
#profile-login-form {
|
||||||
|
width: 400px;
|
||||||
|
margin: 30px auto;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
#profile-login-form .form-control {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 5px 0 10px 0;
|
||||||
|
padding: 5px;
|
||||||
|
height: 34px;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.42857143;
|
||||||
|
color: #555;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
#profile-login-form .btn {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 0;
|
||||||
|
height: 34px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.42857143;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #337ab7;
|
||||||
|
border: 1px solid #2e6da4;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ var gvars = {{ gvars | tojson }};
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if user %}
|
{% if user and tags %}
|
||||||
<div id="tagwrap">
|
<div id="tagwrap">
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@ -5,7 +5,39 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="wrap">
|
<div id="wrap">
|
||||||
This is where the user gets to log in, or see information about their account if logged in.
|
|
||||||
|
{% if user %}
|
||||||
|
<div>
|
||||||
|
<div>Logged in user: {{ user }}</div>
|
||||||
|
<div>
|
||||||
|
<a href="{{ url_for('logout') }}">Log out</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div>
|
||||||
|
|
||||||
|
<div id="profile-warning">
|
||||||
|
<p>
|
||||||
|
Okay, arxiv-sanity-lite uses a super lite version of
|
||||||
|
"user accounts" where there are no passwords. Basically, you can "log in"
|
||||||
|
with any arbitrary username. If you want to share your library with a
|
||||||
|
friend, you can just tell them the username. And if you'd like to keep your
|
||||||
|
account private, just make your username be something unique
|
||||||
|
and write it down somewhere safe.
|
||||||
|
</p>
|
||||||
|
<b>TLDR: there are no passwords!</b>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form id="profile-login-form" action="/login" method="POST">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Username:</label>
|
||||||
|
<input class="form-control" type="text" name="username">
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Log in</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user