Newer
Older
"error": True,
"message": "Assertion failed. Error: {}".format( e )
app.logger.debug( "Update key usage in the database" )
dt = datetime.now( pytz.timezone( "Europe/Zurich" ) )
q = config.db.query( "UPDATE webauthn SET sign_count = %s, last_usage = %s, usage_counter = usage_counter + 1 WHERE credential_id = %s", ( sign_count, dt, credential_id, ) )
config.db.commit()
session[ "need_to_check" ].remove( "securitykey" )
do_login()
return jsonify( {
################################################################################
# New user
"""
Serve the page to register to ICNML.
"""
app.logger.info( "New user registration page open" )
q = config.db.query( "SELECT id, name FROM account_type WHERE can_singin = true" )
r = q.fetchall()
account_type = []
for rr in r:
account_type.append( dict( rr ) )
list_account_type = account_type
@app.route( baseurl + "/do/signin", methods = [ "POST" ] )
def add_account_request_to_db():
"""
Add the new user request to the database.
"""
app.logger.info( "Registrer new user request to the database" )
first_name = request.form[ "first_name" ]
last_name = request.form[ "last_name" ]
email = request.form[ "email" ]
account_type = int( request.form[ "account_type" ] )
app.logger.debug( "First name: {}".format( first_name ) )
app.logger.debug( "Last name: {}".format( last_name ) )
app.logger.debug( "Email: {}".format( email ) )
app.logger.debug( "Account: {}".format( account_type ) )
sql = "SELECT name FROM account_type WHERE id = %s"
account_type_name = config.db.query_fetchone( sql, ( account_type, ) )[ "name" ]
account_type_name = account_type_name.lower()
sql = "SELECT nextval( 'username_{}_seq' ) as id".format( account_type_name )
username_id = config.db.query_fetchone( sql )[ "id" ]
app.logger.debug( "Username id:{}".format( username_id ) )
utils.sql.sql_insert_generate( "signin_requests", [ "first_name", "last_name", "email", "account_type", "uuid", "username_id" ] ),
( first_name, last_name, email, account_type, uuid, username_id, )
)
config.db.commit()
return jsonify( {
app.logger.error( "New user request database error" )
@app.route( baseurl + "/validate_signin" )
@admin_required
def validate_signin():
"""
Serve the page to admins regarding the validation of new users.
"""
app.logger.info( "Serve the signin valiation page" )
q = config.db.query( """
SELECT signin_requests.*, account_type.name as account_type
FROM signin_requests
LEFT JOIN account_type ON signin_requests.account_type = account_type.id
WHERE signin_requests.status = 'pending'
try:
r = q.fetchall()
for rr in r:
users.append( dict( rr ) )
app.logger.debug( "Add '{}' to the validation list".format( rr[ "email" ] ) )
except:
pass
app.logger.info( "{} users added to the validation list".format( len( users ) ) )
"users/validate_signin.html",
users = users
@app.route( baseurl + "/do/validate_signin", methods = [ "POST" ] )
@admin_required
def do_validate_signin():
"""
Prepare the new user data to be signed by the admin, and serve the page.
"""
request_id = request.form.get( "id" )
app.logger.info( "Signin validation begin for request_id '{}'".format( request_id ) )
q = config.db.query( "SELECT * FROM signin_requests WHERE id = %s", ( request_id, ) )
s = q.fetchone()
s = dict( s )
r = {}
r[ "user" ] = s
r[ "user" ][ "request_time" ] = str( r[ "user" ][ "request_time" ] )
r[ "user" ][ "validation_time" ] = str( r[ "user" ][ "validation_time" ] )
r[ "acceptance" ] = {}
r[ "acceptance" ][ "username" ] = session[ "username" ]
r[ "acceptance" ][ "time" ] = str( datetime.now() )
j = json.dumps( r )
challenge = base64.b64encode( j )
challenge = challenge.replace( "=", "" )
session[ "validation_user_challenge" ] = challenge
############################################################################
q = config.db.query( "SELECT * FROM webauthn WHERE user_id = %s AND usage_counter > 0 ORDER BY last_usage DESC LIMIT 1", ( user_id, ) )
key = q.fetchone()
webauthn_user = webauthn.WebAuthnUser(
key[ "ukey" ], session[ "username" ], session[ "username" ], None,
key[ "credential_id" ], key[ "pub_key" ], key[ "sign_count" ], config.RP_ID
)
webauthn_assertion_options = webauthn.WebAuthnAssertionOptions( webauthn_user, challenge )
return jsonify( {
"error": False,
"data": webauthn_assertion_options.assertion_dict
@app.route( baseurl + "/do/validate_signin_2", methods = [ "POST" ] )
@admin_required
def do_validate_signin_2():
"""
Verification of the signature of the new user data by the admin.
"""
app.logger.info( "Verification of the validated new user" )
challenge = session.get( "validation_user_challenge" )
assertion_response = request.form
assertion_response_s = base64.b64encode( json.dumps( assertion_response ) )
credential_id = assertion_response.get( "id" )
q = config.db.query( "SELECT * FROM webauthn WHERE credential_id = %s", ( credential_id, ) )
user = q.fetchone()
webauthn_user = webauthn.WebAuthnUser(
user[ "ukey" ], session[ "username" ], session[ "username" ], None,
user[ "credential_id" ], user[ "pub_key" ], user[ "sign_count" ], "icnml.unil.ch"
)
webauthn_assertion_response = webauthn.WebAuthnAssertionResponse(
webauthn_user,
assertion_response,
challenge,
config.ORIGIN,
uv_required = False
)
try:
webauthn_assertion_response.verify()
app.logger.info( "Webauthn assertion verified" )
except Exception as e:
return jsonify( {
"error": True,
"message": "Assertion failed. Error: {}".format( e )
} )
############################################################################
if len( challenge ) % 4 != 0:
challenge += "=" * ( 4 - ( len( challenge ) % 4 ) )
newuser = base64.b64decode( challenge )
newuser = json.loads( newuser )
user_type = int( newuser[ "user" ][ "account_type" ] )
email = newuser[ "user" ][ "email" ]
email_hash = utils.hash.pbkdf2( email, utils.rand.random_data( config.EMAIL_SALT_LENGTH ), config.EMAIL_NB_ITERATIONS ).hash()
request_id = newuser[ "user" ][ "id" ]
username_id = newuser[ "user" ][ "username_id" ]
n = config.db.query( "SELECT name FROM account_type WHERE id = %s", ( user_type, ) )
n = n.fetchone()
n = n[ 0 ]
username = "{}_{}".format( n, username_id )
username = username.lower()
app.logger.info( "Creation of the new user '{}'".format( username ) )
config.db.query( "UPDATE signin_requests SET validation_time = now(), assertion_response = %s, status = 'validated' WHERE id = %s", ( assertion_response_s, request_id ) )
config.db.query( utils.sql.sql_insert_generate( "users", [ "username", "email", "type" ] ), ( username, email_hash, user_type ) )
app.logger.debug( "User '{}' created".format( username ) )

Marco De Donno
committed
app.logger.error( "Error while creating the user account for '{}'".format( username ) )
"error": True,
"message": "Can not insert into database."
} )
############################################################################
email_content = utils.template.render_jinja_html(
"templates/email", "signin.html",
username = username,
url = "https://icnml.unil.ch" + url_for( "config_new_user", uuid = newuser[ "user" ][ "uuid" ] )
)
msg = MIMEText( email_content, "html" )
msg[ "Subject" ] = "ICNML - Login information"
msg[ "From" ] = config.sender
msg[ "To" ] = email
app.logger.info( "Sending the email to the user '{}'".format( username ) )
s = smtplib.SMTP( config.smtpserver )
s.starttls()
s.login( config.smtpuser, config.smtppassword )
s.sendmail( config.sender, [ email ], msg.as_string() )
s.quit()
############################################################################
return jsonify( {
@app.route( baseurl + "/do/validation_reject", methods = [ "POST" ] )
"""
Reject the request for a new user.
"""
request_id = request.form.get( "id" )
app.logger.info( "Reject the new user request {}".format( request_id ) )
try:
sql = "UPDATE signin_requests SET status = 'rejected' WHERE id = %s"
config.db.query( sql, ( request_id, ) )
config.db.commit()
return jsonify( {
"error": False
} )
except:
return jsonify( {
"error": True
} )
def config_new_user( uuid ):
"""
Serve the first page to the new user to configure his account.
"""
app.logger.info( "Serve user account configuration page" )
session.clear()
q = config.db.query( "SELECT email FROM signin_requests WHERE uuid = %s", ( uuid, ) )
r = q.fetchone()
try:
email = r[ "email" ]
session[ "signin_user_validation_email" ] = email
session[ "signin_user_validation_uuid" ] = uuid
next_step = "do_config_new_user"
@app.route( baseurl + "/do/config", methods = [ "POST" ] )
"""
Save the configuration of the new user to the database.
"""
app.logger.info( "Start user account configuration" )
email = session[ "signin_user_validation_email" ]
uuid = session[ "signin_user_validation_uuid" ]
username = request.form.get( "username" )
password = request.form.get( "password" )
############################################################################
q = config.db.query( "SELECT count(*) FROM signin_requests WHERE uuid = %s AND email = %s", ( uuid, email, ) )
r = q.fetchone()
r = r[ 0 ]
if r == 0:
return jsonify( {
"error": True,
"message": "no signin request"
} )
q = config.db.query( "SELECT * FROM users WHERE username = %s", ( username, ) )
user = q.fetchone()
if user == None:
app.logger.error( "No user found in the databse for '{}'".format( username ) )
} )
elif not password.startswith( "pbkdf2" ):
app.logger.error( "Password not hashed with PBKDF2" )
"error": True,
"message": "password not in the correct format"
elif not utils.hash.pbkdf2( email, user[ "email" ] ).verify():
app.logger.error( "Email not corresponding to the stored email in the database" )
"error": True,
"message": "email not corresponding to the request form"
elif user.get( "password", None ) != None:
app.logger.error( "Password already set for this user" )
"error": True,
"message": "password already set"
} )
############################################################################
app.logger.debug( "Storing the new password to the databse" )
password = utils.hash.pbkdf2( password, utils.rand.random_data( config.EMAIL_SALT_LENGTH ), config.PASSWORD_NB_ITERATIONS ).hash()
q = config.db.query( "UPDATE users SET password = %s WHERE username = %s", ( password, username, ) )
config.db.commit()
############################################################################
return jsonify( {
@app.route( baseurl + "/config/donor/<h>" )
def config_new_user_donor( h ):
"""
Serve the configuration page for a new donor.
"""
app.logger.info( "Start new donor configuration" )
session.clear()
app.logger.debug( "Searching in the database for hash value '{}'".format( h ) )
sql = """
SELECT users.id, users.username, users.email
FROM users
LEFT JOIN account_type ON users.type = account_type.id
WHERE account_type.name = 'Donor' AND password IS NULL
"""
for r in config.db.query_fetchall( sql ):
if h == hashlib.sha512( r[ "email" ] ).hexdigest():
app.logger.info( "User '{}' found".format( r[ "username" ] ) )
user = r
break
else:
app.logger.error( "The hash '{}' is not present in the users database".format( h ) )
return redirect( url_for( "home" ) )
session[ "email_hash" ] = h
session[ "user_id" ] = user[ "id" ]
app.logger.info( "Serving the config new donor page" )
"users/config.html",
next_step = "do_config_new_donor",
hash = h
)
@app.route( baseurl + "/do/config/donor", methods = [ "POST" ] )
def do_config_new_donor():
"""
Save the donor configuration to the database.
"""
app.logger.info( "Start donor configuration" )
username = request.form.get( "username" )
app.logger.debug( "Username: {}".format( username ) )
password = request.form.get( "password" )
password = utils.hash.pbkdf2( password, utils.rand.random_data( config.PASSWORD_SALT_LENGTH ), config.PASSWORD_NB_ITERATIONS ).hash()
h = request.form.get( "hash" )
sql = "SELECT id FROM users WHERE username = %s"
user_id = config.db.query_fetchone( sql, ( username, ) )[ "id" ]
if session[ "email_hash" ] == h and session[ "user_id" ] == user_id:
config.db.query( "UPDATE users SET password = %s WHERE username = %s", ( password, username, ) )
config.db.commit()
app.logger.info( "Password set" )
return jsonify( {
"error": False
} )
else:
app.logger.error( "Error while updating the password dor {}".format( username ) )
return jsonify( {
"error": True,
"message": "Invalid parameters"
} )
"""
Serve the help page for the TOTP.
"""
app.logger.info( "Serving the TOTP help page" )
return my_render_template( "totp_help.html" )
################################################################################
# QR Code generation
def renew_secret():
"""
Request a new TOTP secret.
"""
app.logger.info( "Generate new secret" )
return secret
def get_secret():
"""
Retrieve the current secret.
"""
app.logger.info( "Request secret for user '{}'".format( session[ "username" ] ) )
secret = session.get( "secret", None )
if secret == None:
secret = renew_secret()
return secret
"""
Set the new secret value for the TOTP in the database.
"""
app.logger.info( "Storing new secret for user '{}'".format( session[ "username" ] ) )
config.db.query( "UPDATE users SET totp = %s WHERE username = %s", ( session[ "secret" ], session[ "username" ], ) )
config.db.commit()
return jsonify( {
"""
Serve the current secret as JSON.
"""
app.logger.info( "Request the secret for user '{}'".format( session[ "username" ] ) )
get_secret()
return jsonify( {
"error": False,
"secret": session[ "secret" ]
@login_required
def request_renew_secret():
"""
Serve current secret.
"""
app.logger.info( "Renew TOTP secret for user '{}'".format( session[ "username" ] ) )
renew_secret()
return jsonify( {
"error": False,
"secret": session[ "secret" ]
@app.route( baseurl + "/user/config/totp_qrcode.png" )
Generate the TOTP PNG QRcode image ready to scan.
app.logger.info( "Generate the TOTP QRcode" )
qrcode_value = "otpauth://totp/ICNML%20{}?secret={}".format( session[ "username" ], get_secret() )
qrcode_value = "otpauth://totp/ICNML?secret={}".format( get_secret() )
app.logger.debug( "Value: {}".format( qrcode_value ) )
img = qrcode.make( qrcode_value )
temp = StringIO()
img.save( temp, format = "png" )
temp.seek( 0 )
return send_file( temp, mimetype = "image/png" )
@app.route( baseurl + "/user/config/totp" )
@login_required
app.logger.info( "Serve the TOTP config page" )
"users/totp.html",
secret = get_secret()
################################################################################
# DEK encryption/decryption
@app.route( baseurl + "/dek/reconstruct", methods = [ "POST" ] )
@login_required
def dek_regenerate():
app.logger.info( "DEK reconstruction" )
try:
email_hash = request.form.get( "email_hash" )
username = session.get( "username" )
app.logger.debug( "User: {}".format( username ) )
sql = "SELECT * FROM donor_dek WHERE donor_name = %s"
user = config.db.query_fetchone( sql, ( username, ) )
if user[ "salt" ] == None:
app.logger.error( "No DEK salt for user '{}'".format( session[ "username" ] ) )
raise
_, dek, _ = dek_generate( username = username, email_hash = email_hash, salt = user[ "salt" ] )
app.logger.debug( "DEK reconstructed: {}...".format( dek[ 0:10 ] ) )
check = utils.aes.do_decrypt( user[ "dek_check" ], dek )
check = json.loads( check )
if check[ "value" ] != "ok":
app.logger.error( "DEK check error for user '{}'".format( session[ "username" ] ) )
app.logger.debug( "DEK check OK" )
sql = "UPDATE donor_dek SET dek = %s WHERE id = %s AND donor_name = %s"
config.db.query( sql, ( dek, user[ "id" ], username, ) )
config.db.commit()
app.logger.info( "Reconstructed DEK saved to the database" )
return jsonify( {
"error": False
} )
return jsonify( {
"error": True
} )
@app.route( baseurl + "/dek/delete" )
@login_required
def dek_delete():
try:
username = session.get( "username" )
app.logger.info( "Delete DEK for user {}".format( username ) )
sql = "UPDATE donor_dek SET dek = NULL WHERE donor_name = %s"
config.db.query( sql, ( username, ) )
config.db.commit()
return jsonify( {
"error": False
} )
except:
return jsonify( {
"error": True
} )
@app.route( baseurl + "/dek/fulldelete" )
@login_required
def dek_delete_fully():
try:
username = session.get( "username" )
app.logger.info( "Fully delete the DEK of user {}".format( username ) )
sql = "UPDATE donor_dek SET dek = NULL WHERE donor_name = %s"
config.db.query( sql, ( username, ) )
sql = "UPDATE donor_dek SET salt = NULL WHERE donor_name = %s"
config.db.query( sql, ( username, ) )
sql = "UPDATE donor_dek SET dek_check = NULL WHERE donor_name = %s"
config.db.query( sql, ( username, ) )
config.db.commit()
return jsonify( {
"error": False
} )
except:
return jsonify( {
"error": True
################################################################################
# File upload
@app.route( baseurl + "/upload", methods = [ "POST" ] )
@login_required
def upload_file():
Main function dealing with the upload of files (tenprint, mark and consent forms).
This function accept traditionals images and NIST files for the fingerprint data,
and PDFs for the consent forms.
"""
app.logger.info( "Processing of the uploaded file" )
upload_type = request.form.get( "upload_type", None )
app.logger.debug( "Upload type: {}".format( upload_type ) )
file_extension = request.form.get( "extension", None )
if isinstance( file_extension, str ):
file_extension = file_extension.lower()
app.logger.debug( "File extension: {}".format( file_extension ) )
if upload_type == None:
"message": "Must specify a file type to upload a file"
if "file" not in request.files:
app.logger.error( "No file in the upload request" )
return jsonify( {
"error": True,
"message": "No file in the POST request"
} )
elif "submission_id" not in request.form:
app.logger.error( "No submission identification number" )
return jsonify( {
"error": True,
"message": "No submission_id"
} )
else:
try:
submission_uuid = request.form.get( "submission_id" )
sql = "SELECT id FROM submissions WHERE uuid = %s"
r = config.db.query( sql, ( submission_uuid, ) )
submission_id = r.fetchone()[ "id" ]
app.logger.debug( "Submission UUID: {}".format( submission_uuid ) )
except:
return jsonify( {
"error": True,
"message": "upload not related to a submission form"
uploaded_file = request.files[ "file" ]
file_name = do_encrypt_user_session( uploaded_file.filename )
file_uuid = str( uuid4() )
app.logger.debug( "File uuid: {}".format( file_uuid ) )
fp = StringIO()
uploaded_file.save( fp )
file_size = fp.tell()
app.logger.debug( "File size: {}".format( file_size ) )
fp.seek( 0 )
if file_extension in config.NIST_file_extensions:
file_data = fp.getvalue()
file_data = base64.b64encode( file_data )
file_data = do_encrypt_dek( file_data, submission_uuid )
n = NISTf_auto( fp )
if not n.is_initialized():
raise
app.logger.info( "NIST file loaded correctly" )
app.logger.debug( "Records: " + ", ".join( [ "Type-%02d" % x for x in n.get_ntype() ] ) )
app.logger.error( "Error while loading the NIST file" )
"message": "Error while loading the NIST file"
# Save the NIST file in the DB
app.logger.info( "Saving the NIST file to the database" )
sql = utils.sql.sql_insert_generate( "files", [ "folder", "creator", "filename", "type", "format", "size", "uuid", "data" ] )
data = ( submission_id, session[ "user_id" ], file_name, 5, "NIST", file_size, file_uuid, file_data, )
config.db.query( sql, data )
# Segmentation of the NIST file
app.logger.info( "Segmenting the NIST file" )
fpc_in_file = []
for fpc in config.all_fpc:
app.logger.debug( "FPC {}".format( fpc ) )
try:
img = n.get_print( fpc = fpc )
except:
img = n.get_palmar( fpc = fpc )
buff = StringIO()
img.save( buff, format = "TIFF" )
app.logger.debug( str( img ) )
buff.seek( 0 )
img_data = buff.getvalue()
img_data = base64.b64encode( img_data )
img_data = do_encrypt_dek( img_data, submission_uuid )
sql = utils.sql.sql_insert_generate( "files_segments", [ "tenprint", "uuid", "pc", "data" ] )
data = ( file_uuid, str( uuid4() ), fpc, img_data, )
config.db.query( sql, data )
app.logger.info( "Image saved to the database" )
fpc_in_file.append( fpc )
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
app.logger.debug( " No data" )
pass
app.logger.info( "FPC processed ({}): {}".format( len( fpc_in_file ), fpc_in_file ) )
config.db.commit()
return jsonify( {
"error": False,
"fpc": fpc_in_file
} )
else:
if upload_type in [ "mark_target", "mark_incidental", "tenprint_card_front", "tenprint_card_back" ]:
app.logger.info( "Image file type: {}".format( upload_type ) )
img = Image.open( fp )
img_format = img.format
width, height = img.size
app.logger.debug( str( img ) )
try:
res = int( img.info[ "dpi" ][ 0 ] )
app.logger.debug( "Resolution: {}".format( res ) )
except:
app.logger.error( "No resolution found in the image" )
return jsonify( {
"error": True,
"message": "No resolution found in the image. Upload not possible at the moment."
} )

Marco De Donno
committed
try:
img = utils.images.rotate_image_upon_exif( img )
app.logger.debug( "Rotation of the image" )
except:
pass
buff = StringIO()
img.save( buff, format = img_format )
buff.seek( 0 )
file_data = buff.getvalue()
if upload_type in [ "tenprint_card_front", "tenprint_card_back" ]:
app.logger.debug( "Creation of the thumbnail" )
create_thumbnail( file_uuid, img, submission_uuid )
else:
file_data = fp.getvalue()
file_data_r = file_data
file_data = base64.b64encode( file_data )
sql = "SELECT id FROM files_type WHERE name = %s"
upload_type_id = config.db.query( sql, ( upload_type, ) ).fetchone()[ 0 ]
####################################################################
if upload_type == "consent_form":
app.logger.info( "Processing of the consent form" )
sql = "SELECT email_aes FROM submissions WHERE uuid = %s"
email = config.db.query_fetchone( sql, ( submission_uuid, ) )[ "email_aes" ]
email = do_decrypt_user_session( email )
sql = """
SELECT users.username, users.email
FROM users
LEFT JOIN account_type ON users.type = account_type.id
WHERE account_type.name = 'Donor'
ORDER BY users.id DESC
"""
for username_db, email_db in config.db.query_fetchall( sql ):
if utils.hash.pbkdf2( email, email_db ).verify():
username = username_db
url_hash = hashlib.sha512( email_db ).hexdigest()
app.logger.info( "Donor: {}".format( username ) )
break
app.logger.error( "User not found" )
return jsonify( {
"error": True,
"message": "user not found"
} )
# Email for the donor
app.logger.info( "Sending the email to the donor" )
email_content = utils.template.render_jinja_html(
"templates/email", "donor.html",
username = username,
url = "https://icnml.unil.ch" + url_for( "config_new_user_donor", h = url_hash )
)
msg = MIMEMultipart()
msg[ "Subject" ] = "ICNML - You have been added as donor"
msg[ "From" ] = config.sender
msg[ "To" ] = email
msg.attach( MIMEText( email_content, "html" ) )
part = MIMEApplication( file_data_r, Name = "consent_form.pdf" )
part[ "Content-Disposition" ] = "attachment; filename=consent_form.pdf"
msg.attach( part )
try:
s = smtplib.SMTP( config.smtpserver )
s.starttls()
s.login( config.smtpuser, config.smtppassword )
s.sendmail( config.sender, [ email ], msg.as_string() )
s.quit()
app.logger.info( "Email sended" )
except:
app.logger.error( "Can not send the email to the donor" )
return jsonify( {
"error": True,
"message": "Can not send the email to the user"
} )
# Consent form save
app.logger.info( "Saving the consent form to the database" )
file_data = base64.b64encode( file_data )
file_data = gpg.encrypt( file_data, *config.gpg_key )
file_data = str( file_data )
file_data = base64.b64encode( file_data )
sql = utils.sql.sql_insert_generate( "cf", [ "uuid", "data", "email" ] )
data = ( file_uuid, file_data, utils.hash.pbkdf2( email, iterations = config.CF_NB_ITERATIONS ).hash(), )
config.db.query( sql , data )
sql = "UPDATE submissions SET consent_form = true WHERE uuid = %s"
config.db.query( sql, ( submission_uuid, ) )
config.db.commit()
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
else:
app.logger.info( "Save the file to the databse" )
file_data = do_encrypt_dek( file_data, submission_uuid )
sql = utils.sql.sql_insert_generate( "files", [
"folder", "creator",
"filename", "type",
"format", "size", "width", "height", "resolution",
"uuid", "data"
] )
data = (
submission_id, session[ "user_id" ],
file_name, upload_type_id,
img_format, file_size, width, height, res,
file_uuid, file_data,
)
config.db.query( sql, data )
config.db.commit()
return jsonify( {
"error": False,
"uuid": file_uuid
} )
################################################################################
@app.route( baseurl + "/submission/new" )
@submission_has_access
"""
Serve the page to start a new submission (new donor).
"""
app.logger.info( "Serve the new donor form" )
return my_render_template( "submission/new.html" )
@app.route( baseurl + "/submission/do_new", methods = [ "POST" ] )
@submission_has_access
"""
Check the new donor data, and store the new submission process in the database.
"""
app.logger.info( "Process the new donor form" )
email = request.form.get( "email", False )
# Check for duplicate base upon the email data
sql = "SELECT id, email_hash FROM submissions WHERE submitter_id = %s"
r = config.db.query( sql, ( session[ "user_id" ], ) )