mirror of
https://github.com/bringout/oca-server-auth.git
synced 2026-04-19 03:52:07 +02:00
Initial commit: OCA Server Auth packages (29 packages)
This commit is contained in:
commit
3ed80311c4
1325 changed files with 127292 additions and 0 deletions
|
|
@ -0,0 +1,177 @@
|
|||
import os
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
|
||||
from saml2 import BINDING_HTTP_POST, BINDING_HTTP_REDIRECT, pack
|
||||
from saml2.authn_context import INTERNETPROTOCOLPASSWORD
|
||||
from saml2.config import Config as Saml2Config
|
||||
from saml2.metadata import create_metadata_string
|
||||
from saml2.saml import NAME_FORMAT_URI, NAMEID_FORMAT_PERSISTENT
|
||||
from saml2.server import Server
|
||||
|
||||
TYP = {"GET": [BINDING_HTTP_REDIRECT], "POST": [BINDING_HTTP_POST]}
|
||||
|
||||
|
||||
AUTHN = {
|
||||
"class_ref": INTERNETPROTOCOLPASSWORD,
|
||||
"authn_auth": "http://www.example.com/login",
|
||||
}
|
||||
|
||||
|
||||
BASE = "http://localhost:8000"
|
||||
CONFIG = {
|
||||
"entityid": "urn:mace:example.com:saml:example:idp",
|
||||
"name": "Rolands IdP",
|
||||
"service": {
|
||||
"aa": {
|
||||
"endpoints": {
|
||||
"attribute_service": [
|
||||
("%s/aap" % BASE, BINDING_HTTP_POST),
|
||||
]
|
||||
},
|
||||
},
|
||||
"aq": {
|
||||
"endpoints": {
|
||||
"authn_query_service": [("%s/aqs" % BASE, BINDING_HTTP_POST)]
|
||||
},
|
||||
},
|
||||
"idp": {
|
||||
"endpoints": {
|
||||
"single_sign_on_service": [
|
||||
("%s/sso/redirect" % BASE, BINDING_HTTP_REDIRECT),
|
||||
("%s/sso/post" % BASE, BINDING_HTTP_POST),
|
||||
],
|
||||
},
|
||||
"policy": {
|
||||
"default": {
|
||||
"lifetime": {"minutes": 15},
|
||||
"attribute_restrictions": None,
|
||||
"name_form": NAME_FORMAT_URI,
|
||||
},
|
||||
"urn:mace:example.com:saml:example:sp": {
|
||||
"lifetime": {"minutes": 5},
|
||||
"nameid_format": NAMEID_FORMAT_PERSISTENT,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"debug": 1,
|
||||
"key_file": os.path.join(os.path.dirname(__file__), "data", "idp.pem"),
|
||||
"cert_file": os.path.join(os.path.dirname(__file__), "data", "idp.pem"),
|
||||
"organization": {
|
||||
"name": "Example",
|
||||
"display_name": [("Example", "uk")],
|
||||
"url": "http://www.example.com/",
|
||||
},
|
||||
"contact_person": [
|
||||
{
|
||||
"given_name": "Admin",
|
||||
"sur_name": "Admin",
|
||||
"email_address": ["admin@example.com"],
|
||||
"contact_type": "technical",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
class DummyResponse:
|
||||
def __init__(self, status, data, headers=None):
|
||||
self.status_code = status
|
||||
self.text = data
|
||||
self.headers = headers or []
|
||||
self.content = data
|
||||
|
||||
def _unpack(self, ver="SAMLResponse"):
|
||||
"""
|
||||
Unpack the response form
|
||||
"""
|
||||
_str = self.text
|
||||
|
||||
sr_str = 'name="%s" value="' % ver
|
||||
rs_str = 'name="RelayState" value="'
|
||||
|
||||
i = _str.find(sr_str)
|
||||
i += len(sr_str)
|
||||
j = _str.find('"', i)
|
||||
|
||||
sr = _str[i:j]
|
||||
|
||||
start = _str.find(rs_str, j)
|
||||
start += len(rs_str)
|
||||
end = _str.find('"', start)
|
||||
|
||||
rs = _str[start:end]
|
||||
|
||||
return {ver: sr, "RelayState": rs}
|
||||
|
||||
|
||||
class FakeIDP(Server):
|
||||
def __init__(self, metadatas=None, settings=None):
|
||||
if settings is None:
|
||||
settings = CONFIG
|
||||
if metadatas:
|
||||
settings.update({"metadata": {"inline": metadatas}})
|
||||
|
||||
config = Saml2Config()
|
||||
config.load(settings)
|
||||
config.allow_unknown_attributes = True
|
||||
Server.__init__(self, config=config)
|
||||
|
||||
def get_metadata(self):
|
||||
return create_metadata_string(
|
||||
None,
|
||||
config=self.config,
|
||||
sign=True,
|
||||
valid=True,
|
||||
cert=CONFIG.get("cert_file"),
|
||||
keyfile=CONFIG.get("key_file"),
|
||||
)
|
||||
|
||||
def fake_login(self, url):
|
||||
# Assumes GET query and HTTP_REDIRECT only.
|
||||
# This is all that auth_pysaml currently supports.
|
||||
parsed_url = urlparse(url)
|
||||
qs_dict = parse_qs(parsed_url.query)
|
||||
|
||||
samlreq = qs_dict["SAMLRequest"][0]
|
||||
rstate = qs_dict["RelayState"][0]
|
||||
|
||||
# process the logon request, and automatically "login"
|
||||
return self.authn_request_endpoint(samlreq, BINDING_HTTP_REDIRECT, rstate)
|
||||
|
||||
def authn_request_endpoint(self, req, binding, relay_state):
|
||||
req = self.parse_authn_request(req, binding)
|
||||
if req.message.protocol_binding == BINDING_HTTP_REDIRECT:
|
||||
_binding = BINDING_HTTP_POST
|
||||
else:
|
||||
_binding = req.message.protocol_binding
|
||||
|
||||
resp_args = self.response_args(req.message, [_binding])
|
||||
|
||||
identity = {
|
||||
"surName": "Example",
|
||||
"givenName": "Test",
|
||||
"title": "Ind",
|
||||
"mail": "test@example.com",
|
||||
}
|
||||
|
||||
resp_args.update({"sign_assertion": True, "sign_response": True})
|
||||
|
||||
authn_resp = self.create_authn_response(
|
||||
identity, userid=identity.get("mail"), authn=AUTHN, **resp_args
|
||||
)
|
||||
|
||||
_dict = pack.factory(
|
||||
_binding, authn_resp, resp_args["destination"], relay_state, "SAMLResponse"
|
||||
)
|
||||
|
||||
return DummyResponse(**_dict)
|
||||
|
||||
|
||||
class UnsignedFakeIDP(FakeIDP):
|
||||
def create_authn_response(
|
||||
self,
|
||||
*args,
|
||||
**kwargs,
|
||||
):
|
||||
kwargs["sign_assertion"] = False
|
||||
return super().create_authn_response(*args, **kwargs)
|
||||
Loading…
Add table
Add a link
Reference in a new issue