Initial commit
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
venv
|
||||||
|
urlshorten.zip
|
||||||
16
README.md
Normal file
16
README.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# URL Shortener
|
||||||
|
There are many; this is mine.
|
||||||
|
|
||||||
|
## Bundling for upload
|
||||||
|
Create a virtual environment
|
||||||
|
python -m venv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
|
Install dependencies
|
||||||
|
python -m pip install -r requirements.txt
|
||||||
|
|
||||||
|
Zip it all up
|
||||||
|
cd venv/lib/python3.10/site-packages
|
||||||
|
zip -r ../../../../urlshorten.zip .
|
||||||
|
cd ../../../../
|
||||||
|
zip -g urlshorten.zip urlshorten.py
|
||||||
5
requirements.txt
Normal file
5
requirements.txt
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
certifi==2023.5.7
|
||||||
|
charset-normalizer==3.1.0
|
||||||
|
idna==3.4
|
||||||
|
requests==2.29.0
|
||||||
|
urllib3==1.26.15
|
||||||
76
urlshorten.py
Normal file
76
urlshorten.py
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import boto3
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from base64 import b64decode
|
||||||
|
from botocore.exceptions import ClientError
|
||||||
|
|
||||||
|
dynamodb = boto3.resource('dynamodb', region_name='us-west-2')
|
||||||
|
|
||||||
|
ENCRYPTED = os.environ['RECAPTCHA_SECRET']
|
||||||
|
# Decrypt code should run once and variables stored outside of the function
|
||||||
|
# handler so that these are decrypted once per container
|
||||||
|
RECAPTCHA_SECRET = boto3.client('kms').decrypt(CiphertextBlob=b64decode(ENCRYPTED))['Plaintext']
|
||||||
|
|
||||||
|
def lambda_handler(event, context):
|
||||||
|
table = dynamodb.Table('urlshorten')
|
||||||
|
|
||||||
|
if 'from' in event and 'to' in event:
|
||||||
|
captcha_data = {
|
||||||
|
'secret': RECAPTCHA_SECRET,
|
||||||
|
'response': event['g-recaptcha-response'],
|
||||||
|
'remoteip': event['remoteip']
|
||||||
|
}
|
||||||
|
|
||||||
|
verify = requests.get('https://www.google.com/recaptcha/api/siteverify',
|
||||||
|
params=captcha_data)
|
||||||
|
if not (verify.status_code == 200 and verify.json()['success']):
|
||||||
|
return {
|
||||||
|
'status': 'error',
|
||||||
|
'error': verify.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl = event['to'][:5].lower() == 'https'
|
||||||
|
|
||||||
|
url = ('https://' if ssl else 'http://') + event['to'].split('://')[-1]
|
||||||
|
|
||||||
|
try:
|
||||||
|
table.put_item(
|
||||||
|
Item={
|
||||||
|
'key': event['from'],
|
||||||
|
'value': url
|
||||||
|
},
|
||||||
|
ConditionExpression='attribute_not_exists(#key)',
|
||||||
|
ExpressionAttributeNames={
|
||||||
|
'#key': 'key'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
except ClientError as e:
|
||||||
|
return {
|
||||||
|
'status': 'error',
|
||||||
|
'error': e.response['Error']
|
||||||
|
}
|
||||||
|
except KeyError:
|
||||||
|
return {
|
||||||
|
'status': 'error',
|
||||||
|
'error': 'Invalid Request',
|
||||||
|
'location': '/'
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return {
|
||||||
|
'status': 'ok'
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = table.get_item(Key={ 'key': event['shortUrl'] })
|
||||||
|
location = response['Item']['value']
|
||||||
|
except ClientError as e:
|
||||||
|
return e.response['Error']
|
||||||
|
except KeyError:
|
||||||
|
return {
|
||||||
|
'location': '/'
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
return {
|
||||||
|
'location': response['Item']['value']
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user