mirror of https://github.com/zulip/zulip.git
78 lines
2.7 KiB
Python
78 lines
2.7 KiB
Python
import base64
|
|
import logging
|
|
import re
|
|
import shlex
|
|
import subprocess
|
|
from typing import Optional
|
|
|
|
import orjson
|
|
from django.conf import settings
|
|
from django.http import HttpRequest, HttpResponse
|
|
from django.utils.translation import gettext as _
|
|
|
|
from zerver.decorator import authenticated_json_view
|
|
from zerver.lib.ccache import make_ccache
|
|
from zerver.lib.exceptions import JsonableError
|
|
from zerver.lib.pysa import mark_sanitized
|
|
from zerver.lib.request import REQ, has_request_variables
|
|
from zerver.lib.response import json_success
|
|
from zerver.lib.users import get_api_key
|
|
from zerver.models import UserProfile
|
|
|
|
# Hack for mit.edu users whose Kerberos usernames don't match what they zephyr
|
|
# as. The key is for Kerberos and the value is for zephyr.
|
|
kerberos_alter_egos = {
|
|
"golem": "ctl",
|
|
}
|
|
|
|
|
|
@authenticated_json_view
|
|
@has_request_variables
|
|
def webathena_kerberos_login(
|
|
request: HttpRequest, user_profile: UserProfile, cred: Optional[str] = REQ(default=None)
|
|
) -> HttpResponse:
|
|
global kerberos_alter_egos
|
|
if cred is None:
|
|
raise JsonableError(_("Could not find Kerberos credential"))
|
|
if not user_profile.realm.webathena_enabled:
|
|
raise JsonableError(_("Webathena login not enabled"))
|
|
|
|
try:
|
|
parsed_cred = orjson.loads(cred)
|
|
user = parsed_cred["cname"]["nameString"][0]
|
|
if user in kerberos_alter_egos:
|
|
user = kerberos_alter_egos[user]
|
|
assert user == user_profile.email.split("@")[0]
|
|
# Limit characters in usernames to valid MIT usernames
|
|
# This is important for security since DNS is not secure.
|
|
assert re.match(r"^[a-z0-9_.-]+$", user) is not None
|
|
ccache = make_ccache(parsed_cred)
|
|
|
|
# 'user' has been verified to contain only benign characters that won't
|
|
# help with shell injection.
|
|
user = mark_sanitized(user)
|
|
|
|
# 'ccache' is only written to disk by the script and used as a kerberos
|
|
# credential cache file.
|
|
ccache = mark_sanitized(ccache)
|
|
except Exception:
|
|
raise JsonableError(_("Invalid Kerberos cache"))
|
|
|
|
# TODO: Send these data via (say) RabbitMQ
|
|
try:
|
|
api_key = get_api_key(user_profile)
|
|
command = [
|
|
"/home/zulip/python-zulip-api/zulip/integrations/zephyr/process_ccache",
|
|
user,
|
|
api_key,
|
|
base64.b64encode(ccache).decode(),
|
|
]
|
|
subprocess.check_call(
|
|
["ssh", settings.PERSONAL_ZMIRROR_SERVER, "--", " ".join(map(shlex.quote, command))]
|
|
)
|
|
except subprocess.CalledProcessError:
|
|
logging.exception("Error updating the user's ccache", stack_info=True)
|
|
raise JsonableError(_("We were unable to set up mirroring for you"))
|
|
|
|
return json_success(request)
|