
рдХреБрдЫ рд▓реЛрдЧреЛрдВ рдХреЛ рдЫреЛрдЯреЗ рд╕рдВрджреЗрд╢ рджреЗрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рдХреИрд╕реЗ рдХрд░реЗрдВ рдпрджрд┐ рдЖрдк рд╡рд┐рднрд┐рдиреНрди рд╕рд╛рдорд╛рдЬрд┐рдХ рдиреЗрдЯрд╡рд░реНрдХ рдФрд░ рддреНрд╡рд░рд┐рдд рджреВрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдбреЗрдЯрд╛ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХреА рд╕реБрд░рдХреНрд╖рд╛ рдореЗрдВ рдЬрд┐рд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрдкрдХреЛ рд╕рдВрджреЗрд╣ рд╣реИред
рдХреБрдЫ рд▓реЛрдЧ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╕реЗрд▓реНрдл-рдбрд┐рд╕реНрдЯреНрд░рдХреНрдЯрд┐рдВрдЧ рдПрдирдХреНрд░рд┐рдкреНрдЯреЗрдб рдиреЛрдЯреНрд╕ рдХреА рд╕реЗрд╡рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдпрд╣ рд╕рд╡рд╛рд▓ рдЙрдарддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЗрди рд╕реЗрд╡рд╛рдУрдВ рдкрд░ рднрд░реЛрд╕рд╛ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдХреНрдпрд╛ рд╡рд╛рдХрдИ рдЗрдиреНрд╣реЗрдВ рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж рдиреЛрдЯ рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред
Python cryptography Flask Heroku.
github
Heroku
Virtualenv.
virtualenv
pip install virtualenv
mkdir encnotes
cd encnotes
virtualenv venv
source venv/bin/activate ( nix )
venv\Scripts\activate ( Windows )
requirements.txt :
cryptography
Flask
Flask-Migrate
Flask-SQLAlchemy
Flask-WTF
Flask-Bootstrap
Flask-SSLify
pip , requirements.txt
pip install -r requirements.txt
encnotes.py. . . .
import os
import random
from cryptography.fernet import Fernet
from flask import Flask, render_template, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_wtf import FlaskForm
from flask_bootstrap import Bootstrap
from flask_sslify import SSLify
from wtforms import TextAreaField, SubmitField
from wtforms.validators import DataRequired, Length
,
class Config():
SECRET_KEY = os.environ.get('SECRET_KEY')
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')
SITE_URL = 'https://encnote.herokuapp.com'
SECRET_KEY тАФ . , , . Flask-WTF Cross-Site Request Forgery CSRF.
SQLALCHEMY_TRACK_MODIFICATIONS тАФ ,
, .
SITE_URL тАФ , Heroku.
Flask Config
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
bootstrap = Bootstrap(app)
sslify = SSLify(app)
, . 3 :
- id тАФ ,
- number тАФ , .
1000000 9999999 - ciptext тАФ
.
class Note(db.Model):
__tablename__ = 'notes'
id = db.Column(db.Integer, primary_key=True)
number = db.Column(db.Integer, unique=True, nullable=False)
ciptext = db.Column(db.Text, nullable=False)
def __repr__(self):
return f'<Note number: {self.number}'
- , Flask-WTF
class TextForm(FlaskForm):
text = TextAreaField(' ( 1000 )',
validators=[DataRequired(), Length(1, 1000)])
submit = SubmitField('')
- text тАФ . 2 . , . 1000 . .
. .
@app.shell_context_processor
def make_shell_context():
return {'db': db, 'Note': Note}
@app.route('/', methods=['GET', 'POST'])
def index():
form = TextForm()
if form.validate_on_submit():
key = Fernet.generate_key()
str_key = key.decode('ascii')
f = Fernet(key)
bin_string = form.text.data.encode('utf-8')
cipher_text = f.encrypt(bin_string)
str_cipher_text = cipher_text.decode('ascii')
rnumber = random.randint(1000000, 9999999)
while True:
n = Note.query.filter_by(number=rnumber).first()
if n:
rnumber = random.randint(1000000, 9999999)
continue
break
cipher_note = Note(number=rnumber, ciptext=str_cipher_text)
link = f'{app.config["SITE_URL"]}/{rnumber}/{str_key}'
db.session.add(cipher_note)
db.session.commit()
return render_template('complete.html', link=link)
return render_template('index.html', form=form)
, . POST, "". . URL-safe base64, "Ascii" URL. AES-128.
, URL-safe base64, , . , while , , . , html complete.html - . html Flask-Bootstrap, bootstrap.
, . , , . .. .
@app.route('/<rnumber>/<str_key>')
def question(rnumber, str_key):
link = f'{app.config["SITE_URL"]}/decrypt/{rnumber}/{str_key}'
return render_template('question.html', link=link)
"" ,
@app.route('/decrypt/<int:rnumber>/<str_key>')
def decrypt(rnumber, str_key):
cipher_note = Note.query.filter_by(number=rnumber).first_or_404()
cipher_text = cipher_note.ciptext.encode('ascii')
key = str_key.encode('ascii')
try:
f = Fernet(key)
text = f.decrypt(cipher_text)
except (ValueError, InvalidToken):
return render_template('error.html')
text = text.decode('utf-8')
db.session.delete(cipher_note)
db.session.commit()
return render_template('decrypt.html', text=text)
. try except
.
Heroku
- Heroku. . , 30 , . , .
Heroku Heroku CLI. git
Heroku CLI
$ heroku login
git
$ git init
Heroku. , encnote
heroku apps:create encnote
Creating тмв encnote... done
https://encnote.herokuapp.com/ | https://git.heroku.com/encnote.git
, Heroku
heroku addons:add heroku-postgresql:hobby-dev
Creating heroku-postgresql:hobby-dev on тмв encnote... free
Database has been created and is available
! This database is empty. If upgrading, you can transfer
! data from another database with pg:copy
Created postgresql-graceful-12123 as DATABASE_URL
Use heroku addons:docs heroku-postgresql to view documentation
Heroku DATABASE_URL
, . , , Flask
nix export FLASK_APP=encnotes.py
Windows set FLASK_APP=encnotes.py
,
$ export DATABASE_URL=sqlite:////home/user/Python/encnote/app.db ( nix )
$ set DATABASE_URL=sqlite:///D:\Python\encnotes\app.db ( Windows )
flask db init
flask db migrate
migrate, . app.db .
.gitignore , git Heroku
venv
__pycache__
- flask , gunicorn. Postgres psycopg2. http https, Flask-SSLify.
requirements.txt
gunicorn
psycopg2
Heroku , Procfile . :
web: flask db upgrade; gunicorn encnotes:app
Heroku. , .
, . SECRET_KEY .
heroku config:set SECRET_KEY=super-secret-work232
heroku config:set FLASK_APP=encnotes.py
DATABASE_URL Heroku,
heroku addons:add heroku-postgresql:hobby-dev
рдЕрдм рд╣рдо рд╕рднреА рддреИрдирд╛рддреА рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВред рд╣рдорд╛рд░реЗ рдлрд╛рдЗрд▓ рдХреЛ git рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ, рдХрдорд┐рдЯ рдХрд░реЗрдВ рдФрд░ heroku рдХреЛ рднреЗрдЬреЗрдВ
git add .
git commit -m "Heroku deploy"
git push heroku master
рдпрд╣ рдмрд╛рдд рд╣реИ, рдЖрд╡реЗрджрди рддреИрдпрд╛рд░ рд╣реИ! рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВрдиреЗ рджрд┐рдЦрд╛рдпрд╛ рдХрд┐
рдлреНрд▓рд╛рд╕реНрдХ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЫреЛрдЯреЗ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛рдирд╛ рдХрд┐рддрдирд╛ рдЖрд╕рд╛рди рд╣реИ рдФрд░
рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлреА рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдореЗрдВ рдЖрд╕рд╛рди рдкрд╛рдпрдерди рдореЙрдбреНрдпреВрд▓ рд╣реИ ред