initial commit

This commit is contained in:
Lilah 2022-04-11 21:44:17 -06:00
commit caa37a5021
11 changed files with 201 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

44
app.py Normal file
View File

@ -0,0 +1,44 @@
from flask import Flask, render_template, request, make_response, redirect
from numpy import real
from freecaptcha import captcha
import uuid
app = Flask(__name__, static_url_path='', static_folder='static',)
captcha_solutions = {}
captcha_solved = []
@app.route("/captcha", methods=['GET', 'POST'])
def login():
# This means they just submitted a CAPTCHA
# We need to see if they got it right
incorrect_captcha = False
if request.method == 'POST':
captcha_quess = request.form.get('captcha', None)
captcha_cookie = request.cookies.get('freecaptcha_cookie')
real_answer = captcha_solutions.get(captcha_cookie, None)
if real_answer is not None:
if int(captcha_quess) == int(real_answer):
captcha_solved.append(captcha_cookie)
return redirect("/", code=302)
else:
incorrect_captcha = True
# Select an image
image_path = captcha.random_image()
# Generate list of rotated versions of image
# and save which one is correct
answer, options = captcha.captchafy(image_path)
# Provide the CAPTCHA options to the web page using the CAPTCHA
resp = make_response(render_template("index.html", captcha_options=options, incorrect_captcha=incorrect_captcha))
# Track this user with a cookie and store the correct answer
# by linking the cookie with the answer, we can check their answer
# later
freecaptcha_cookie = str(uuid.uuid4())
resp.set_cookie('freecaptcha_cookie', freecaptcha_cookie)
captcha_solutions[freecaptcha_cookie] = answer
return resp

0
freecaptcha/__init__.py Normal file
View File

Binary file not shown.

Binary file not shown.

54
freecaptcha/captcha.py Normal file
View File

@ -0,0 +1,54 @@
import random
import os
from PIL import Image
import base64
from io import BytesIO
# Angles we'll rotate the original by
# when we create n rotations
def calculate_angles(n):
return list(range(0, 360, 360 // n))
def rotate_img(img_path, angle):
original_img = Image.open(img_path)
rotated = original_img.rotate(angle)
buffered = BytesIO()
rotated.save(buffered, format="PNG")
b64_rot = base64.b64encode(buffered.getvalue())
return b64_rot.decode("utf-8")
def captchafy(img_path, n=6):
angles = calculate_angles(n)
rotated_imgs = [
{
'original': False,
'image': rotate_img(img_path, angle)
} for angle in angles]
rotated_imgs[0]['original'] = True
random.shuffle(rotated_imgs)
correct_img = None
for index, img in enumerate(rotated_imgs):
if img['original']:
correct_img = index
return correct_img, [img['image'] for img in rotated_imgs]
def random_image(dir='images/'):
dir_contents = os.listdir(dir)
random_image = random.choice(dir_contents)
return dir + random_image
def resize_dir(size=150, dir='images/'):
for img_file in os.listdir(dir):
img = Image.open(dir + img_file)
width, height = img.size
print(width, height)
if not (width > size or height > size):
continue
img.thumbnail((size, size),Image.ANTIALIAS)
img.save(dir + img_file)

BIN
gnome.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1015 KiB

BIN
images/gnome.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

72
static/freecaptcha.css Normal file
View File

@ -0,0 +1,72 @@
.grid {
display: grid;
grid-template-columns: repeat(3, 0fr);
}
div > div {
padding: 10px;
}
/* HIDE RADIO */
[type=radio] {
position: absolute;
opacity: 0;
width: 0;
height: 0;
}
/* IMAGE STYLES */
[type=radio] + img {
cursor: pointer;
padding: 5px;
}
/* CHECKED STYLES */
[type=radio]:checked + img {
outline: 2px solid black;
filter: brightness(120%);
}
.isa_info, .isa_success, .isa_warning, .isa_error {
margin: 10px 0px;
padding:12px;
}
.isa_info {
color: #00529B;
background-color: #BDE5F8;
}
.isa_success {
color: #4F8A10;
background-color: #DFF2BF;
}
.isa_warning {
color: #9F6000;
background-color: #FEEFB3;
}
.isa_error {
color: #D8000C;
background-color: #FFD2D2;
}
.isa_info i, .isa_success i, .isa_warning i, .isa_error i {
margin:10px 22px;
font-size:2em;
vertical-align:middle;
}
#root {
width: fit-content;
/* To adjust the height as well */
height: fit-content;
}
input[type=submit] {
background-color: #4CAF50; /* Green */
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
}

31
templates/index.html Normal file
View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="freecaptcha.css">
<title>Tor Dev</title>
</head>
<body>
<div id="root">
{% if incorrect_captcha %}
<div class="isa_error">
<i class="fa fa-error"></i>
Wrong CAPTCHA, try again!
</div>
{% endif %}
<form method="POST">
<div class='grid'>
{% for captcha_image in captcha_options %}
<label>
<input type="radio" name="captcha" value="{{ loop.index0 }}" checked>
<img src="data:image/png;base64,{{ captcha_image }}"></img>
</label>
{% endfor %}
</div>
<center><input type="submit" value="Submit"></input></center>
</form>
</div>
</body>
</html>