mirror of
https://github.com/RoboSats/robosats.git
synced 2025-07-17 08:13:19 +00:00
Allow auth header to carry pgp keys (#805)
This commit is contained in:
@ -5,6 +5,8 @@ from channels.db import database_sync_to_async
|
|||||||
from channels.middleware import BaseMiddleware
|
from channels.middleware import BaseMiddleware
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.models import AnonymousUser, User, update_last_login
|
from django.contrib.auth.models import AnonymousUser, User, update_last_login
|
||||||
|
from django.utils.deprecation import MiddlewareMixin
|
||||||
|
from django.db import IntegrityError
|
||||||
from rest_framework.authtoken.models import Token
|
from rest_framework.authtoken.models import Token
|
||||||
from rest_framework.exceptions import AuthenticationFailed
|
from rest_framework.exceptions import AuthenticationFailed
|
||||||
from robohash import Robohash
|
from robohash import Robohash
|
||||||
@ -29,6 +31,24 @@ class DisableCSRFMiddleware(object):
|
|||||||
response = self.get_response(request)
|
response = self.get_response(request)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
class SplitAuthorizationHeaderMiddleware(MiddlewareMixin):
|
||||||
|
"""
|
||||||
|
This middleware splits the HTTP_AUTHORIZATION, leaves on it only the `Token ` and creates
|
||||||
|
two new META headers for both PGP keys.
|
||||||
|
Given that API calls to a RoboSats API might be made from other host origin,
|
||||||
|
there is a high chance browsers will not attach cookies and other sensitive information.
|
||||||
|
Therefore, we are using the `HTTP_AUTHORIZATION` header to also embded the needed robot
|
||||||
|
pubKey and encPrivKey to create a new robot in the coordinator on the first request.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def process_request(self, request):
|
||||||
|
auth_header = request.META.get("HTTP_AUTHORIZATION", "")
|
||||||
|
split_auth = auth_header.split(" | ")
|
||||||
|
|
||||||
|
if len(split_auth) == 3:
|
||||||
|
request.META["HTTP_AUTHORIZATION"] = split_auth[0]
|
||||||
|
request.META["PUBLIC_KEY"] = split_auth[1]
|
||||||
|
request.META["ENCRYPTED_PRIVATE_KEY"] = split_auth[2]
|
||||||
|
|
||||||
class RobotTokenSHA256AuthenticationMiddleWare:
|
class RobotTokenSHA256AuthenticationMiddleWare:
|
||||||
"""
|
"""
|
||||||
@ -70,9 +90,21 @@ class RobotTokenSHA256AuthenticationMiddleWare:
|
|||||||
# If we get here the user does not have a robot on this coordinator
|
# If we get here the user does not have a robot on this coordinator
|
||||||
# Let's create a new user & robot on-the-fly.
|
# Let's create a new user & robot on-the-fly.
|
||||||
|
|
||||||
# The first ever request to a coordinator must include cookies for the public key (and encrypted priv key as of now).
|
# The first ever request to a coordinator must public key (and encrypted priv key as of now). Either on the
|
||||||
public_key = request.COOKIES.get("public_key")
|
# Authorization header or in the Cookies.
|
||||||
encrypted_private_key = request.COOKIES.get("encrypted_private_key", "")
|
|
||||||
|
public_key = ""
|
||||||
|
encrypted_private_key = ""
|
||||||
|
|
||||||
|
public_key = request.META.get("PUBLIC_KEY", "").replace("Public ", "")
|
||||||
|
encrypted_private_key = request.META.get(
|
||||||
|
"ENCRYPTED_PRIVATE_KEY", ""
|
||||||
|
).replace("Private ", "")
|
||||||
|
|
||||||
|
# Some legacy (pre-federation) clients will still send keys as cookies
|
||||||
|
if public_key == "" or encrypted_private_key == "":
|
||||||
|
public_key = request.COOKIES.get("public_key")
|
||||||
|
encrypted_private_key = request.COOKIES.get("encrypted_private_key", "")
|
||||||
|
|
||||||
if not public_key or not encrypted_private_key:
|
if not public_key or not encrypted_private_key:
|
||||||
raise AuthenticationFailed(
|
raise AuthenticationFailed(
|
||||||
|
@ -149,16 +149,18 @@ SPECTACULAR_SETTINGS = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
"corsheaders.middleware.CorsMiddleware",
|
||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
"django.middleware.common.CommonMiddleware",
|
"django.middleware.common.CommonMiddleware",
|
||||||
"robosats.middleware.DisableCSRFMiddleware",
|
"robosats.middleware.DisableCSRFMiddleware",
|
||||||
|
"robosats.middleware.SplitAuthorizationHeaderMiddleware",
|
||||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
"robosats.middleware.RobotTokenSHA256AuthenticationMiddleWare",
|
"robosats.middleware.RobotTokenSHA256AuthenticationMiddleWare",
|
||||||
"django.contrib.messages.middleware.MessageMiddleware",
|
"django.contrib.messages.middleware.MessageMiddleware",
|
||||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||||
"corsheaders.middleware.CorsMiddleware",
|
|
||||||
"django.middleware.common.CommonMiddleware",
|
"django.middleware.common.CommonMiddleware",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user