Compare commits
	
		
			29 Commits
		
	
	
		
			version/0.
			...
			version/0.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c9f0d048a8 | |||
| 90a94b5e3e | |||
| ae1a8842db | |||
| a3b17d1ed4 | |||
| 41576e27be | |||
| 07082cb3aa | |||
| 426cb33fab | |||
| 9e4f840d2d | |||
| e120d274e9 | |||
| 977d3f6ef9 | |||
| ecdbc917a5 | |||
| 0083cd55df | |||
| d380194e13 | |||
| 32f5d5ba72 | |||
| e818416863 | |||
| 7eed70cfe9 | |||
| ea6ca23f57 | |||
| f056b026d6 | |||
| 1c0a6efeb1 | |||
| 17732eea08 | |||
| aa5381fd59 | |||
| ffee86fcf3 | |||
| 7ff7398aff | |||
| 67925a39f2 | |||
| 3b5e1c7b34 | |||
| 3e49acf7ae | |||
| 76764c4374 | |||
| 9f6f8e1b55 | |||
| 9590180c6c | 
| @ -1,5 +1,5 @@ | ||||
| [bumpversion] | ||||
| current_version = 0.13.0-rc3 | ||||
| current_version = 0.13.0-rc4 | ||||
| tag = True | ||||
| commit = True | ||||
| parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-(?P<release>.*) | ||||
|  | ||||
							
								
								
									
										14
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @ -18,11 +18,11 @@ jobs: | ||||
|       - name: Building Docker Image | ||||
|         run: docker build | ||||
|           --no-cache | ||||
|           -t beryju/authentik:0.13.0-rc3 | ||||
|           -t beryju/authentik:0.13.0-rc4 | ||||
|           -t beryju/authentik:latest | ||||
|           -f Dockerfile . | ||||
|       - name: Push Docker Container to Registry (versioned) | ||||
|         run: docker push beryju/authentik:0.13.0-rc3 | ||||
|         run: docker push beryju/authentik:0.13.0-rc4 | ||||
|       - name: Push Docker Container to Registry (latest) | ||||
|         run: docker push beryju/authentik:latest | ||||
|   build-proxy: | ||||
| @ -48,11 +48,11 @@ jobs: | ||||
|           cd proxy/ | ||||
|           docker build \ | ||||
|           --no-cache \ | ||||
|           -t beryju/authentik-proxy:0.13.0-rc3 \ | ||||
|           -t beryju/authentik-proxy:0.13.0-rc4 \ | ||||
|           -t beryju/authentik-proxy:latest \ | ||||
|           -f Dockerfile . | ||||
|       - name: Push Docker Container to Registry (versioned) | ||||
|         run: docker push beryju/authentik-proxy:0.13.0-rc3 | ||||
|         run: docker push beryju/authentik-proxy:0.13.0-rc4 | ||||
|       - name: Push Docker Container to Registry (latest) | ||||
|         run: docker push beryju/authentik-proxy:latest | ||||
|   build-static: | ||||
| @ -69,11 +69,11 @@ jobs: | ||||
|           cd web/ | ||||
|           docker build \ | ||||
|           --no-cache \ | ||||
|           -t beryju/authentik-static:0.13.0-rc3 \ | ||||
|           -t beryju/authentik-static:0.13.0-rc4 \ | ||||
|           -t beryju/authentik-static:latest \ | ||||
|           -f Dockerfile . | ||||
|       - name: Push Docker Container to Registry (versioned) | ||||
|         run: docker push beryju/authentik-static:0.13.0-rc3 | ||||
|         run: docker push beryju/authentik-static:0.13.0-rc4 | ||||
|       - name: Push Docker Container to Registry (latest) | ||||
|         run: docker push beryju/authentik-static:latest | ||||
|   test-release: | ||||
| @ -107,5 +107,5 @@ jobs: | ||||
|           SENTRY_PROJECT: authentik | ||||
|           SENTRY_URL: https://sentry.beryju.org | ||||
|         with: | ||||
|           tagName: 0.13.0-rc3 | ||||
|           tagName: 0.13.0-rc4 | ||||
|           environment: beryjuorg-prod | ||||
|  | ||||
| @ -38,6 +38,7 @@ RUN apt-get update && \ | ||||
|  | ||||
| COPY ./authentik/ /authentik | ||||
| COPY ./pytest.ini / | ||||
| COPY ./xml /xml | ||||
| COPY ./manage.py / | ||||
| COPY ./lifecycle/ /lifecycle | ||||
|  | ||||
|  | ||||
							
								
								
									
										5
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
									
									
									
									
								
							| @ -1,5 +1,10 @@ | ||||
| all: lint-fix lint coverage gen | ||||
|  | ||||
| test-full: | ||||
| 	coverage run manage.py test --failfast -v 3 . | ||||
| 	coverage html | ||||
| 	coverage report | ||||
|  | ||||
| test-integration: | ||||
| 	k3d cluster create || exit 0 | ||||
| 	k3d kubeconfig write -o ~/.kube/config --overwrite | ||||
|  | ||||
| @ -6,9 +6,9 @@ As authentik is currently in a pre-stable, only the latest "stable" version is s | ||||
|  | ||||
| | Version  | Supported          | | ||||
| | -------- | ------------------ | | ||||
| | 0.10.x   | :white_check_mark: | | ||||
| | 0.11.x   | :white_check_mark: | | ||||
| | 0.12.x   | :white_check_mark: | | ||||
| | 0.13.x   | :white_check_mark: | | ||||
|  | ||||
| ## Reporting a Vulnerability | ||||
|  | ||||
|  | ||||
| @ -1,2 +1,2 @@ | ||||
| """authentik""" | ||||
| __version__ = "0.13.0-rc3" | ||||
| __version__ = "0.13.0-rc4" | ||||
|  | ||||
							
								
								
									
										37
									
								
								authentik/admin/tests/test_api.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								authentik/admin/tests/test_api.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| """test admin api""" | ||||
| from json import loads | ||||
|  | ||||
| from django.shortcuts import reverse | ||||
| from django.test import TestCase | ||||
|  | ||||
| from authentik import __version__ | ||||
| from authentik.core.models import Group, User | ||||
|  | ||||
|  | ||||
| class TestAdminAPI(TestCase): | ||||
|     """test admin api""" | ||||
|  | ||||
|     def setUp(self) -> None: | ||||
|         super().setUp() | ||||
|         self.user = User.objects.create(username="test-user") | ||||
|         self.group = Group.objects.create(name="superusers", is_superuser=True) | ||||
|         self.group.users.add(self.user) | ||||
|         self.group.save() | ||||
|         self.client.force_login(self.user) | ||||
|  | ||||
|     def test_overview(self): | ||||
|         """Test Overview API""" | ||||
|         response = self.client.get(reverse("authentik_api:admin_overview-list")) | ||||
|         self.assertEqual(response.status_code, 200) | ||||
|         body = loads(response.content) | ||||
|         self.assertEqual(body["version"], __version__) | ||||
|  | ||||
|     def test_metrics(self): | ||||
|         """Test metrics API""" | ||||
|         response = self.client.get(reverse("authentik_api:admin_metrics-list")) | ||||
|         self.assertEqual(response.status_code, 200) | ||||
|  | ||||
|     def test_tasks(self): | ||||
|         """Test tasks metrics API""" | ||||
|         response = self.client.get(reverse("authentik_api:admin_system_tasks-list")) | ||||
|         self.assertEqual(response.status_code, 200) | ||||
| @ -1,9 +1,13 @@ | ||||
| """admin tests""" | ||||
| from uuid import uuid4 | ||||
|  | ||||
| from django import forms | ||||
| from django.test import TestCase | ||||
| from django.test.client import RequestFactory | ||||
|  | ||||
| from authentik.admin.views.policies_bindings import PolicyBindingCreateView | ||||
| from authentik.core.models import Application | ||||
| from authentik.policies.forms import PolicyBindingForm | ||||
|  | ||||
|  | ||||
| class TestPolicyBindingView(TestCase): | ||||
| @ -18,9 +22,22 @@ class TestPolicyBindingView(TestCase): | ||||
|         view = PolicyBindingCreateView(request=request) | ||||
|         self.assertEqual(view.get_initial(), {}) | ||||
|  | ||||
|     def test_with_param(self): | ||||
|     def test_with_params_invalid(self): | ||||
|         """Test PolicyBindingCreateView with invalid get params""" | ||||
|         request = self.factory.get("/", {"target": uuid4()}) | ||||
|         view = PolicyBindingCreateView(request=request) | ||||
|         self.assertEqual(view.get_initial(), {}) | ||||
|  | ||||
|     def test_with_params(self): | ||||
|         """Test PolicyBindingCreateView with get params""" | ||||
|         target = Application.objects.create(name="test") | ||||
|         request = self.factory.get("/", {"target": target.pk.hex}) | ||||
|         view = PolicyBindingCreateView(request=request) | ||||
|         self.assertEqual(view.get_initial(), {"target": target, "order": 0}) | ||||
|  | ||||
|         self.assertTrue( | ||||
|             isinstance( | ||||
|                 PolicyBindingForm(initial={"target": "foo"}).fields["target"].widget, | ||||
|                 forms.HiddenInput, | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
| @ -1,8 +1,12 @@ | ||||
| """admin tests""" | ||||
| from uuid import uuid4 | ||||
|  | ||||
| from django import forms | ||||
| from django.test import TestCase | ||||
| from django.test.client import RequestFactory | ||||
|  | ||||
| from authentik.admin.views.stages_bindings import StageBindingCreateView | ||||
| from authentik.flows.forms import FlowStageBindingForm | ||||
| from authentik.flows.models import Flow | ||||
|  | ||||
|  | ||||
| @ -18,9 +22,22 @@ class TestStageBindingView(TestCase): | ||||
|         view = StageBindingCreateView(request=request) | ||||
|         self.assertEqual(view.get_initial(), {}) | ||||
|  | ||||
|     def test_with_param(self): | ||||
|     def test_with_params_invalid(self): | ||||
|         """Test StageBindingCreateView with invalid get params""" | ||||
|         request = self.factory.get("/", {"target": uuid4()}) | ||||
|         view = StageBindingCreateView(request=request) | ||||
|         self.assertEqual(view.get_initial(), {}) | ||||
|  | ||||
|     def test_with_params(self): | ||||
|         """Test StageBindingCreateView with get params""" | ||||
|         target = Flow.objects.create(name="test", slug="test") | ||||
|         request = self.factory.get("/", {"target": target.pk.hex}) | ||||
|         view = StageBindingCreateView(request=request) | ||||
|         self.assertEqual(view.get_initial(), {"target": target, "order": 0}) | ||||
|  | ||||
|         self.assertTrue( | ||||
|             isinstance( | ||||
|                 FlowStageBindingForm(initial={"target": "foo"}).fields["target"].widget, | ||||
|                 forms.HiddenInput, | ||||
|             ) | ||||
|         ) | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| """API Authentication""" | ||||
| from base64 import b64decode | ||||
| from binascii import Error | ||||
| from typing import Any, Optional, Tuple, Union | ||||
|  | ||||
| from rest_framework.authentication import BaseAuthentication, get_authorization_header | ||||
| @ -24,7 +25,7 @@ def token_from_header(raw_header: bytes) -> Optional[Token]: | ||||
|             return None | ||||
|     try: | ||||
|         auth_credentials = b64decode(auth_credentials.encode()).decode() | ||||
|     except UnicodeDecodeError: | ||||
|     except (UnicodeDecodeError, Error): | ||||
|         return None | ||||
|     # Accept credentials with username and without | ||||
|     if ":" in auth_credentials: | ||||
|  | ||||
							
								
								
									
										37
									
								
								authentik/api/tests.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								authentik/api/tests.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| """Test API Authentication""" | ||||
| from base64 import b64encode | ||||
|  | ||||
| from django.test import TestCase | ||||
| from guardian.shortcuts import get_anonymous_user | ||||
|  | ||||
| from authentik.api.auth import token_from_header | ||||
| from authentik.core.models import Token, TokenIntents | ||||
|  | ||||
|  | ||||
| class TestAPIAuth(TestCase): | ||||
|     """Test API Authentication""" | ||||
|  | ||||
|     def test_valid(self): | ||||
|         """Test valid token""" | ||||
|         token = Token.objects.create( | ||||
|             intent=TokenIntents.INTENT_API, user=get_anonymous_user() | ||||
|         ) | ||||
|         auth = b64encode(f":{token.key}".encode()).decode() | ||||
|         self.assertEqual(token_from_header(f"Basic {auth}".encode()), token) | ||||
|  | ||||
|     def test_invalid_type(self): | ||||
|         """Test invalid type""" | ||||
|         self.assertIsNone(token_from_header("foo bar".encode())) | ||||
|  | ||||
|     def test_invalid_decode(self): | ||||
|         """Test invalid bas64""" | ||||
|         self.assertIsNone(token_from_header("Basic bar".encode())) | ||||
|  | ||||
|     def test_invalid_empty_password(self): | ||||
|         """Test invalid with empty password""" | ||||
|         self.assertIsNone(token_from_header("Basic :".encode())) | ||||
|  | ||||
|     def test_invalid_no_token(self): | ||||
|         """Test invalid with no token""" | ||||
|         auth = b64encode(":abc".encode()).decode() | ||||
|         self.assertIsNone(token_from_header(f"Basic :{auth}".encode())) | ||||
| @ -1,4 +1,5 @@ | ||||
| """Channels base classes""" | ||||
| from channels.exceptions import DenyConnection | ||||
| from channels.generic.websocket import JsonWebsocketConsumer | ||||
| from structlog import get_logger | ||||
|  | ||||
| @ -17,16 +18,13 @@ class AuthJsonConsumer(JsonWebsocketConsumer): | ||||
|         headers = dict(self.scope["headers"]) | ||||
|         if b"authorization" not in headers: | ||||
|             LOGGER.warning("WS Request without authorization header") | ||||
|             self.close() | ||||
|             return False | ||||
|             raise DenyConnection() | ||||
|  | ||||
|         raw_header = headers[b"authorization"] | ||||
|  | ||||
|         token = token_from_header(raw_header) | ||||
|         if not token: | ||||
|             LOGGER.warning("Failed to authenticate") | ||||
|             self.close() | ||||
|             return False | ||||
|             raise DenyConnection() | ||||
|  | ||||
|         self.user = token.user | ||||
|         return True | ||||
|  | ||||
| @ -22,16 +22,15 @@ class CertificateKeyPairSerializer(ModelSerializer): | ||||
|     def validate_key_data(self, value): | ||||
|         """Verify that input is a valid PEM RSA Key""" | ||||
|         # Since this field is optional, data can be empty. | ||||
|         if value == "": | ||||
|             return value | ||||
|         try: | ||||
|             load_pem_private_key( | ||||
|                 str.encode("\n".join([x.strip() for x in value.split("\n")])), | ||||
|                 password=None, | ||||
|                 backend=default_backend(), | ||||
|             ) | ||||
|         except ValueError: | ||||
|             raise ValidationError("Unable to load private key.") | ||||
|         if value != "": | ||||
|             try: | ||||
|                 load_pem_private_key( | ||||
|                     str.encode("\n".join([x.strip() for x in value.split("\n")])), | ||||
|                     password=None, | ||||
|                     backend=default_backend(), | ||||
|                 ) | ||||
|             except ValueError: | ||||
|                 raise ValidationError("Unable to load private key.") | ||||
|         return value | ||||
|  | ||||
|     class Meta: | ||||
|  | ||||
| @ -26,16 +26,15 @@ class CertificateKeyPairForm(forms.ModelForm): | ||||
|         """Verify that input is a valid PEM RSA Key""" | ||||
|         key_data = self.cleaned_data["key_data"] | ||||
|         # Since this field is optional, data can be empty. | ||||
|         if key_data == "": | ||||
|             return key_data | ||||
|         try: | ||||
|             load_pem_private_key( | ||||
|                 str.encode("\n".join([x.strip() for x in key_data.split("\n")])), | ||||
|                 password=None, | ||||
|                 backend=default_backend(), | ||||
|             ) | ||||
|         except ValueError: | ||||
|             raise forms.ValidationError("Unable to load private key.") | ||||
|         if key_data != "": | ||||
|             try: | ||||
|                 load_pem_private_key( | ||||
|                     str.encode("\n".join([x.strip() for x in key_data.split("\n")])), | ||||
|                     password=None, | ||||
|                     backend=default_backend(), | ||||
|                 ) | ||||
|             except ValueError: | ||||
|                 raise forms.ValidationError("Unable to load private key.") | ||||
|         return key_data | ||||
|  | ||||
|     class Meta: | ||||
|  | ||||
| @ -3,14 +3,17 @@ from unittest.mock import MagicMock, PropertyMock, patch | ||||
|  | ||||
| from django.http import HttpRequest, HttpResponse | ||||
| from django.shortcuts import reverse | ||||
| from django.test import Client, TestCase | ||||
| from django.test import TestCase | ||||
| from django.test.client import RequestFactory | ||||
| from django.utils.encoding import force_str | ||||
|  | ||||
| from authentik.core.models import User | ||||
| from authentik.flows.exceptions import EmptyFlowException, FlowNonApplicableException | ||||
| from authentik.flows.markers import ReevaluateMarker, StageMarker | ||||
| from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding | ||||
| from authentik.flows.planner import FlowPlan | ||||
| from authentik.flows.views import NEXT_ARG_NAME, SESSION_KEY_PLAN | ||||
| from authentik.flows.planner import FlowPlan, FlowPlanner | ||||
| from authentik.flows.stage import PLAN_CONTEXT_PENDING_USER_IDENTIFIER, StageView | ||||
| from authentik.flows.views import NEXT_ARG_NAME, SESSION_KEY_PLAN, FlowExecutorView | ||||
| from authentik.lib.config import CONFIG | ||||
| from authentik.policies.dummy.models import DummyPolicy | ||||
| from authentik.policies.http import AccessDeniedResponse | ||||
| @ -35,7 +38,7 @@ class TestFlowExecutor(TestCase): | ||||
|     """Test views logic""" | ||||
|  | ||||
|     def setUp(self): | ||||
|         self.client = Client() | ||||
|         self.request_factory = RequestFactory() | ||||
|  | ||||
|     def test_existing_plan_diff_flow(self): | ||||
|         """Check that a plan for a different flow cancels the current plan""" | ||||
| @ -276,6 +279,83 @@ class TestFlowExecutor(TestCase): | ||||
|             {"type": "redirect", "to": reverse("authentik_core:shell")}, | ||||
|         ) | ||||
|  | ||||
|     def test_reevaluate_keep(self): | ||||
|         """Test planner with re-evaluate (everything is kept)""" | ||||
|         flow = Flow.objects.create( | ||||
|             name="test-default-context", | ||||
|             slug="test-default-context", | ||||
|             designation=FlowDesignation.AUTHENTICATION, | ||||
|         ) | ||||
|         true_policy = DummyPolicy.objects.create(result=True, wait_min=1, wait_max=2) | ||||
|  | ||||
|         binding = FlowStageBinding.objects.create( | ||||
|             target=flow, stage=DummyStage.objects.create(name="dummy1"), order=0 | ||||
|         ) | ||||
|         binding2 = FlowStageBinding.objects.create( | ||||
|             target=flow, | ||||
|             stage=DummyStage.objects.create(name="dummy2"), | ||||
|             order=1, | ||||
|             re_evaluate_policies=True, | ||||
|         ) | ||||
|         binding3 = FlowStageBinding.objects.create( | ||||
|             target=flow, stage=DummyStage.objects.create(name="dummy3"), order=2 | ||||
|         ) | ||||
|  | ||||
|         PolicyBinding.objects.create(policy=true_policy, target=binding2, order=0) | ||||
|  | ||||
|         # Here we patch the dummy policy to evaluate to true so the stage is included | ||||
|         with patch( | ||||
|             "authentik.policies.dummy.models.DummyPolicy.passes", POLICY_RETURN_TRUE | ||||
|         ): | ||||
|  | ||||
|             exec_url = reverse( | ||||
|                 "authentik_flows:flow-executor", kwargs={"flow_slug": flow.slug} | ||||
|             ) | ||||
|             # First request, run the planner | ||||
|             response = self.client.get(exec_url) | ||||
|  | ||||
|             self.assertEqual(response.status_code, 200) | ||||
|             plan: FlowPlan = self.client.session[SESSION_KEY_PLAN] | ||||
|  | ||||
|             self.assertEqual(plan.stages[0], binding.stage) | ||||
|             self.assertEqual(plan.stages[1], binding2.stage) | ||||
|             self.assertEqual(plan.stages[2], binding3.stage) | ||||
|  | ||||
|             self.assertIsInstance(plan.markers[0], StageMarker) | ||||
|             self.assertIsInstance(plan.markers[1], ReevaluateMarker) | ||||
|             self.assertIsInstance(plan.markers[2], StageMarker) | ||||
|  | ||||
|             # Second request, this passes the first dummy stage | ||||
|             response = self.client.post(exec_url) | ||||
|             self.assertEqual(response.status_code, 302) | ||||
|  | ||||
|             plan: FlowPlan = self.client.session[SESSION_KEY_PLAN] | ||||
|  | ||||
|             self.assertEqual(plan.stages[0], binding2.stage) | ||||
|             self.assertEqual(plan.stages[1], binding3.stage) | ||||
|  | ||||
|             self.assertIsInstance(plan.markers[0], StageMarker) | ||||
|             self.assertIsInstance(plan.markers[1], StageMarker) | ||||
|  | ||||
|             # Third request, this passes the first dummy stage | ||||
|             response = self.client.post(exec_url) | ||||
|             self.assertEqual(response.status_code, 302) | ||||
|  | ||||
|             plan: FlowPlan = self.client.session[SESSION_KEY_PLAN] | ||||
|  | ||||
|             self.assertEqual(plan.stages[0], binding3.stage) | ||||
|  | ||||
|             self.assertIsInstance(plan.markers[0], StageMarker) | ||||
|  | ||||
|         # third request, this should trigger the re-evaluate | ||||
|         # We do this request without the patch, so the policy results in false | ||||
|         response = self.client.post(exec_url) | ||||
|         self.assertEqual(response.status_code, 200) | ||||
|         self.assertJSONEqual( | ||||
|             force_str(response.content), | ||||
|             {"type": "redirect", "to": reverse("authentik_core:shell")}, | ||||
|         ) | ||||
|  | ||||
|     def test_reevaluate_remove_consecutive(self): | ||||
|         """Test planner with re-evaluate (consecutive stages are removed)""" | ||||
|         flow = Flow.objects.create( | ||||
| @ -351,3 +431,33 @@ class TestFlowExecutor(TestCase): | ||||
|             force_str(response.content), | ||||
|             {"type": "redirect", "to": reverse("authentik_core:shell")}, | ||||
|         ) | ||||
|  | ||||
|     def test_stageview_user_identifier(self): | ||||
|         """Test PLAN_CONTEXT_PENDING_USER_IDENTIFIER""" | ||||
|         flow = Flow.objects.create( | ||||
|             name="test-default-context", | ||||
|             slug="test-default-context", | ||||
|             designation=FlowDesignation.AUTHENTICATION, | ||||
|         ) | ||||
|         FlowStageBinding.objects.create( | ||||
|             target=flow, stage=DummyStage.objects.create(name="dummy"), order=0 | ||||
|         ) | ||||
|  | ||||
|         ident = "test-identifier" | ||||
|  | ||||
|         user = User.objects.create(username="test-user") | ||||
|         request = self.request_factory.get( | ||||
|             reverse("authentik_flows:flow-executor", kwargs={"flow_slug": flow.slug}), | ||||
|         ) | ||||
|         request.user = user | ||||
|         planner = FlowPlanner(flow) | ||||
|         plan = planner.plan( | ||||
|             request, default_context={PLAN_CONTEXT_PENDING_USER_IDENTIFIER: ident} | ||||
|         ) | ||||
|  | ||||
|         executor = FlowExecutorView() | ||||
|         executor.plan = plan | ||||
|         executor.flow = flow | ||||
|  | ||||
|         stage_view = StageView(executor) | ||||
|         self.assertEqual(ident, stage_view.get_context_data()["user"].username) | ||||
|  | ||||
| @ -61,7 +61,7 @@ class DataclassEncoder(JSONEncoder): | ||||
|             return asdict(o) | ||||
|         if isinstance(o, UUID): | ||||
|             return str(o) | ||||
|         return super().default(o) | ||||
|         return super().default(o)  # pragma: no cover | ||||
|  | ||||
|  | ||||
| class EntryInvalidError(SentryIgnoredException): | ||||
|  | ||||
| @ -11,7 +11,7 @@ from authentik.flows.transfer.common import ( | ||||
|     FlowBundle, | ||||
|     FlowBundleEntry, | ||||
| ) | ||||
| from authentik.policies.models import Policy, PolicyBinding, PolicyBindingModel | ||||
| from authentik.policies.models import Policy, PolicyBinding | ||||
| from authentik.stages.prompt.models import PromptStage | ||||
|  | ||||
|  | ||||
| @ -31,11 +31,6 @@ class FlowExporter: | ||||
|  | ||||
|     def _prepare_pbm(self): | ||||
|         self.pbm_uuids = [self.flow.pbm_uuid] | ||||
|         for stage_subclass in Stage.__subclasses__(): | ||||
|             if issubclass(stage_subclass, PolicyBindingModel): | ||||
|                 self.pbm_uuids += stage_subclass.objects.filter( | ||||
|                     flow=self.flow | ||||
|                 ).values_list("pbm_uuid", flat=True) | ||||
|         self.pbm_uuids += FlowStageBinding.objects.filter(target=self.flow).values_list( | ||||
|             "pbm_uuid", flat=True | ||||
|         ) | ||||
|  | ||||
| @ -1,55 +0,0 @@ | ||||
| """authentik lib navbar Templatetag""" | ||||
| from django import template | ||||
| from django.http import HttpRequest | ||||
| from structlog import get_logger | ||||
|  | ||||
| register = template.Library() | ||||
|  | ||||
| LOGGER = get_logger() | ||||
| ACTIVE_STRING = "pf-m-current" | ||||
|  | ||||
|  | ||||
| @register.simple_tag(takes_context=True) | ||||
| def is_active(context, *args: str, **_) -> str: | ||||
|     """Return whether a navbar link is active or not.""" | ||||
|     request: HttpRequest = context.get("request") | ||||
|     if not request.resolver_match: | ||||
|         return "" | ||||
|     match = request.resolver_match | ||||
|     for url in args: | ||||
|         if ":" in url: | ||||
|             app_name, url = url.split(":") | ||||
|             if match.app_name == app_name and match.url_name == url: | ||||
|                 return ACTIVE_STRING | ||||
|         else: | ||||
|             if match.url_name == url: | ||||
|                 return ACTIVE_STRING | ||||
|     return "" | ||||
|  | ||||
|  | ||||
| @register.simple_tag(takes_context=True) | ||||
| def is_active_url(context, view: str) -> str: | ||||
|     """Return whether a navbar link is active or not.""" | ||||
|     request: HttpRequest = context.get("request") | ||||
|     if not request.resolver_match: | ||||
|         return "" | ||||
|  | ||||
|     match = request.resolver_match | ||||
|     current_full_url = f"{match.app_name}:{match.url_name}" | ||||
|  | ||||
|     if current_full_url == view: | ||||
|         return ACTIVE_STRING | ||||
|     return "" | ||||
|  | ||||
|  | ||||
| @register.simple_tag(takes_context=True) | ||||
| def is_active_app(context, *args: str) -> str: | ||||
|     """Return True if current link is from app""" | ||||
|  | ||||
|     request: HttpRequest = context.get("request") | ||||
|     if not request.resolver_match: | ||||
|         return "" | ||||
|     for app_name in args: | ||||
|         if request.resolver_match.app_name == app_name: | ||||
|             return ACTIVE_STRING | ||||
|     return "" | ||||
							
								
								
									
										0
									
								
								authentik/lib/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								authentik/lib/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										18
									
								
								authentik/lib/tests/test_sentry.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								authentik/lib/tests/test_sentry.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| """test sentry integration""" | ||||
| from django.test import TestCase | ||||
|  | ||||
| from authentik.lib.sentry import SentryIgnoredException, before_send | ||||
|  | ||||
|  | ||||
| class TestSentry(TestCase): | ||||
|     """test sentry integration""" | ||||
|  | ||||
|     def test_error_not_sent(self): | ||||
|         """Test SentryIgnoredError not sent""" | ||||
|         self.assertIsNone( | ||||
|             before_send(None, {"exc_info": (0, SentryIgnoredException(), 0)}) | ||||
|         ) | ||||
|  | ||||
|     def test_error_sent(self): | ||||
|         """Test error sent""" | ||||
|         self.assertIsNone(before_send(None, {"exc_info": (0, ValueError(), 0)})) | ||||
| @ -20,6 +20,8 @@ class TestTimeUtils(TestCase): | ||||
|         """Test invalid expression""" | ||||
|         with self.assertRaises(ValueError): | ||||
|             timedelta_from_string("foo") | ||||
|         with self.assertRaises(ValueError): | ||||
|             timedelta_from_string("bar=baz") | ||||
| 
 | ||||
|     def test_validation(self): | ||||
|         """Test Django model field validator""" | ||||
| @ -35,4 +35,6 @@ def timedelta_from_string(expr: str) -> datetime.timedelta: | ||||
|         if key.lower() not in ALLOWED_KEYS: | ||||
|             continue | ||||
|         kwargs[key.lower()] = float(value) | ||||
|     if len(kwargs) < 1: | ||||
|         raise ValueError("No valid keys to pass to timedelta") | ||||
|     return datetime.timedelta(**kwargs) | ||||
|  | ||||
| @ -22,7 +22,6 @@ class AuthentikOutpostConfig(AppConfig): | ||||
|  | ||||
|     name = "authentik.outposts" | ||||
|     label = "authentik_outposts" | ||||
|     mountpoint = "outposts/" | ||||
|     verbose_name = "authentik Outpost" | ||||
|  | ||||
|     def ready(self): | ||||
|  | ||||
| @ -2,8 +2,9 @@ | ||||
| from dataclasses import asdict, dataclass, field | ||||
| from datetime import datetime | ||||
| from enum import IntEnum | ||||
| from typing import Any, Dict | ||||
| from typing import Any, Dict, Optional | ||||
|  | ||||
| from channels.exceptions import DenyConnection | ||||
| from dacite import from_dict | ||||
| from dacite.data import Data | ||||
| from guardian.shortcuts import get_objects_for_user | ||||
| @ -39,18 +40,16 @@ class WebsocketMessage: | ||||
| class OutpostConsumer(AuthJsonConsumer): | ||||
|     """Handler for Outposts that connect over websockets for health checks and live updates""" | ||||
|  | ||||
|     outpost: Outpost | ||||
|     outpost: Optional[Outpost] = None | ||||
|  | ||||
|     def connect(self): | ||||
|         if not super().connect(): | ||||
|             return | ||||
|         super().connect() | ||||
|         uuid = self.scope["url_route"]["kwargs"]["pk"] | ||||
|         outpost = get_objects_for_user( | ||||
|             self.user, "authentik_outposts.view_outpost" | ||||
|         ).filter(pk=uuid) | ||||
|         if not outpost.exists(): | ||||
|             self.close() | ||||
|             return | ||||
|             raise DenyConnection() | ||||
|         self.accept() | ||||
|         self.outpost = outpost.first() | ||||
|         OutpostState( | ||||
| @ -60,7 +59,8 @@ class OutpostConsumer(AuthJsonConsumer): | ||||
|  | ||||
|     # pylint: disable=unused-argument | ||||
|     def disconnect(self, close_code): | ||||
|         OutpostState.for_channel(self.outpost, self.channel_name).delete() | ||||
|         if self.outpost: | ||||
|             OutpostState.for_channel(self.outpost, self.channel_name).delete() | ||||
|         LOGGER.debug("removed channel from cache", channel_name=self.channel_name) | ||||
|  | ||||
|     def receive_json(self, content: Data): | ||||
|  | ||||
							
								
								
									
										38
									
								
								authentik/outposts/migrations/0014_auto_20201213_1407.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								authentik/outposts/migrations/0014_auto_20201213_1407.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| # Generated by Django 3.1.4 on 2020-12-13 14:07 | ||||
|  | ||||
| from django.apps.registry import Apps | ||||
| from django.db import migrations, models | ||||
| from django.db.backends.base.schema import BaseDatabaseSchemaEditor | ||||
|  | ||||
|  | ||||
| def update_config_prefix(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): | ||||
|     alias = schema_editor.connection.alias | ||||
|     Outpost = apps.get_model("authentik_outposts", "Outpost") | ||||
|  | ||||
|     for outpost in Outpost.objects.using(alias).all(): | ||||
|         config = outpost._config | ||||
|         for key in list(config): | ||||
|             if "passbook" in key: | ||||
|                 new_key = key.replace("passbook", "authentik") | ||||
|                 config[new_key] = config[key] | ||||
|                 del config[key] | ||||
|         outpost._config = config | ||||
|         outpost.save() | ||||
|  | ||||
|  | ||||
| class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("authentik_outposts", "0013_auto_20201203_2009"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|         migrations.RunPython(update_config_prefix), | ||||
|         migrations.AlterField( | ||||
|             model_name="dockerserviceconnection", | ||||
|             name="url", | ||||
|             field=models.TextField( | ||||
|                 help_text="Can be in the format of 'unix://<path>' when connecting to a local docker daemon, or 'https://<hostname>:2376' when connecting to a remote system." | ||||
|             ), | ||||
|         ), | ||||
|     ] | ||||
| @ -140,7 +140,14 @@ class OutpostServiceConnection(models.Model): | ||||
| class DockerServiceConnection(OutpostServiceConnection): | ||||
|     """Service Connection to a Docker endpoint""" | ||||
|  | ||||
|     url = models.TextField() | ||||
|     url = models.TextField( | ||||
|         help_text=_( | ||||
|             ( | ||||
|                 "Can be in the format of 'unix://<path>' when connecting to a local docker daemon, " | ||||
|                 "or 'https://<hostname>:2376' when connecting to a remote system." | ||||
|             ) | ||||
|         ) | ||||
|     ) | ||||
|     tls_verification = models.ForeignKey( | ||||
|         CertificateKeyPair, | ||||
|         null=True, | ||||
|  | ||||
| @ -12,4 +12,9 @@ CELERY_BEAT_SCHEDULE = { | ||||
|         "schedule": crontab(minute=0, hour="*"), | ||||
|         "options": {"queue": "authentik_scheduled"}, | ||||
|     }, | ||||
|     "outpost_token_ensurer": { | ||||
|         "task": "authentik.outposts.tasks.outpost_token_ensurer", | ||||
|         "schedule": crontab(minute="*/5"), | ||||
|         "options": {"queue": "authentik_scheduled"}, | ||||
|     }, | ||||
| } | ||||
|  | ||||
| @ -90,6 +90,21 @@ def outpost_pre_delete(outpost_pk: str): | ||||
|             ProxyKubernetesController(outpost, service_connection).down() | ||||
|  | ||||
|  | ||||
| @CELERY_APP.task(bind=True, base=MonitoredTask) | ||||
| def outpost_token_ensurer(self: MonitoredTask): | ||||
|     """Periodically ensure that all Outposts have valid Service Accounts | ||||
|     and Tokens""" | ||||
|     all_outposts = Outpost.objects.all() | ||||
|     for outpost in all_outposts: | ||||
|         _ = outpost.token | ||||
|     self.set_status( | ||||
|         TaskResult( | ||||
|             TaskResultStatus.SUCCESSFUL, | ||||
|             [f"Successfully checked {len(all_outposts)} Outposts."], | ||||
|         ) | ||||
|     ) | ||||
|  | ||||
|  | ||||
| @CELERY_APP.task() | ||||
| def outpost_post_save(model_class: str, model_pk: Any): | ||||
|     """If an Outpost is saved, Ensure that token is created/updated | ||||
|  | ||||
| @ -1,11 +0,0 @@ | ||||
| """authentik outposts urls""" | ||||
| from django.urls import path | ||||
|  | ||||
| from authentik.outposts.views import KubernetesManifestView, SetupView | ||||
|  | ||||
| urlpatterns = [ | ||||
|     path( | ||||
|         "<uuid:outpost_pk>/k8s/", KubernetesManifestView.as_view(), name="k8s-manifest" | ||||
|     ), | ||||
|     path("<uuid:outpost_pk>/", SetupView.as_view(), name="setup"), | ||||
| ] | ||||
| @ -1,89 +0,0 @@ | ||||
| """authentik outpost views""" | ||||
| from typing import Any, Dict, List | ||||
|  | ||||
| from django.contrib.auth.mixins import LoginRequiredMixin | ||||
| from django.db.models import Model | ||||
| from django.http import HttpRequest, HttpResponse | ||||
| from django.shortcuts import get_object_or_404 | ||||
| from django.views import View | ||||
| from django.views.generic import TemplateView | ||||
| from guardian.shortcuts import get_objects_for_user | ||||
| from structlog import get_logger | ||||
|  | ||||
| from authentik.core.models import User | ||||
| from authentik.outposts.controllers.docker import DockerController | ||||
| from authentik.outposts.models import ( | ||||
|     DockerServiceConnection, | ||||
|     KubernetesServiceConnection, | ||||
|     Outpost, | ||||
|     OutpostType, | ||||
| ) | ||||
| from authentik.providers.proxy.controllers.kubernetes import ProxyKubernetesController | ||||
|  | ||||
| LOGGER = get_logger() | ||||
|  | ||||
|  | ||||
| def get_object_for_user_or_404(user: User, perm: str, **filters) -> Model: | ||||
|     """Wrapper that combines get_objects_for_user and get_object_or_404""" | ||||
|     return get_object_or_404(get_objects_for_user(user, perm), **filters) | ||||
|  | ||||
|  | ||||
| class DockerComposeView(LoginRequiredMixin, View): | ||||
|     """Generate docker-compose yaml""" | ||||
|  | ||||
|     def get(self, request: HttpRequest, outpost_pk: str) -> HttpResponse: | ||||
|         """Render docker-compose file""" | ||||
|         outpost: Outpost = get_object_for_user_or_404( | ||||
|             request.user, | ||||
|             "authentik_outposts.view_outpost", | ||||
|             pk=outpost_pk, | ||||
|         ) | ||||
|         manifest = "" | ||||
|         if outpost.type == OutpostType.PROXY: | ||||
|             controller = DockerController(outpost, DockerServiceConnection()) | ||||
|             manifest = controller.get_static_deployment() | ||||
|  | ||||
|         return HttpResponse(manifest, content_type="text/vnd.yaml") | ||||
|  | ||||
|  | ||||
| class KubernetesManifestView(LoginRequiredMixin, View): | ||||
|     """Generate Kubernetes Deployment and SVC for proxy""" | ||||
|  | ||||
|     def get(self, request: HttpRequest, outpost_pk: str) -> HttpResponse: | ||||
|         """Render deployment template""" | ||||
|         outpost: Outpost = get_object_for_user_or_404( | ||||
|             request.user, | ||||
|             "authentik_outposts.view_outpost", | ||||
|             pk=outpost_pk, | ||||
|         ) | ||||
|         manifest = "" | ||||
|         if outpost.type == OutpostType.PROXY: | ||||
|             controller = ProxyKubernetesController( | ||||
|                 outpost, KubernetesServiceConnection() | ||||
|             ) | ||||
|             manifest = controller.get_static_deployment() | ||||
|  | ||||
|         return HttpResponse(manifest, content_type="text/vnd.yaml") | ||||
|  | ||||
|  | ||||
| class SetupView(LoginRequiredMixin, TemplateView): | ||||
|     """Setup view""" | ||||
|  | ||||
|     def get_template_names(self) -> List[str]: | ||||
|         allowed = ["dc", "custom", "k8s_manual", "k8s_integration"] | ||||
|         setup_type = self.request.GET.get("type", "dc") | ||||
|         if setup_type not in allowed: | ||||
|             setup_type = allowed[0] | ||||
|         return [f"outposts/setup_{setup_type}.html"] | ||||
|  | ||||
|     def get_context_data(self, **kwargs: Any) -> Dict[str, Any]: | ||||
|         kwargs = super().get_context_data(**kwargs) | ||||
|         outpost: Outpost = get_object_for_user_or_404( | ||||
|             self.request.user, | ||||
|             "authentik_outposts.view_outpost", | ||||
|             pk=self.kwargs["outpost_pk"], | ||||
|         ) | ||||
|         kwargs.update( | ||||
|             {"host": self.request.build_absolute_uri("/"), "outpost": outpost} | ||||
|         ) | ||||
|         return kwargs | ||||
| @ -50,6 +50,7 @@ class HaveIBeenPwendPolicy(Policy): | ||||
|                 field=self.password_field, | ||||
|                 fields=request.context.keys(), | ||||
|             ) | ||||
|             return PolicyResult(False, _("Password not set in context")) | ||||
|         password = request.context[self.password_field] | ||||
|  | ||||
|         pw_hash = sha1(password.encode("utf-8")).hexdigest()  # nosec | ||||
|  | ||||
| @ -10,6 +10,16 @@ from authentik.providers.oauth2.generators import generate_client_secret | ||||
| class TestHIBPPolicy(TestCase): | ||||
|     """Test HIBP Policy""" | ||||
|  | ||||
|     def test_invalid(self): | ||||
|         """Test without password""" | ||||
|         policy = HaveIBeenPwendPolicy.objects.create( | ||||
|             name="test_invalid", | ||||
|         ) | ||||
|         request = PolicyRequest(get_anonymous_user()) | ||||
|         result: PolicyResult = policy.passes(request) | ||||
|         self.assertFalse(result.passing) | ||||
|         self.assertEqual(result.messages[0], "Password not set in context") | ||||
|  | ||||
|     def test_false(self): | ||||
|         """Failing password case""" | ||||
|         policy = HaveIBeenPwendPolicy.objects.create( | ||||
|  | ||||
| @ -50,6 +50,7 @@ class PasswordPolicy(Policy): | ||||
|                 field=self.password_field, | ||||
|                 fields=request.context.keys(), | ||||
|             ) | ||||
|             return PolicyResult(False, _("Password not set in context")) | ||||
|         password = request.context[self.password_field] | ||||
|  | ||||
|         filter_regex = [] | ||||
|  | ||||
| @ -9,6 +9,21 @@ from authentik.policies.types import PolicyRequest, PolicyResult | ||||
| class TestPasswordPolicy(TestCase): | ||||
|     """Test Password Policy""" | ||||
|  | ||||
|     def test_invalid(self): | ||||
|         """Test without password""" | ||||
|         policy = PasswordPolicy.objects.create( | ||||
|             name="test_invalid", | ||||
|             amount_uppercase=1, | ||||
|             amount_lowercase=2, | ||||
|             amount_symbols=3, | ||||
|             length_min=24, | ||||
|             error_message="test message", | ||||
|         ) | ||||
|         request = PolicyRequest(get_anonymous_user()) | ||||
|         result: PolicyResult = policy.passes(request) | ||||
|         self.assertFalse(result.passing) | ||||
|         self.assertEqual(result.messages[0], "Password not set in context") | ||||
|  | ||||
|     def test_false(self): | ||||
|         """Failing password case""" | ||||
|         policy = PasswordPolicy.objects.create( | ||||
|  | ||||
							
								
								
									
										0
									
								
								authentik/providers/oauth2/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								authentik/providers/oauth2/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										46
									
								
								authentik/providers/oauth2/tests/test_views_authorize.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								authentik/providers/oauth2/tests/test_views_authorize.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| """Test authorize view""" | ||||
| from django.test import RequestFactory, TestCase | ||||
|  | ||||
| from authentik.flows.models import Flow | ||||
| from authentik.providers.oauth2.errors import ( | ||||
|     AuthorizeError, | ||||
|     ClientIdError, | ||||
|     RedirectUriError, | ||||
| ) | ||||
| from authentik.providers.oauth2.models import OAuth2Provider | ||||
| from authentik.providers.oauth2.views.authorize import OAuthAuthorizationParams | ||||
|  | ||||
|  | ||||
| class TestViewsAuthorize(TestCase): | ||||
|     """Test authorize view""" | ||||
|  | ||||
|     def setUp(self) -> None: | ||||
|         super().setUp() | ||||
|         self.factory = RequestFactory() | ||||
|  | ||||
|     def test_invalid_grant_type(self): | ||||
|         """Test with invalid grant type""" | ||||
|         with self.assertRaises(AuthorizeError): | ||||
|             request = self.factory.get("/", data={"response_type": "invalid"}) | ||||
|             OAuthAuthorizationParams.from_request(request) | ||||
|  | ||||
|     def test_invalid_client_id(self): | ||||
|         """Test invalid client ID""" | ||||
|         with self.assertRaises(ClientIdError): | ||||
|             request = self.factory.get( | ||||
|                 "/", data={"response_type": "code", "client_id": "invalid"} | ||||
|             ) | ||||
|             OAuthAuthorizationParams.from_request(request) | ||||
|  | ||||
|     def test_missing_redirect_uri(self): | ||||
|         """test missing redirect URI""" | ||||
|         OAuth2Provider.objects.create( | ||||
|             name="test", | ||||
|             client_id="test", | ||||
|             authorization_flow=Flow.objects.first(), | ||||
|         ) | ||||
|         with self.assertRaises(RedirectUriError): | ||||
|             request = self.factory.get( | ||||
|                 "/", data={"response_type": "code", "client_id": "test"} | ||||
|             ) | ||||
|             OAuthAuthorizationParams.from_request(request) | ||||
| @ -139,7 +139,7 @@ class OAuthAuthorizationParams: | ||||
|         is_open_id = SCOPE_OPENID in self.scope | ||||
|  | ||||
|         # Redirect URI validation. | ||||
|         if is_open_id and not self.redirect_uri: | ||||
|         if not self.redirect_uri: | ||||
|             LOGGER.warning("Missing redirect uri.") | ||||
|             raise RedirectUriError() | ||||
|         if self.redirect_uri.lower() not in [ | ||||
|  | ||||
							
								
								
									
										84
									
								
								authentik/providers/saml/tests/test_schema.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								authentik/providers/saml/tests/test_schema.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,84 @@ | ||||
| """Test Requests and Responses against schema""" | ||||
| from base64 import b64encode | ||||
|  | ||||
| from django.contrib.sessions.middleware import SessionMiddleware | ||||
| from django.test import RequestFactory, TestCase | ||||
| from guardian.utils import get_anonymous_user | ||||
| from lxml import etree  # nosec | ||||
|  | ||||
| from authentik.crypto.models import CertificateKeyPair | ||||
| from authentik.flows.models import Flow | ||||
| from authentik.providers.saml.models import SAMLPropertyMapping, SAMLProvider | ||||
| from authentik.providers.saml.processors.assertion import AssertionProcessor | ||||
| from authentik.providers.saml.processors.request_parser import AuthNRequestParser | ||||
| from authentik.providers.saml.tests.test_auth_n_request import dummy_get_response | ||||
| from authentik.sources.saml.models import SAMLSource | ||||
| from authentik.sources.saml.processors.request import RequestProcessor | ||||
|  | ||||
|  | ||||
| class TestSchema(TestCase): | ||||
|     """Test Requests and Responses against schema""" | ||||
|  | ||||
|     def setUp(self): | ||||
|         cert = CertificateKeyPair.objects.first() | ||||
|         self.provider: SAMLProvider = SAMLProvider.objects.create( | ||||
|             authorization_flow=Flow.objects.get( | ||||
|                 slug="default-provider-authorization-implicit-consent" | ||||
|             ), | ||||
|             acs_url="http://testserver/source/saml/provider/acs/", | ||||
|             signing_kp=cert, | ||||
|             verification_kp=cert, | ||||
|         ) | ||||
|         self.provider.property_mappings.set(SAMLPropertyMapping.objects.all()) | ||||
|         self.provider.save() | ||||
|         self.source = SAMLSource.objects.create( | ||||
|             slug="provider", | ||||
|             issuer="authentik", | ||||
|             signing_kp=cert, | ||||
|         ) | ||||
|         self.factory = RequestFactory() | ||||
|  | ||||
|     def test_request_schema(self): | ||||
|         """Test generated AuthNRequest against Schema""" | ||||
|         http_request = self.factory.get("/") | ||||
|  | ||||
|         middleware = SessionMiddleware(dummy_get_response) | ||||
|         middleware.process_request(http_request) | ||||
|         http_request.session.save() | ||||
|  | ||||
|         # First create an AuthNRequest | ||||
|         request_proc = RequestProcessor(self.source, http_request, "test_state") | ||||
|         request = request_proc.build_auth_n() | ||||
|  | ||||
|         metadata = etree.fromstring(request)  # nosec | ||||
|  | ||||
|         schema = etree.XMLSchema( | ||||
|             etree.parse("xml/saml-schema-protocol-2.0.xsd") | ||||
|         )  # nosec | ||||
|         self.assertTrue(schema.validate(metadata)) | ||||
|  | ||||
|     def test_response_schema(self): | ||||
|         """Test generated AuthNRequest against Schema""" | ||||
|         http_request = self.factory.get("/") | ||||
|         http_request.user = get_anonymous_user() | ||||
|  | ||||
|         middleware = SessionMiddleware(dummy_get_response) | ||||
|         middleware.process_request(http_request) | ||||
|         http_request.session.save() | ||||
|  | ||||
|         # First create an AuthNRequest | ||||
|         request_proc = RequestProcessor(self.source, http_request, "test_state") | ||||
|         request = request_proc.build_auth_n() | ||||
|  | ||||
|         # To get an assertion we need a parsed request (parsed by provider) | ||||
|         parsed_request = AuthNRequestParser(self.provider).parse( | ||||
|             b64encode(request.encode()).decode(), "test_state" | ||||
|         ) | ||||
|         # Now create a response and convert it to string (provider) | ||||
|         response_proc = AssertionProcessor(self.provider, http_request, parsed_request) | ||||
|         response = response_proc.build_response() | ||||
|  | ||||
|         metadata = etree.fromstring(response)  # nosec | ||||
|  | ||||
|         schema = etree.XMLSchema(etree.parse("xml/saml-schema-protocol-2.0.xsd")) | ||||
|         self.assertTrue(schema.validate(metadata)) | ||||
| @ -1,15 +1,6 @@ | ||||
| """Small helper functions""" | ||||
| import uuid | ||||
|  | ||||
| from django.http import HttpRequest, HttpResponse | ||||
| from django.shortcuts import render | ||||
| from django.template.context import Context | ||||
|  | ||||
|  | ||||
| def render_xml(request: HttpRequest, template: str, ctx: Context) -> HttpResponse: | ||||
|     """Render template with content_type application/xml""" | ||||
|     return render(request, template, context=ctx, content_type="application/xml") | ||||
|  | ||||
|  | ||||
| def get_random_id() -> str: | ||||
|     """Random hex id""" | ||||
|  | ||||
| @ -32,3 +32,10 @@ class TestRecovery(TestCase): | ||||
|             reverse("authentik_recovery:use-token", kwargs={"key": token.key}) | ||||
|         ) | ||||
|         self.assertEqual(int(self.client.session["_auth_user_id"]), token.user.pk) | ||||
|  | ||||
|     def test_recovery_view_invalid(self): | ||||
|         """Test recovery view with invalid token""" | ||||
|         response = self.client.get( | ||||
|             reverse("authentik_recovery:use-token", kwargs={"key": "abc"}) | ||||
|         ) | ||||
|         self.assertEqual(response.status_code, 404) | ||||
|  | ||||
| @ -105,7 +105,16 @@ class ASGILogger: | ||||
|             # https://code.djangoproject.com/ticket/31508 | ||||
|             # https://github.com/encode/uvicorn/issues/266 | ||||
|             return | ||||
|         await self.app(scope, receive, send_hooked) | ||||
|         try: | ||||
|             await self.app(scope, receive, send_hooked) | ||||
|         except TypeError as exc: | ||||
|             # https://github.com/encode/uvicorn/issues/244 | ||||
|             if exc.args == ( | ||||
|                 "An asyncio.Future, a coroutine or an awaitable is required", | ||||
|             ): | ||||
|                 pass | ||||
|             else: | ||||
|                 raise exc | ||||
|  | ||||
|     def _get_ip(self) -> str: | ||||
|         client_ip = None | ||||
|  | ||||
| @ -4,7 +4,7 @@ from django.conf import settings | ||||
| from authentik.lib.config import CONFIG | ||||
|  | ||||
|  | ||||
| class PytestTestRunner: | ||||
| class PytestTestRunner:  # pragma: no cover | ||||
|     """Runs pytest to discover and run tests.""" | ||||
|  | ||||
|     def __init__(self, verbosity=1, failfast=False, keepdb=False, **_): | ||||
|  | ||||
							
								
								
									
										0
									
								
								authentik/sources/oauth/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								authentik/sources/oauth/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										41
									
								
								authentik/sources/oauth/tests/test_type_discord.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								authentik/sources/oauth/tests/test_type_discord.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| """Discord Type tests""" | ||||
| from django.test import TestCase | ||||
|  | ||||
| from authentik.sources.oauth.models import OAuthSource, UserOAuthSourceConnection | ||||
| from authentik.sources.oauth.types.discord import DiscordOAuth2Callback | ||||
|  | ||||
| # https://discord.com/developers/docs/resources/user#user-object | ||||
| DISCORD_USER = { | ||||
|     "id": "80351110224678912", | ||||
|     "username": "Nelly", | ||||
|     "discriminator": "1337", | ||||
|     "avatar": "8342729096ea3675442027381ff50dfe", | ||||
|     "verified": True, | ||||
|     "email": "nelly@discord.com", | ||||
|     "flags": 64, | ||||
|     "premium_type": 1, | ||||
|     "public_flags": 64, | ||||
| } | ||||
|  | ||||
|  | ||||
| class TestTypeGitHub(TestCase): | ||||
|     """OAuth Source tests""" | ||||
|  | ||||
|     def setUp(self): | ||||
|         self.source = OAuthSource.objects.create( | ||||
|             name="test", | ||||
|             slug="test", | ||||
|             provider_type="openid-connect", | ||||
|             authorization_url="", | ||||
|             profile_url="", | ||||
|             consumer_key="", | ||||
|         ) | ||||
|  | ||||
|     def test_enroll_context(self): | ||||
|         """Test GitHub Enrollment context""" | ||||
|         ak_context = DiscordOAuth2Callback().get_user_enroll_context( | ||||
|             self.source, UserOAuthSourceConnection(), DISCORD_USER | ||||
|         ) | ||||
|         self.assertEqual(ak_context["username"], DISCORD_USER["username"]) | ||||
|         self.assertEqual(ak_context["email"], DISCORD_USER["email"]) | ||||
|         self.assertEqual(ak_context["name"], DISCORD_USER["username"]) | ||||
							
								
								
									
										71
									
								
								authentik/sources/oauth/tests/test_type_github.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								authentik/sources/oauth/tests/test_type_github.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | ||||
| """GitHub Type tests""" | ||||
| from django.test import TestCase | ||||
|  | ||||
| from authentik.sources.oauth.models import OAuthSource, UserOAuthSourceConnection | ||||
| from authentik.sources.oauth.types.github import GitHubOAuth2Callback | ||||
|  | ||||
| # https://developer.github.com/v3/users/#get-the-authenticated-user | ||||
| GITHUB_USER = { | ||||
|     "login": "octocat", | ||||
|     "id": 1, | ||||
|     "node_id": "MDQ6VXNlcjE=", | ||||
|     "avatar_url": "https://github.com/images/error/octocat_happy.gif", | ||||
|     "gravatar_id": "", | ||||
|     "url": "https://api.github.com/users/octocat", | ||||
|     "html_url": "https://github.com/octocat", | ||||
|     "followers_url": "https://api.github.com/users/octocat/followers", | ||||
|     "following_url": "https://api.github.com/users/octocat/following{/other_user}", | ||||
|     "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", | ||||
|     "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", | ||||
|     "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", | ||||
|     "organizations_url": "https://api.github.com/users/octocat/orgs", | ||||
|     "repos_url": "https://api.github.com/users/octocat/repos", | ||||
|     "events_url": "https://api.github.com/users/octocat/events{/privacy}", | ||||
|     "received_events_url": "https://api.github.com/users/octocat/received_events", | ||||
|     "type": "User", | ||||
|     "site_admin": False, | ||||
|     "name": "monalisa octocat", | ||||
|     "company": "GitHub", | ||||
|     "blog": "https://github.com/blog", | ||||
|     "location": "San Francisco", | ||||
|     "email": "octocat@github.com", | ||||
|     "hireable": False, | ||||
|     "bio": "There once was...", | ||||
|     "twitter_username": "monatheoctocat", | ||||
|     "public_repos": 2, | ||||
|     "public_gists": 1, | ||||
|     "followers": 20, | ||||
|     "following": 0, | ||||
|     "created_at": "2008-01-14T04:33:35Z", | ||||
|     "updated_at": "2008-01-14T04:33:35Z", | ||||
|     "private_gists": 81, | ||||
|     "total_private_repos": 100, | ||||
|     "owned_private_repos": 100, | ||||
|     "disk_usage": 10000, | ||||
|     "collaborators": 8, | ||||
|     "two_factor_authentication": True, | ||||
|     "plan": {"name": "Medium", "space": 400, "private_repos": 20, "collaborators": 0}, | ||||
| } | ||||
|  | ||||
|  | ||||
| class TestTypeGitHub(TestCase): | ||||
|     """OAuth Source tests""" | ||||
|  | ||||
|     def setUp(self): | ||||
|         self.source = OAuthSource.objects.create( | ||||
|             name="test", | ||||
|             slug="test", | ||||
|             provider_type="openid-connect", | ||||
|             authorization_url="", | ||||
|             profile_url="", | ||||
|             consumer_key="", | ||||
|         ) | ||||
|  | ||||
|     def test_enroll_context(self): | ||||
|         """Test GitHub Enrollment context""" | ||||
|         ak_context = GitHubOAuth2Callback().get_user_enroll_context( | ||||
|             self.source, UserOAuthSourceConnection(), GITHUB_USER | ||||
|         ) | ||||
|         self.assertEqual(ak_context["username"], GITHUB_USER["login"]) | ||||
|         self.assertEqual(ak_context["email"], GITHUB_USER["email"]) | ||||
|         self.assertEqual(ak_context["name"], GITHUB_USER["name"]) | ||||
							
								
								
									
										112
									
								
								authentik/sources/oauth/tests/test_type_twitter.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								authentik/sources/oauth/tests/test_type_twitter.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,112 @@ | ||||
| """Twitter Type tests""" | ||||
| from django.test import Client, TestCase | ||||
|  | ||||
| from authentik.sources.oauth.models import OAuthSource, UserOAuthSourceConnection | ||||
| from authentik.sources.oauth.types.twitter import TwitterOAuthCallback | ||||
|  | ||||
| # https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/manage-account-settings/ \ | ||||
| # api-reference/get-account-verify_credentials | ||||
| TWITTER_USER = { | ||||
|     "contributors_enabled": True, | ||||
|     "created_at": "Sat May 09 17:58:22 +0000 2009", | ||||
|     "default_profile": False, | ||||
|     "default_profile_image": False, | ||||
|     "description": "I taught your phone that thing you like.", | ||||
|     "favourites_count": 588, | ||||
|     "follow_request_sent": None, | ||||
|     "followers_count": 10625, | ||||
|     "following": None, | ||||
|     "friends_count": 1181, | ||||
|     "geo_enabled": True, | ||||
|     "id": 38895958, | ||||
|     "id_str": "38895958", | ||||
|     "is_translator": False, | ||||
|     "lang": "en", | ||||
|     "listed_count": 190, | ||||
|     "location": "San Francisco", | ||||
|     "name": "Sean Cook", | ||||
|     "notifications": None, | ||||
|     "profile_background_color": "1A1B1F", | ||||
|     "profile_background_image_url": "", | ||||
|     "profile_background_image_url_https": "", | ||||
|     "profile_background_tile": True, | ||||
|     "profile_image_url": "", | ||||
|     "profile_image_url_https": "", | ||||
|     "profile_link_color": "2FC2EF", | ||||
|     "profile_sidebar_border_color": "181A1E", | ||||
|     "profile_sidebar_fill_color": "252429", | ||||
|     "profile_text_color": "666666", | ||||
|     "profile_use_background_image": True, | ||||
|     "protected": False, | ||||
|     "screen_name": "theSeanCook", | ||||
|     "show_all_inline_media": True, | ||||
|     "status": { | ||||
|         "contributors": None, | ||||
|         "coordinates": {"coordinates": [-122.45037293, 37.76484123], "type": "Point"}, | ||||
|         "created_at": "Tue Aug 28 05:44:24 +0000 2012", | ||||
|         "favorited": False, | ||||
|         "geo": {"coordinates": [37.76484123, -122.45037293], "type": "Point"}, | ||||
|         "id": 240323931419062272, | ||||
|         "id_str": "240323931419062272", | ||||
|         "in_reply_to_screen_name": "messl", | ||||
|         "in_reply_to_status_id": 240316959173009410, | ||||
|         "in_reply_to_status_id_str": "240316959173009410", | ||||
|         "in_reply_to_user_id": 18707866, | ||||
|         "in_reply_to_user_id_str": "18707866", | ||||
|         "place": { | ||||
|             "attributes": {}, | ||||
|             "bounding_box": { | ||||
|                 "coordinates": [ | ||||
|                     [ | ||||
|                         [-122.45778216, 37.75932999], | ||||
|                         [-122.44248216, 37.75932999], | ||||
|                         [-122.44248216, 37.76752899], | ||||
|                         [-122.45778216, 37.76752899], | ||||
|                     ] | ||||
|                 ], | ||||
|                 "type": "Polygon", | ||||
|             }, | ||||
|             "country": "United States", | ||||
|             "country_code": "US", | ||||
|             "full_name": "Ashbury Heights, San Francisco", | ||||
|             "id": "866269c983527d5a", | ||||
|             "name": "Ashbury Heights", | ||||
|             "place_type": "neighborhood", | ||||
|             "url": "http://api.twitter.com/1/geo/id/866269c983527d5a.json", | ||||
|         }, | ||||
|         "retweet_count": 0, | ||||
|         "retweeted": False, | ||||
|         "source": "Twitter for  iPhone", | ||||
|         "text": "@messl congrats! So happy for all 3 of you.", | ||||
|         "truncated": False, | ||||
|     }, | ||||
|     "statuses_count": 2609, | ||||
|     "time_zone": "Pacific Time (US & Canada)", | ||||
|     "url": None, | ||||
|     "utc_offset": -28800, | ||||
|     "verified": False, | ||||
| } | ||||
|  | ||||
|  | ||||
| class TestTypeGitHub(TestCase): | ||||
|     """OAuth Source tests""" | ||||
|  | ||||
|     def setUp(self): | ||||
|         self.client = Client() | ||||
|         self.source = OAuthSource.objects.create( | ||||
|             name="test", | ||||
|             slug="test", | ||||
|             provider_type="openid-connect", | ||||
|             authorization_url="", | ||||
|             profile_url="", | ||||
|             consumer_key="", | ||||
|         ) | ||||
|  | ||||
|     def test_enroll_context(self): | ||||
|         """Test Twitter Enrollment context""" | ||||
|         ak_context = TwitterOAuthCallback().get_user_enroll_context( | ||||
|             self.source, UserOAuthSourceConnection(), TWITTER_USER | ||||
|         ) | ||||
|         self.assertEqual(ak_context["username"], TWITTER_USER["screen_name"]) | ||||
|         self.assertEqual(ak_context["email"], TWITTER_USER.get("email", None)) | ||||
|         self.assertEqual(ak_context["name"], TWITTER_USER["name"]) | ||||
| @ -1,15 +1,14 @@ | ||||
| """OAuth Source tests""" | ||||
| from django.shortcuts import reverse | ||||
| from django.test import Client, TestCase | ||||
| from django.test import TestCase | ||||
| 
 | ||||
| from authentik.sources.oauth.models import OAuthSource | ||||
| 
 | ||||
| 
 | ||||
| class OAuthSourceTests(TestCase): | ||||
| class TestOAuthSource(TestCase): | ||||
|     """OAuth Source tests""" | ||||
| 
 | ||||
|     def setUp(self): | ||||
|         self.client = Client() | ||||
|         self.source = OAuthSource.objects.create( | ||||
|             name="test", | ||||
|             slug="test", | ||||
| @ -11,7 +11,7 @@ from authentik.sources.oauth.views.redirect import OAuthRedirect | ||||
| class DiscordOAuthRedirect(OAuthRedirect): | ||||
|     """Discord OAuth2 Redirect""" | ||||
|  | ||||
|     def get_additional_parameters(self, source): | ||||
|     def get_additional_parameters(self, source):  # pragma: no cover | ||||
|         return { | ||||
|             "scope": "email identify", | ||||
|         } | ||||
|  | ||||
| @ -14,7 +14,7 @@ from authentik.sources.oauth.views.redirect import OAuthRedirect | ||||
| class FacebookOAuthRedirect(OAuthRedirect): | ||||
|     """Facebook OAuth2 Redirect""" | ||||
|  | ||||
|     def get_additional_parameters(self, source): | ||||
|     def get_additional_parameters(self, source):  # pragma: no cover | ||||
|         return { | ||||
|             "scope": "email", | ||||
|         } | ||||
|  | ||||
| @ -11,7 +11,7 @@ from authentik.sources.oauth.views.redirect import OAuthRedirect | ||||
| class GoogleOAuthRedirect(OAuthRedirect): | ||||
|     """Google OAuth2 Redirect""" | ||||
|  | ||||
|     def get_additional_parameters(self, source): | ||||
|     def get_additional_parameters(self, source):  # pragma: no cover | ||||
|         return { | ||||
|             "scope": "email profile", | ||||
|         } | ||||
|  | ||||
| @ -11,7 +11,7 @@ from authentik.sources.oauth.views.redirect import OAuthRedirect | ||||
| class OpenIDConnectOAuthRedirect(OAuthRedirect): | ||||
|     """OpenIDConnect OAuth2 Redirect""" | ||||
|  | ||||
|     def get_additional_parameters(self, source: OAuthSource): | ||||
|     def get_additional_parameters(self, source: OAuthSource):  # pragma: no cover | ||||
|         return { | ||||
|             "scope": "openid email profile", | ||||
|         } | ||||
|  | ||||
| @ -14,7 +14,7 @@ from authentik.sources.oauth.views.redirect import OAuthRedirect | ||||
| class RedditOAuthRedirect(OAuthRedirect): | ||||
|     """Reddit OAuth2 Redirect""" | ||||
|  | ||||
|     def get_additional_parameters(self, source): | ||||
|     def get_additional_parameters(self, source):  # pragma: no cover | ||||
|         return { | ||||
|             "scope": "identity", | ||||
|             "duration": "permanent", | ||||
|  | ||||
| @ -18,6 +18,6 @@ class TwitterOAuthCallback(OAuthCallback): | ||||
|     ) -> Dict[str, Any]: | ||||
|         return { | ||||
|             "username": info.get("screen_name"), | ||||
|             "email": info.get("email"), | ||||
|             "email": info.get("email", None), | ||||
|             "name": info.get("name"), | ||||
|         } | ||||
|  | ||||
| @ -1,26 +0,0 @@ | ||||
| """SAML Source tests""" | ||||
| from defusedxml import ElementTree | ||||
| from django.test import RequestFactory, TestCase | ||||
|  | ||||
| from authentik.crypto.models import CertificateKeyPair | ||||
| from authentik.sources.saml.models import SAMLSource | ||||
| from authentik.sources.saml.processors.metadata import MetadataProcessor | ||||
|  | ||||
|  | ||||
| class TestMetadataProcessor(TestCase): | ||||
|     """Test MetadataProcessor""" | ||||
|  | ||||
|     def setUp(self): | ||||
|         self.source = SAMLSource.objects.create( | ||||
|             slug="provider", | ||||
|             issuer="authentik", | ||||
|             signing_kp=CertificateKeyPair.objects.first(), | ||||
|         ) | ||||
|         self.factory = RequestFactory() | ||||
|  | ||||
|     def test_metadata(self): | ||||
|         """Test Metadata generation being valid""" | ||||
|         request = self.factory.get("/") | ||||
|         xml = MetadataProcessor(self.source, request).build_entity_descriptor() | ||||
|         metadata = ElementTree.fromstring(xml) | ||||
|         self.assertEqual(metadata.attrib["entityID"], "authentik") | ||||
							
								
								
									
										0
									
								
								authentik/sources/saml/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								authentik/sources/saml/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										55
									
								
								authentik/sources/saml/tests/test_metadata.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								authentik/sources/saml/tests/test_metadata.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | ||||
| """SAML Source tests""" | ||||
| from defusedxml import ElementTree | ||||
| from django.test import RequestFactory, TestCase | ||||
| from lxml import etree  # nosec | ||||
|  | ||||
| from authentik.crypto.models import CertificateKeyPair | ||||
| from authentik.sources.saml.models import SAMLSource | ||||
| from authentik.sources.saml.processors.metadata import MetadataProcessor | ||||
|  | ||||
|  | ||||
| class TestMetadataProcessor(TestCase): | ||||
|     """Test MetadataProcessor""" | ||||
|  | ||||
|     def setUp(self): | ||||
|         self.factory = RequestFactory() | ||||
|  | ||||
|     def test_metadata_schema(self): | ||||
|         """Test Metadata generation being valid""" | ||||
|         source = SAMLSource.objects.create( | ||||
|             slug="provider", | ||||
|             issuer="authentik", | ||||
|             signing_kp=CertificateKeyPair.objects.first(), | ||||
|         ) | ||||
|         request = self.factory.get("/") | ||||
|         xml = MetadataProcessor(source, request).build_entity_descriptor() | ||||
|         metadata = etree.fromstring(xml)  # nosec | ||||
|  | ||||
|         schema = etree.XMLSchema( | ||||
|             etree.parse("xml/saml-schema-metadata-2.0.xsd") | ||||
|         )  # nosec | ||||
|         self.assertTrue(schema.validate(metadata)) | ||||
|  | ||||
|     def test_metadata(self): | ||||
|         """Test Metadata generation being valid""" | ||||
|         source = SAMLSource.objects.create( | ||||
|             slug="provider", | ||||
|             issuer="authentik", | ||||
|             signing_kp=CertificateKeyPair.objects.first(), | ||||
|         ) | ||||
|         request = self.factory.get("/") | ||||
|         xml = MetadataProcessor(source, request).build_entity_descriptor() | ||||
|         metadata = ElementTree.fromstring(xml) | ||||
|         self.assertEqual(metadata.attrib["entityID"], "authentik") | ||||
|  | ||||
|     def test_metadata_without_signautre(self): | ||||
|         """Test Metadata generation being valid""" | ||||
|         source = SAMLSource.objects.create( | ||||
|             slug="provider", | ||||
|             issuer="authentik", | ||||
|             # signing_kp=CertificateKeyPair.objects.first(), | ||||
|         ) | ||||
|         request = self.factory.get("/") | ||||
|         xml = MetadataProcessor(source, request).build_entity_descriptor() | ||||
|         metadata = ElementTree.fromstring(xml) | ||||
|         self.assertEqual(metadata.attrib["entityID"], "authentik") | ||||
| @ -87,6 +87,7 @@ class TestUserWriteStage(TestCase): | ||||
|             "username": "test-user-new", | ||||
|             "password": new_password, | ||||
|             "attribute_some-custom-attribute": "test", | ||||
|             "some_ignored_attribute": "bar", | ||||
|         } | ||||
|         session = self.client.session | ||||
|         session[SESSION_KEY_PLAN] = plan | ||||
| @ -109,6 +110,7 @@ class TestUserWriteStage(TestCase): | ||||
|         self.assertTrue(user_qs.exists()) | ||||
|         self.assertTrue(user_qs.first().check_password(new_password)) | ||||
|         self.assertEqual(user_qs.first().attributes["some-custom-attribute"], "test") | ||||
|         self.assertNotIn("some_ignored_attribute", user_qs.first().attributes) | ||||
|  | ||||
|     @patch( | ||||
|         "authentik.flows.views.to_stage_response", | ||||
|  | ||||
| @ -19,7 +19,7 @@ services: | ||||
|     networks: | ||||
|       - internal | ||||
|   server: | ||||
|     image: beryju/authentik:${AUTHENTIK_TAG:-0.13.0-rc3} | ||||
|     image: beryju/authentik:${AUTHENTIK_TAG:-0.13.0-rc4} | ||||
|     command: server | ||||
|     environment: | ||||
|       AUTHENTIK_REDIS__HOST: redis | ||||
| @ -42,7 +42,7 @@ services: | ||||
|     env_file: | ||||
|       - .env | ||||
|   worker: | ||||
|     image: beryju/authentik:${AUTHENTIK_TAG:-0.13.0-rc3} | ||||
|     image: beryju/authentik:${AUTHENTIK_TAG:-0.13.0-rc4} | ||||
|     command: worker | ||||
|     networks: | ||||
|       - internal | ||||
| @ -56,7 +56,7 @@ services: | ||||
|     env_file: | ||||
|       - .env | ||||
|   static: | ||||
|     image: beryju/authentik-static:${AUTHENTIK_TAG:-0.13.0-rc3} | ||||
|     image: beryju/authentik-static:${AUTHENTIK_TAG:-0.13.0-rc4} | ||||
|     networks: | ||||
|       - internal | ||||
|     labels: | ||||
|  | ||||
| @ -4,7 +4,7 @@ name: authentik | ||||
| home: https://goauthentik.io | ||||
| sources: | ||||
|   - https://github.com/BeryJu/authentik | ||||
| version: "0.13.0-rc3" | ||||
| version: "0.13.0-rc4" | ||||
| icon: https://raw.githubusercontent.com/BeryJu/authentik/master/web/icons/icon.svg | ||||
| dependencies: | ||||
|   - name: postgresql | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
| |-----------------------------------|-------------------------|-------------| | ||||
| | image.name                        | beryju/authentik         | Image used to run the authentik server and worker | | ||||
| | image.name_static                 | beryju/authentik-static  | Image used to run the authentik static server (CSS and JS Files) | | ||||
| | image.tag                         | 0.13.0-rc3              | Image tag | | ||||
| | image.tag                         | 0.13.0-rc4              | Image tag | | ||||
| | image.pullPolicy                  | IfNotPresent            | Image Pull Policy used for all deployments | | ||||
| | serverReplicas                    | 1                       | Replicas for the Server deployment | | ||||
| | workerReplicas                    | 1                       | Replicas for the Worker deployment | | ||||
|  | ||||
| @ -5,7 +5,7 @@ image: | ||||
|   name: beryju/authentik | ||||
|   name_static: beryju/authentik-static | ||||
|   name_outposts: beryju/authentik # Prefix used for Outpost deployments, Outpost type and version is appended | ||||
|   tag: 0.13.0-rc3 | ||||
|   tag: 0.13.0-rc4 | ||||
|   pullPolicy: IfNotPresent | ||||
|  | ||||
| serverReplicas: 1 | ||||
|  | ||||
| @ -1,3 +1,3 @@ | ||||
| package pkg | ||||
|  | ||||
| const VERSION = "0.13.0-rc3" | ||||
| const VERSION = "0.13.0-rc4" | ||||
|  | ||||
| @ -7087,6 +7087,9 @@ definitions: | ||||
|         type: boolean | ||||
|       url: | ||||
|         title: Url | ||||
|         description: Can be in the format of 'unix://<path>' when connecting to a | ||||
|           local docker daemon, or 'https://<hostname>:2376' when connecting to a remote | ||||
|           system. | ||||
|         type: string | ||||
|         minLength: 1 | ||||
|       tls_verification: | ||||
|  | ||||
							
								
								
									
										95
									
								
								tests/integration/test_outpost_docker.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								tests/integration/test_outpost_docker.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,95 @@ | ||||
| """outpost tests""" | ||||
| from shutil import rmtree | ||||
| from tempfile import mkdtemp | ||||
| from time import sleep | ||||
|  | ||||
| from django.test import TestCase | ||||
| from docker import DockerClient, from_env | ||||
| from docker.models.containers import Container | ||||
| from docker.types.healthcheck import Healthcheck | ||||
|  | ||||
| from authentik.crypto.models import CertificateKeyPair | ||||
| from authentik.flows.models import Flow | ||||
| from authentik.outposts.apps import AuthentikOutpostConfig | ||||
| from authentik.outposts.controllers.docker import DockerController | ||||
| from authentik.outposts.models import DockerServiceConnection, Outpost, OutpostType | ||||
| from authentik.providers.proxy.models import ProxyProvider | ||||
|  | ||||
|  | ||||
| class OutpostDockerTests(TestCase): | ||||
|     """Test Docker Controllers""" | ||||
|  | ||||
|     def _start_container(self, ssl_folder: str) -> Container: | ||||
|         client: DockerClient = from_env() | ||||
|         container = client.containers.run( | ||||
|             image="docker.beryju.org/proxy/library/docker:dind", | ||||
|             detach=True, | ||||
|             network_mode="host", | ||||
|             remove=True, | ||||
|             privileged=True, | ||||
|             healthcheck=Healthcheck( | ||||
|                 test=["CMD", "docker", "info"], | ||||
|                 interval=5 * 100 * 1000000, | ||||
|                 start_period=5 * 100 * 1000000, | ||||
|             ), | ||||
|             environment={"DOCKER_TLS_CERTDIR": "/ssl"}, | ||||
|             volumes={ | ||||
|                 f"{ssl_folder}/": { | ||||
|                     "bind": "/ssl", | ||||
|                 } | ||||
|             }, | ||||
|         ) | ||||
|         while True: | ||||
|             container.reload() | ||||
|             status = container.attrs.get("State", {}).get("Health", {}).get("Status") | ||||
|             if status == "healthy": | ||||
|                 return container | ||||
|             sleep(1) | ||||
|  | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|         self.ssl_folder = mkdtemp() | ||||
|         self.container = self._start_container(self.ssl_folder) | ||||
|         # Ensure that local connection have been created | ||||
|         AuthentikOutpostConfig.init_local_connection() | ||||
|         self.provider: ProxyProvider = ProxyProvider.objects.create( | ||||
|             name="test", | ||||
|             internal_host="http://localhost", | ||||
|             external_host="http://localhost", | ||||
|             authorization_flow=Flow.objects.first(), | ||||
|         ) | ||||
|         authentication_kp = CertificateKeyPair.objects.create( | ||||
|             name="docker-authentication", | ||||
|             certificate_data=open(f"{self.ssl_folder}/client/cert.pem").read(), | ||||
|             key_data=open(f"{self.ssl_folder}/client/key.pem").read(), | ||||
|         ) | ||||
|         verification_kp = CertificateKeyPair.objects.create( | ||||
|             name="docker-verification", | ||||
|             certificate_data=open(f"{self.ssl_folder}/client/ca.pem").read(), | ||||
|         ) | ||||
|         self.service_connection = DockerServiceConnection.objects.create( | ||||
|             url="https://localhost:2376", | ||||
|             tls_verification=verification_kp, | ||||
|             tls_authentication=authentication_kp, | ||||
|         ) | ||||
|         self.outpost: Outpost = Outpost.objects.create( | ||||
|             name="test", | ||||
|             type=OutpostType.PROXY, | ||||
|             service_connection=self.service_connection, | ||||
|         ) | ||||
|         self.outpost.providers.add(self.provider) | ||||
|         self.outpost.save() | ||||
|  | ||||
|     def tearDown(self) -> None: | ||||
|         super().tearDown() | ||||
|         self.container.kill() | ||||
|         try: | ||||
|             rmtree(self.ssl_folder) | ||||
|         except PermissionError: | ||||
|             pass | ||||
|  | ||||
|     def test_docker_controller(self): | ||||
|         """test that deployment requires update""" | ||||
|         controller = DockerController(self.outpost, self.service_connection) | ||||
|         controller.up() | ||||
|         controller.down() | ||||
| @ -8,3 +8,4 @@ FROM nginx | ||||
|  | ||||
| COPY --from=npm-builder /static/robots.txt /usr/share/nginx/html/robots.txt | ||||
| COPY --from=npm-builder /static/dist/ /usr/share/nginx/html/static/dist/ | ||||
| COPY --from=npm-builder /static/authentik/ /usr/share/nginx/html/static/authentik/ | ||||
|  | ||||
| @ -154,6 +154,9 @@ select[multiple] { | ||||
|         background-color: var(--ak-dark-background-light); | ||||
|         color: var(--ak-dark-foreground); | ||||
|     } | ||||
|     .pf-c-form-control[readonly] { | ||||
|         background-color: var(--ak-dark-background-light); | ||||
|     } | ||||
|     .pf-c-button.pf-m-control { | ||||
|         --pf-c-button--after--BorderColor: var(--ak-dark-background-lighter) var(--ak-dark-background-lighter) var(--pf-c-button--m-control--after--BorderBottomColor) var(--ak-dark-background-lighter); | ||||
|         background-color: var(--ak-dark-background-light); | ||||
|  | ||||
| @ -28,4 +28,4 @@ export const ColorStyles = css` | ||||
|         background-color: var(--pf-global--danger-color--100); | ||||
|     } | ||||
| `; | ||||
| export const VERSION = "0.13.0-rc3"; | ||||
| export const VERSION = "0.13.0-rc4"; | ||||
|  | ||||
| @ -15,7 +15,7 @@ Download the latest `docker-compose.yml` from [here](https://raw.githubuserconte | ||||
|  | ||||
| To optionally enable error-reporting, run `echo AUTHENTIK_ERROR_REPORTING__ENABLED=true >> .env` | ||||
|  | ||||
| To optionally deploy a different version run `echo AUTHENTIK_TAG=0.13.0-rc3 >> .env` | ||||
| To optionally deploy a different version run `echo AUTHENTIK_TAG=0.13.0-rc4 >> .env` | ||||
|  | ||||
| If this is a fresh authentik install run the following commands to generate a password: | ||||
|  | ||||
|  | ||||
| @ -22,7 +22,7 @@ image: | ||||
|     name: beryju/authentik | ||||
|     name_static: beryju/authentik-static | ||||
|     name_outposts: beryju/authentik # Prefix used for Outpost deployments, Outpost type and version is appended | ||||
|     tag: 0.13.0-rc3 | ||||
|     tag: 0.13.0-rc4 | ||||
|  | ||||
| serverReplicas: 1 | ||||
| workerReplicas: 1 | ||||
|  | ||||
| @ -12,7 +12,8 @@ After a long back and forth, we've finally switched to a more permanent name. Wh | ||||
|     In this initial release, this brings features such as a refresh button, a generally better User experience due to shorter loading times | ||||
|     and fewer visual context changes. | ||||
|  | ||||
| - The web interface now has a darkmode, which is enabled automatically based on your Operating system. | ||||
| - The web interface now has a darkmode, which is enabled automatically based on your Operating system darkmode. | ||||
| - Application Icons can now be uploaded directly to authentik, rather than just being loaded from a URL | ||||
|  | ||||
| ## Smaller changes | ||||
|  | ||||
|  | ||||
							
								
								
									
										283
									
								
								xml/saml-schema-assertion-2.0.xsd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										283
									
								
								xml/saml-schema-assertion-2.0.xsd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,283 @@ | ||||
| <?xml version="1.0" encoding="US-ASCII"?> | ||||
| <schema | ||||
|     targetNamespace="urn:oasis:names:tc:SAML:2.0:assertion" | ||||
|     xmlns="http://www.w3.org/2001/XMLSchema" | ||||
|     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" | ||||
|     xmlns:ds="http://www.w3.org/2000/09/xmldsig#" | ||||
|     xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" | ||||
|     elementFormDefault="unqualified" | ||||
|     attributeFormDefault="unqualified" | ||||
|     blockDefault="substitution" | ||||
|     version="2.0"> | ||||
|     <import namespace="http://www.w3.org/2000/09/xmldsig#" | ||||
|         schemaLocation="xmldsig-core-schema.xsd"/> | ||||
|     <import namespace="http://www.w3.org/2001/04/xmlenc#" | ||||
|         schemaLocation="xenc-schema.xsd"/> | ||||
|     <annotation> | ||||
|         <documentation> | ||||
|             Document identifier: saml-schema-assertion-2.0 | ||||
|             Location: http://docs.oasis-open.org/security/saml/v2.0/ | ||||
|             Revision history: | ||||
|             V1.0 (November, 2002): | ||||
|               Initial Standard Schema. | ||||
|             V1.1 (September, 2003): | ||||
|               Updates within the same V1.0 namespace. | ||||
|             V2.0 (March, 2005): | ||||
|               New assertion schema for SAML V2.0 namespace. | ||||
|         </documentation> | ||||
|     </annotation> | ||||
|     <attributeGroup name="IDNameQualifiers"> | ||||
|         <attribute name="NameQualifier" type="string" use="optional"/> | ||||
|         <attribute name="SPNameQualifier" type="string" use="optional"/> | ||||
|     </attributeGroup> | ||||
|     <element name="BaseID" type="saml:BaseIDAbstractType"/> | ||||
|     <complexType name="BaseIDAbstractType" abstract="true"> | ||||
|         <attributeGroup ref="saml:IDNameQualifiers"/> | ||||
|     </complexType> | ||||
|     <element name="NameID" type="saml:NameIDType"/> | ||||
|     <complexType name="NameIDType"> | ||||
|         <simpleContent> | ||||
|             <extension base="string"> | ||||
|                 <attributeGroup ref="saml:IDNameQualifiers"/> | ||||
|                 <attribute name="Format" type="anyURI" use="optional"/> | ||||
|                 <attribute name="SPProvidedID" type="string" use="optional"/> | ||||
|             </extension> | ||||
|         </simpleContent> | ||||
|     </complexType> | ||||
|     <complexType name="EncryptedElementType"> | ||||
|         <sequence> | ||||
|             <element ref="xenc:EncryptedData"/> | ||||
|             <element ref="xenc:EncryptedKey" minOccurs="0" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|     </complexType> | ||||
|     <element name="EncryptedID" type="saml:EncryptedElementType"/> | ||||
|     <element name="Issuer" type="saml:NameIDType"/> | ||||
|     <element name="AssertionIDRef" type="NCName"/> | ||||
|     <element name="AssertionURIRef" type="anyURI"/> | ||||
|     <element name="Assertion" type="saml:AssertionType"/> | ||||
|     <complexType name="AssertionType"> | ||||
|         <sequence> | ||||
|             <element ref="saml:Issuer"/> | ||||
|             <element ref="ds:Signature" minOccurs="0"/> | ||||
|             <element ref="saml:Subject" minOccurs="0"/> | ||||
|             <element ref="saml:Conditions" minOccurs="0"/> | ||||
|             <element ref="saml:Advice" minOccurs="0"/> | ||||
|             <choice minOccurs="0" maxOccurs="unbounded"> | ||||
|                 <element ref="saml:Statement"/> | ||||
|                 <element ref="saml:AuthnStatement"/> | ||||
|                 <element ref="saml:AuthzDecisionStatement"/> | ||||
|                 <element ref="saml:AttributeStatement"/> | ||||
|             </choice> | ||||
|         </sequence> | ||||
|         <attribute name="Version" type="string" use="required"/> | ||||
|         <attribute name="ID" type="ID" use="required"/> | ||||
|         <attribute name="IssueInstant" type="dateTime" use="required"/> | ||||
|     </complexType> | ||||
|     <element name="Subject" type="saml:SubjectType"/> | ||||
|     <complexType name="SubjectType"> | ||||
|         <choice> | ||||
|             <sequence> | ||||
|                 <choice> | ||||
|                     <element ref="saml:BaseID"/> | ||||
|                     <element ref="saml:NameID"/> | ||||
|                     <element ref="saml:EncryptedID"/> | ||||
|                 </choice> | ||||
|                 <element ref="saml:SubjectConfirmation" minOccurs="0" maxOccurs="unbounded"/> | ||||
|             </sequence> | ||||
|             <element ref="saml:SubjectConfirmation" maxOccurs="unbounded"/> | ||||
|         </choice> | ||||
|     </complexType> | ||||
|     <element name="SubjectConfirmation" type="saml:SubjectConfirmationType"/> | ||||
|     <complexType name="SubjectConfirmationType"> | ||||
|         <sequence> | ||||
|             <choice minOccurs="0"> | ||||
|                 <element ref="saml:BaseID"/> | ||||
|                 <element ref="saml:NameID"/> | ||||
|                 <element ref="saml:EncryptedID"/> | ||||
|             </choice> | ||||
|             <element ref="saml:SubjectConfirmationData" minOccurs="0"/> | ||||
|         </sequence> | ||||
|         <attribute name="Method" type="anyURI" use="required"/> | ||||
|     </complexType> | ||||
|     <element name="SubjectConfirmationData" type="saml:SubjectConfirmationDataType"/> | ||||
|     <complexType name="SubjectConfirmationDataType" mixed="true"> | ||||
|         <complexContent> | ||||
|             <restriction base="anyType"> | ||||
|                 <sequence> | ||||
|                     <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                 </sequence> | ||||
|                 <attribute name="NotBefore" type="dateTime" use="optional"/> | ||||
|                 <attribute name="NotOnOrAfter" type="dateTime" use="optional"/> | ||||
|                 <attribute name="Recipient" type="anyURI" use="optional"/> | ||||
|                 <attribute name="InResponseTo" type="NCName" use="optional"/> | ||||
|                 <attribute name="Address" type="string" use="optional"/> | ||||
|                 <anyAttribute namespace="##other" processContents="lax"/> | ||||
|             </restriction> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <complexType name="KeyInfoConfirmationDataType" mixed="false"> | ||||
|         <complexContent> | ||||
|             <restriction base="saml:SubjectConfirmationDataType"> | ||||
|                 <sequence> | ||||
|                     <element ref="ds:KeyInfo" maxOccurs="unbounded"/> | ||||
|                 </sequence> | ||||
|             </restriction> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="Conditions" type="saml:ConditionsType"/> | ||||
|     <complexType name="ConditionsType"> | ||||
|         <choice minOccurs="0" maxOccurs="unbounded"> | ||||
|             <element ref="saml:Condition"/> | ||||
|             <element ref="saml:AudienceRestriction"/> | ||||
|             <element ref="saml:OneTimeUse"/> | ||||
|             <element ref="saml:ProxyRestriction"/> | ||||
|         </choice> | ||||
|         <attribute name="NotBefore" type="dateTime" use="optional"/> | ||||
|         <attribute name="NotOnOrAfter" type="dateTime" use="optional"/> | ||||
|     </complexType> | ||||
|     <element name="Condition" type="saml:ConditionAbstractType"/> | ||||
|     <complexType name="ConditionAbstractType" abstract="true"/> | ||||
|     <element name="AudienceRestriction" type="saml:AudienceRestrictionType"/> | ||||
|     <complexType name="AudienceRestrictionType"> | ||||
|         <complexContent> | ||||
|             <extension base="saml:ConditionAbstractType"> | ||||
|                 <sequence> | ||||
|                     <element ref="saml:Audience" maxOccurs="unbounded"/> | ||||
|                 </sequence> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="Audience" type="anyURI"/> | ||||
|     <element name="OneTimeUse" type="saml:OneTimeUseType" /> | ||||
|     <complexType name="OneTimeUseType"> | ||||
|         <complexContent> | ||||
|             <extension base="saml:ConditionAbstractType"/> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="ProxyRestriction" type="saml:ProxyRestrictionType"/> | ||||
|     <complexType name="ProxyRestrictionType"> | ||||
|     <complexContent> | ||||
|         <extension base="saml:ConditionAbstractType"> | ||||
|             <sequence> | ||||
|                 <element ref="saml:Audience" minOccurs="0" maxOccurs="unbounded"/> | ||||
|             </sequence> | ||||
|             <attribute name="Count" type="nonNegativeInteger" use="optional"/> | ||||
|         </extension> | ||||
| 	</complexContent> | ||||
|     </complexType> | ||||
|     <element name="Advice" type="saml:AdviceType"/> | ||||
|     <complexType name="AdviceType"> | ||||
|         <choice minOccurs="0" maxOccurs="unbounded"> | ||||
|             <element ref="saml:AssertionIDRef"/> | ||||
|             <element ref="saml:AssertionURIRef"/> | ||||
|             <element ref="saml:Assertion"/> | ||||
|             <element ref="saml:EncryptedAssertion"/> | ||||
|             <any namespace="##other" processContents="lax"/> | ||||
|         </choice> | ||||
|     </complexType> | ||||
|     <element name="EncryptedAssertion" type="saml:EncryptedElementType"/> | ||||
|     <element name="Statement" type="saml:StatementAbstractType"/> | ||||
|     <complexType name="StatementAbstractType" abstract="true"/> | ||||
|     <element name="AuthnStatement" type="saml:AuthnStatementType"/> | ||||
|     <complexType name="AuthnStatementType"> | ||||
|         <complexContent> | ||||
|             <extension base="saml:StatementAbstractType"> | ||||
|                 <sequence> | ||||
|                     <element ref="saml:SubjectLocality" minOccurs="0"/> | ||||
|                     <element ref="saml:AuthnContext"/> | ||||
|                 </sequence> | ||||
|                 <attribute name="AuthnInstant" type="dateTime" use="required"/> | ||||
|                 <attribute name="SessionIndex" type="string" use="optional"/> | ||||
|                 <attribute name="SessionNotOnOrAfter" type="dateTime" use="optional"/> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="SubjectLocality" type="saml:SubjectLocalityType"/> | ||||
|     <complexType name="SubjectLocalityType"> | ||||
|         <attribute name="Address" type="string" use="optional"/> | ||||
|         <attribute name="DNSName" type="string" use="optional"/> | ||||
|     </complexType> | ||||
|     <element name="AuthnContext" type="saml:AuthnContextType"/> | ||||
|     <complexType name="AuthnContextType"> | ||||
|         <sequence> | ||||
|             <choice> | ||||
|                 <sequence> | ||||
|                     <element ref="saml:AuthnContextClassRef"/> | ||||
|                     <choice minOccurs="0"> | ||||
|                         <element ref="saml:AuthnContextDecl"/> | ||||
|                         <element ref="saml:AuthnContextDeclRef"/> | ||||
|                     </choice> | ||||
|                 </sequence> | ||||
|                 <choice> | ||||
|                     <element ref="saml:AuthnContextDecl"/> | ||||
|                     <element ref="saml:AuthnContextDeclRef"/> | ||||
|                 </choice> | ||||
|             </choice> | ||||
|             <element ref="saml:AuthenticatingAuthority" minOccurs="0" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|     </complexType> | ||||
|     <element name="AuthnContextClassRef" type="anyURI"/> | ||||
|     <element name="AuthnContextDeclRef" type="anyURI"/> | ||||
|     <element name="AuthnContextDecl" type="anyType"/> | ||||
|     <element name="AuthenticatingAuthority" type="anyURI"/> | ||||
|     <element name="AuthzDecisionStatement" type="saml:AuthzDecisionStatementType"/> | ||||
|     <complexType name="AuthzDecisionStatementType"> | ||||
|         <complexContent> | ||||
|             <extension base="saml:StatementAbstractType"> | ||||
|                 <sequence> | ||||
|                     <element ref="saml:Action" maxOccurs="unbounded"/> | ||||
|                     <element ref="saml:Evidence" minOccurs="0"/> | ||||
|                 </sequence> | ||||
|                 <attribute name="Resource" type="anyURI" use="required"/> | ||||
|                 <attribute name="Decision" type="saml:DecisionType" use="required"/> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <simpleType name="DecisionType"> | ||||
|         <restriction base="string"> | ||||
|             <enumeration value="Permit"/> | ||||
|             <enumeration value="Deny"/> | ||||
|             <enumeration value="Indeterminate"/> | ||||
|         </restriction> | ||||
|     </simpleType> | ||||
|     <element name="Action" type="saml:ActionType"/> | ||||
|     <complexType name="ActionType"> | ||||
|         <simpleContent> | ||||
|             <extension base="string"> | ||||
|                 <attribute name="Namespace" type="anyURI" use="required"/> | ||||
|             </extension> | ||||
|         </simpleContent> | ||||
|     </complexType> | ||||
|     <element name="Evidence" type="saml:EvidenceType"/> | ||||
|     <complexType name="EvidenceType"> | ||||
|         <choice maxOccurs="unbounded"> | ||||
|             <element ref="saml:AssertionIDRef"/> | ||||
|             <element ref="saml:AssertionURIRef"/> | ||||
|             <element ref="saml:Assertion"/> | ||||
|             <element ref="saml:EncryptedAssertion"/> | ||||
|         </choice> | ||||
|     </complexType> | ||||
|     <element name="AttributeStatement" type="saml:AttributeStatementType"/> | ||||
|     <complexType name="AttributeStatementType"> | ||||
|         <complexContent> | ||||
|             <extension base="saml:StatementAbstractType"> | ||||
|                 <choice maxOccurs="unbounded"> | ||||
|                     <element ref="saml:Attribute"/> | ||||
|                     <element ref="saml:EncryptedAttribute"/> | ||||
|                 </choice> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="Attribute" type="saml:AttributeType"/> | ||||
|     <complexType name="AttributeType"> | ||||
|         <sequence> | ||||
|             <element ref="saml:AttributeValue" minOccurs="0" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|         <attribute name="Name" type="string" use="required"/> | ||||
|         <attribute name="NameFormat" type="anyURI" use="optional"/> | ||||
|         <attribute name="FriendlyName" type="string" use="optional"/> | ||||
|         <anyAttribute namespace="##other" processContents="lax"/> | ||||
|     </complexType> | ||||
|     <element name="AttributeValue" type="anyType" nillable="true"/> | ||||
|     <element name="EncryptedAttribute" type="saml:EncryptedElementType"/> | ||||
| </schema> | ||||
							
								
								
									
										337
									
								
								xml/saml-schema-metadata-2.0.xsd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										337
									
								
								xml/saml-schema-metadata-2.0.xsd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,337 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <schema | ||||
|     targetNamespace="urn:oasis:names:tc:SAML:2.0:metadata" | ||||
|     xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" | ||||
|     xmlns:ds="http://www.w3.org/2000/09/xmldsig#" | ||||
|     xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" | ||||
|     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" | ||||
|     xmlns="http://www.w3.org/2001/XMLSchema" | ||||
|     elementFormDefault="unqualified" | ||||
|     attributeFormDefault="unqualified" | ||||
|     blockDefault="substitution" | ||||
|     version="2.0"> | ||||
|     <import namespace="http://www.w3.org/2000/09/xmldsig#" | ||||
|         schemaLocation="xmldsig-core-schema.xsd"/> | ||||
|     <import namespace="http://www.w3.org/2001/04/xmlenc#" | ||||
|         schemaLocation="xenc-schema.xsd"/> | ||||
|     <import namespace="urn:oasis:names:tc:SAML:2.0:assertion" | ||||
|         schemaLocation="saml-schema-assertion-2.0.xsd"/> | ||||
|     <import namespace="http://www.w3.org/XML/1998/namespace" | ||||
|         schemaLocation="xml.xsd"/> | ||||
|     <annotation> | ||||
|         <documentation> | ||||
|             Document identifier: saml-schema-metadata-2.0 | ||||
|             Location: http://docs.oasis-open.org/security/saml/v2.0/ | ||||
|             Revision history: | ||||
|               V2.0 (March, 2005): | ||||
|                 Schema for SAML metadata, first published in SAML 2.0. | ||||
|         </documentation> | ||||
|     </annotation> | ||||
|  | ||||
|     <simpleType name="entityIDType"> | ||||
|         <restriction base="anyURI"> | ||||
|             <maxLength value="1024"/> | ||||
|         </restriction> | ||||
|     </simpleType> | ||||
|     <complexType name="localizedNameType"> | ||||
|         <simpleContent> | ||||
|             <extension base="string"> | ||||
|                 <attribute ref="xml:lang" use="required"/> | ||||
|             </extension> | ||||
|         </simpleContent> | ||||
|     </complexType> | ||||
|     <complexType name="localizedURIType"> | ||||
|         <simpleContent> | ||||
|             <extension base="anyURI"> | ||||
|                 <attribute ref="xml:lang" use="required"/> | ||||
|             </extension> | ||||
|         </simpleContent> | ||||
|     </complexType> | ||||
|  | ||||
|     <element name="Extensions" type="md:ExtensionsType"/> | ||||
|     <complexType final="#all" name="ExtensionsType"> | ||||
|         <sequence> | ||||
|             <any namespace="##other" processContents="lax" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|     </complexType> | ||||
|  | ||||
|     <complexType name="EndpointType"> | ||||
|         <sequence> | ||||
|             <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|         <attribute name="Binding" type="anyURI" use="required"/> | ||||
|         <attribute name="Location" type="anyURI" use="required"/> | ||||
|         <attribute name="ResponseLocation" type="anyURI" use="optional"/> | ||||
|         <anyAttribute namespace="##other" processContents="lax"/> | ||||
|     </complexType> | ||||
|  | ||||
|     <complexType name="IndexedEndpointType"> | ||||
|         <complexContent> | ||||
|             <extension base="md:EndpointType"> | ||||
|                 <attribute name="index" type="unsignedShort" use="required"/> | ||||
|                 <attribute name="isDefault" type="boolean" use="optional"/> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|  | ||||
|     <element name="EntitiesDescriptor" type="md:EntitiesDescriptorType"/> | ||||
|     <complexType name="EntitiesDescriptorType"> | ||||
|         <sequence> | ||||
|             <element ref="ds:Signature" minOccurs="0"/> | ||||
|             <element ref="md:Extensions" minOccurs="0"/> | ||||
|             <choice minOccurs="1" maxOccurs="unbounded"> | ||||
|                 <element ref="md:EntityDescriptor"/> | ||||
|                 <element ref="md:EntitiesDescriptor"/> | ||||
|             </choice> | ||||
|         </sequence> | ||||
|         <attribute name="validUntil" type="dateTime" use="optional"/> | ||||
|         <attribute name="cacheDuration" type="duration" use="optional"/> | ||||
|         <attribute name="ID" type="ID" use="optional"/> | ||||
|         <attribute name="Name" type="string" use="optional"/> | ||||
|     </complexType> | ||||
|  | ||||
|     <element name="EntityDescriptor" type="md:EntityDescriptorType"/> | ||||
|     <complexType name="EntityDescriptorType"> | ||||
|         <sequence> | ||||
|             <element ref="ds:Signature" minOccurs="0"/> | ||||
|             <element ref="md:Extensions" minOccurs="0"/> | ||||
|             <choice> | ||||
|                 <choice maxOccurs="unbounded"> | ||||
|                     <element ref="md:RoleDescriptor"/> | ||||
|                     <element ref="md:IDPSSODescriptor"/> | ||||
|                     <element ref="md:SPSSODescriptor"/> | ||||
|                     <element ref="md:AuthnAuthorityDescriptor"/> | ||||
|                     <element ref="md:AttributeAuthorityDescriptor"/> | ||||
|                     <element ref="md:PDPDescriptor"/> | ||||
|                 </choice> | ||||
|                 <element ref="md:AffiliationDescriptor"/> | ||||
|             </choice> | ||||
|             <element ref="md:Organization" minOccurs="0"/> | ||||
|             <element ref="md:ContactPerson" minOccurs="0" maxOccurs="unbounded"/> | ||||
|             <element ref="md:AdditionalMetadataLocation" minOccurs="0" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|         <attribute name="entityID" type="md:entityIDType" use="required"/> | ||||
|         <attribute name="validUntil" type="dateTime" use="optional"/> | ||||
|         <attribute name="cacheDuration" type="duration" use="optional"/> | ||||
|         <attribute name="ID" type="ID" use="optional"/> | ||||
|         <anyAttribute namespace="##other" processContents="lax"/> | ||||
|     </complexType> | ||||
|  | ||||
|     <element name="Organization" type="md:OrganizationType"/> | ||||
|     <complexType name="OrganizationType"> | ||||
|         <sequence> | ||||
|             <element ref="md:Extensions" minOccurs="0"/> | ||||
|             <element ref="md:OrganizationName" maxOccurs="unbounded"/> | ||||
|             <element ref="md:OrganizationDisplayName" maxOccurs="unbounded"/> | ||||
|             <element ref="md:OrganizationURL" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|         <anyAttribute namespace="##other" processContents="lax"/> | ||||
|     </complexType> | ||||
|     <element name="OrganizationName" type="md:localizedNameType"/> | ||||
|     <element name="OrganizationDisplayName" type="md:localizedNameType"/> | ||||
|     <element name="OrganizationURL" type="md:localizedURIType"/> | ||||
|     <element name="ContactPerson" type="md:ContactType"/> | ||||
|     <complexType name="ContactType"> | ||||
|         <sequence> | ||||
|             <element ref="md:Extensions" minOccurs="0"/> | ||||
|             <element ref="md:Company" minOccurs="0"/> | ||||
|             <element ref="md:GivenName" minOccurs="0"/> | ||||
|             <element ref="md:SurName" minOccurs="0"/> | ||||
|             <element ref="md:EmailAddress" minOccurs="0" maxOccurs="unbounded"/> | ||||
|             <element ref="md:TelephoneNumber" minOccurs="0" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|         <attribute name="contactType" type="md:ContactTypeType" use="required"/> | ||||
|         <anyAttribute namespace="##other" processContents="lax"/> | ||||
|     </complexType> | ||||
|     <element name="Company" type="string"/> | ||||
|     <element name="GivenName" type="string"/> | ||||
|     <element name="SurName" type="string"/> | ||||
|     <element name="EmailAddress" type="anyURI"/> | ||||
|     <element name="TelephoneNumber" type="string"/> | ||||
|     <simpleType name="ContactTypeType"> | ||||
|         <restriction base="string"> | ||||
|             <enumeration value="technical"/> | ||||
|             <enumeration value="support"/> | ||||
|             <enumeration value="administrative"/> | ||||
|             <enumeration value="billing"/> | ||||
|             <enumeration value="other"/> | ||||
|         </restriction> | ||||
|     </simpleType> | ||||
|  | ||||
|     <element name="AdditionalMetadataLocation" type="md:AdditionalMetadataLocationType"/> | ||||
|     <complexType name="AdditionalMetadataLocationType"> | ||||
|         <simpleContent> | ||||
|             <extension base="anyURI"> | ||||
|                 <attribute name="namespace" type="anyURI" use="required"/> | ||||
|             </extension> | ||||
|         </simpleContent> | ||||
|     </complexType> | ||||
|  | ||||
|     <element name="RoleDescriptor" type="md:RoleDescriptorType"/> | ||||
|     <complexType name="RoleDescriptorType" abstract="true"> | ||||
|         <sequence> | ||||
|             <element ref="ds:Signature" minOccurs="0"/> | ||||
|             <element ref="md:Extensions" minOccurs="0"/> | ||||
|             <element ref="md:KeyDescriptor" minOccurs="0" maxOccurs="unbounded"/> | ||||
|             <element ref="md:Organization" minOccurs="0"/> | ||||
|             <element ref="md:ContactPerson" minOccurs="0" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|         <attribute name="ID" type="ID" use="optional"/> | ||||
|         <attribute name="validUntil" type="dateTime" use="optional"/> | ||||
|         <attribute name="cacheDuration" type="duration" use="optional"/> | ||||
|         <attribute name="protocolSupportEnumeration" type="md:anyURIListType" use="required"/> | ||||
|         <attribute name="errorURL" type="anyURI" use="optional"/> | ||||
|         <anyAttribute namespace="##other" processContents="lax"/> | ||||
|     </complexType> | ||||
|     <simpleType name="anyURIListType"> | ||||
|         <list itemType="anyURI"/> | ||||
|     </simpleType> | ||||
|  | ||||
|     <element name="KeyDescriptor" type="md:KeyDescriptorType"/> | ||||
|     <complexType name="KeyDescriptorType"> | ||||
|         <sequence> | ||||
|             <element ref="ds:KeyInfo"/> | ||||
|             <element ref="md:EncryptionMethod" minOccurs="0" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|         <attribute name="use" type="md:KeyTypes" use="optional"/> | ||||
|     </complexType> | ||||
|     <simpleType name="KeyTypes"> | ||||
|         <restriction base="string"> | ||||
|             <enumeration value="encryption"/> | ||||
|             <enumeration value="signing"/> | ||||
|         </restriction> | ||||
|     </simpleType> | ||||
|     <element name="EncryptionMethod" type="xenc:EncryptionMethodType"/> | ||||
|  | ||||
|     <complexType name="SSODescriptorType" abstract="true"> | ||||
|         <complexContent> | ||||
|             <extension base="md:RoleDescriptorType"> | ||||
|                 <sequence> | ||||
|                     <element ref="md:ArtifactResolutionService" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:SingleLogoutService" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:ManageNameIDService" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                 </sequence> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="ArtifactResolutionService" type="md:IndexedEndpointType"/> | ||||
|     <element name="SingleLogoutService" type="md:EndpointType"/> | ||||
|     <element name="ManageNameIDService" type="md:EndpointType"/> | ||||
|     <element name="NameIDFormat" type="anyURI"/> | ||||
|  | ||||
|     <element name="IDPSSODescriptor" type="md:IDPSSODescriptorType"/> | ||||
|     <complexType name="IDPSSODescriptorType"> | ||||
|         <complexContent> | ||||
|             <extension base="md:SSODescriptorType"> | ||||
|                 <sequence> | ||||
|                     <element ref="md:SingleSignOnService" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:NameIDMappingService" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:AssertionIDRequestService" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:AttributeProfile" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                     <element ref="saml:Attribute" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                 </sequence> | ||||
|                 <attribute name="WantAuthnRequestsSigned" type="boolean" use="optional"/> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="SingleSignOnService" type="md:EndpointType"/> | ||||
|     <element name="NameIDMappingService" type="md:EndpointType"/> | ||||
|     <element name="AssertionIDRequestService" type="md:EndpointType"/> | ||||
|     <element name="AttributeProfile" type="anyURI"/> | ||||
|  | ||||
|     <element name="SPSSODescriptor" type="md:SPSSODescriptorType"/> | ||||
|     <complexType name="SPSSODescriptorType"> | ||||
|         <complexContent> | ||||
|             <extension base="md:SSODescriptorType"> | ||||
|                 <sequence> | ||||
|                     <element ref="md:AssertionConsumerService" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:AttributeConsumingService" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                 </sequence> | ||||
|                 <attribute name="AuthnRequestsSigned" type="boolean" use="optional"/> | ||||
|                 <attribute name="WantAssertionsSigned" type="boolean" use="optional"/> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="AssertionConsumerService" type="md:IndexedEndpointType"/> | ||||
|     <element name="AttributeConsumingService" type="md:AttributeConsumingServiceType"/> | ||||
|     <complexType name="AttributeConsumingServiceType"> | ||||
|         <sequence> | ||||
|             <element ref="md:ServiceName" maxOccurs="unbounded"/> | ||||
|             <element ref="md:ServiceDescription" minOccurs="0" maxOccurs="unbounded"/> | ||||
|             <element ref="md:RequestedAttribute" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|         <attribute name="index" type="unsignedShort" use="required"/> | ||||
|         <attribute name="isDefault" type="boolean" use="optional"/> | ||||
|     </complexType> | ||||
|     <element name="ServiceName" type="md:localizedNameType"/> | ||||
|     <element name="ServiceDescription" type="md:localizedNameType"/> | ||||
|     <element name="RequestedAttribute" type="md:RequestedAttributeType"/> | ||||
|     <complexType name="RequestedAttributeType"> | ||||
|         <complexContent> | ||||
|             <extension base="saml:AttributeType"> | ||||
|                 <attribute name="isRequired" type="boolean" use="optional"/> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|  | ||||
|     <element name="AuthnAuthorityDescriptor" type="md:AuthnAuthorityDescriptorType"/> | ||||
|     <complexType name="AuthnAuthorityDescriptorType"> | ||||
|         <complexContent> | ||||
|             <extension base="md:RoleDescriptorType"> | ||||
|                 <sequence> | ||||
|                     <element ref="md:AuthnQueryService" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:AssertionIDRequestService" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                 </sequence> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="AuthnQueryService" type="md:EndpointType"/> | ||||
|  | ||||
|     <element name="PDPDescriptor" type="md:PDPDescriptorType"/> | ||||
|     <complexType name="PDPDescriptorType"> | ||||
|         <complexContent> | ||||
|             <extension base="md:RoleDescriptorType"> | ||||
|                 <sequence> | ||||
|                     <element ref="md:AuthzService" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:AssertionIDRequestService" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                 </sequence> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="AuthzService" type="md:EndpointType"/> | ||||
|  | ||||
|     <element name="AttributeAuthorityDescriptor" type="md:AttributeAuthorityDescriptorType"/> | ||||
|     <complexType name="AttributeAuthorityDescriptorType"> | ||||
|         <complexContent> | ||||
|             <extension base="md:RoleDescriptorType"> | ||||
|                 <sequence> | ||||
|                     <element ref="md:AttributeService" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:AssertionIDRequestService" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:NameIDFormat" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                     <element ref="md:AttributeProfile" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                     <element ref="saml:Attribute" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                 </sequence> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="AttributeService" type="md:EndpointType"/> | ||||
|  | ||||
|     <element name="AffiliationDescriptor" type="md:AffiliationDescriptorType"/> | ||||
|     <complexType name="AffiliationDescriptorType"> | ||||
|         <sequence> | ||||
|             <element ref="ds:Signature" minOccurs="0"/> | ||||
|             <element ref="md:Extensions" minOccurs="0"/> | ||||
|             <element ref="md:AffiliateMember" maxOccurs="unbounded"/> | ||||
|             <element ref="md:KeyDescriptor" minOccurs="0" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|         <attribute name="affiliationOwnerID" type="md:entityIDType" use="required"/> | ||||
|         <attribute name="validUntil" type="dateTime" use="optional"/> | ||||
|         <attribute name="cacheDuration" type="duration" use="optional"/> | ||||
|         <attribute name="ID" type="ID" use="optional"/> | ||||
|         <anyAttribute namespace="##other" processContents="lax"/> | ||||
|     </complexType> | ||||
|     <element name="AffiliateMember" type="md:entityIDType"/> | ||||
| </schema> | ||||
							
								
								
									
										302
									
								
								xml/saml-schema-protocol-2.0.xsd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										302
									
								
								xml/saml-schema-protocol-2.0.xsd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,302 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <schema | ||||
|     targetNamespace="urn:oasis:names:tc:SAML:2.0:protocol" | ||||
|     xmlns="http://www.w3.org/2001/XMLSchema" | ||||
|     xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" | ||||
|     xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" | ||||
|     xmlns:ds="http://www.w3.org/2000/09/xmldsig#" | ||||
|     elementFormDefault="unqualified" | ||||
|     attributeFormDefault="unqualified" | ||||
|     blockDefault="substitution" | ||||
|     version="2.0"> | ||||
|     <import namespace="urn:oasis:names:tc:SAML:2.0:assertion" | ||||
|         schemaLocation="saml-schema-assertion-2.0.xsd"/> | ||||
|     <import namespace="http://www.w3.org/2000/09/xmldsig#" | ||||
|         schemaLocation="xmldsig-core-schema.xsd"/> | ||||
|     <annotation> | ||||
|         <documentation> | ||||
|             Document identifier: saml-schema-protocol-2.0 | ||||
|             Location: http://docs.oasis-open.org/security/saml/v2.0/ | ||||
|             Revision history: | ||||
|             V1.0 (November, 2002): | ||||
|               Initial Standard Schema. | ||||
|             V1.1 (September, 2003): | ||||
|               Updates within the same V1.0 namespace. | ||||
|             V2.0 (March, 2005): | ||||
|               New protocol schema based in a SAML V2.0 namespace. | ||||
|      </documentation> | ||||
|     </annotation> | ||||
|     <complexType name="RequestAbstractType" abstract="true"> | ||||
|         <sequence> | ||||
|             <element ref="saml:Issuer" minOccurs="0"/> | ||||
|             <element ref="ds:Signature" minOccurs="0"/> | ||||
|             <element ref="samlp:Extensions" minOccurs="0"/> | ||||
|         </sequence> | ||||
|         <attribute name="ID" type="ID" use="required"/> | ||||
|         <attribute name="Version" type="string" use="required"/> | ||||
|         <attribute name="IssueInstant" type="dateTime" use="required"/> | ||||
|         <attribute name="Destination" type="anyURI" use="optional"/> | ||||
|     	<attribute name="Consent" type="anyURI" use="optional"/> | ||||
|     </complexType> | ||||
|     <element name="Extensions" type="samlp:ExtensionsType"/> | ||||
|     <complexType name="ExtensionsType"> | ||||
|         <sequence> | ||||
|             <any namespace="##other" processContents="lax" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|     </complexType> | ||||
|     <complexType name="StatusResponseType"> | ||||
|     	<sequence> | ||||
|             <element ref="saml:Issuer" minOccurs="0"/> | ||||
|             <element ref="ds:Signature" minOccurs="0"/> | ||||
|             <element ref="samlp:Extensions" minOccurs="0"/> | ||||
|             <element ref="samlp:Status"/> | ||||
|     	</sequence> | ||||
|     	<attribute name="ID" type="ID" use="required"/> | ||||
|     	<attribute name="InResponseTo" type="NCName" use="optional"/> | ||||
|     	<attribute name="Version" type="string" use="required"/> | ||||
|     	<attribute name="IssueInstant" type="dateTime" use="required"/> | ||||
|     	<attribute name="Destination" type="anyURI" use="optional"/> | ||||
|     	<attribute name="Consent" type="anyURI" use="optional"/> | ||||
|     </complexType> | ||||
|     <element name="Status" type="samlp:StatusType"/> | ||||
|     <complexType name="StatusType"> | ||||
|         <sequence> | ||||
|             <element ref="samlp:StatusCode"/> | ||||
|             <element ref="samlp:StatusMessage" minOccurs="0"/> | ||||
|             <element ref="samlp:StatusDetail" minOccurs="0"/> | ||||
|         </sequence> | ||||
|     </complexType> | ||||
|     <element name="StatusCode" type="samlp:StatusCodeType"/> | ||||
|     <complexType name="StatusCodeType"> | ||||
|         <sequence> | ||||
|             <element ref="samlp:StatusCode" minOccurs="0"/> | ||||
|         </sequence> | ||||
|         <attribute name="Value" type="anyURI" use="required"/> | ||||
|     </complexType> | ||||
|     <element name="StatusMessage" type="string"/> | ||||
|     <element name="StatusDetail" type="samlp:StatusDetailType"/> | ||||
|     <complexType name="StatusDetailType"> | ||||
|         <sequence> | ||||
|             <any namespace="##any" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|     </complexType> | ||||
|     <element name="AssertionIDRequest" type="samlp:AssertionIDRequestType"/> | ||||
|     <complexType name="AssertionIDRequestType"> | ||||
|     	<complexContent> | ||||
|             <extension base="samlp:RequestAbstractType"> | ||||
|                 <sequence> | ||||
|                     <element ref="saml:AssertionIDRef" maxOccurs="unbounded"/> | ||||
|                 </sequence> | ||||
|             </extension> | ||||
|     	</complexContent> | ||||
|     </complexType> | ||||
|     <element name="SubjectQuery" type="samlp:SubjectQueryAbstractType"/> | ||||
|     <complexType name="SubjectQueryAbstractType" abstract="true"> | ||||
|     	<complexContent> | ||||
|             <extension base="samlp:RequestAbstractType"> | ||||
|                 <sequence> | ||||
|                     <element ref="saml:Subject"/> | ||||
|                 </sequence> | ||||
|             </extension> | ||||
|     	</complexContent> | ||||
|     </complexType> | ||||
|     <element name="AuthnQuery" type="samlp:AuthnQueryType"/> | ||||
|     <complexType name="AuthnQueryType"> | ||||
|         <complexContent> | ||||
|             <extension base="samlp:SubjectQueryAbstractType"> | ||||
|                 <sequence> | ||||
|                     <element ref="samlp:RequestedAuthnContext" minOccurs="0"/> | ||||
|                 </sequence> | ||||
|                 <attribute name="SessionIndex" type="string" use="optional"/> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="RequestedAuthnContext" type="samlp:RequestedAuthnContextType"/> | ||||
|     <complexType name="RequestedAuthnContextType"> | ||||
|         <choice> | ||||
|             <element ref="saml:AuthnContextClassRef" maxOccurs="unbounded"/> | ||||
|             <element ref="saml:AuthnContextDeclRef" maxOccurs="unbounded"/> | ||||
|         </choice> | ||||
|         <attribute name="Comparison" type="samlp:AuthnContextComparisonType" use="optional"/> | ||||
|     </complexType> | ||||
|     <simpleType name="AuthnContextComparisonType"> | ||||
|         <restriction base="string"> | ||||
|             <enumeration value="exact"/> | ||||
|             <enumeration value="minimum"/> | ||||
|             <enumeration value="maximum"/> | ||||
|             <enumeration value="better"/> | ||||
|         </restriction> | ||||
|     </simpleType> | ||||
|     <element name="AttributeQuery" type="samlp:AttributeQueryType"/> | ||||
|     <complexType name="AttributeQueryType"> | ||||
|         <complexContent> | ||||
|             <extension base="samlp:SubjectQueryAbstractType"> | ||||
|                 <sequence> | ||||
|                     <element ref="saml:Attribute" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                 </sequence> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="AuthzDecisionQuery" type="samlp:AuthzDecisionQueryType"/> | ||||
|     <complexType name="AuthzDecisionQueryType"> | ||||
|         <complexContent> | ||||
|             <extension base="samlp:SubjectQueryAbstractType"> | ||||
|                 <sequence> | ||||
|                     <element ref="saml:Action" maxOccurs="unbounded"/> | ||||
|                     <element ref="saml:Evidence" minOccurs="0"/> | ||||
|                 </sequence> | ||||
|                 <attribute name="Resource" type="anyURI" use="required"/> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="AuthnRequest" type="samlp:AuthnRequestType"/> | ||||
|     <complexType name="AuthnRequestType"> | ||||
|         <complexContent> | ||||
|             <extension base="samlp:RequestAbstractType"> | ||||
|                 <sequence> | ||||
|                     <element ref="saml:Subject" minOccurs="0"/> | ||||
|                     <element ref="samlp:NameIDPolicy" minOccurs="0"/> | ||||
|                     <element ref="saml:Conditions" minOccurs="0"/> | ||||
|                     <element ref="samlp:RequestedAuthnContext" minOccurs="0"/> | ||||
|                     <element ref="samlp:Scoping" minOccurs="0"/> | ||||
|                 </sequence> | ||||
|                 <attribute name="ForceAuthn" type="boolean" use="optional"/> | ||||
|                 <attribute name="IsPassive" type="boolean" use="optional"/> | ||||
|                 <attribute name="ProtocolBinding" type="anyURI" use="optional"/> | ||||
|                 <attribute name="AssertionConsumerServiceIndex" type="unsignedShort" use="optional"/> | ||||
|                 <attribute name="AssertionConsumerServiceURL" type="anyURI" use="optional"/> | ||||
|                 <attribute name="AttributeConsumingServiceIndex" type="unsignedShort" use="optional"/> | ||||
|                 <attribute name="ProviderName" type="string" use="optional"/> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="NameIDPolicy" type="samlp:NameIDPolicyType"/> | ||||
|     <complexType name="NameIDPolicyType"> | ||||
|         <attribute name="Format" type="anyURI" use="optional"/> | ||||
|         <attribute name="SPNameQualifier" type="string" use="optional"/> | ||||
|         <attribute name="AllowCreate" type="boolean" use="optional"/> | ||||
|     </complexType> | ||||
|     <element name="Scoping" type="samlp:ScopingType"/> | ||||
|     <complexType name="ScopingType"> | ||||
|         <sequence> | ||||
|             <element ref="samlp:IDPList" minOccurs="0"/> | ||||
|             <element ref="samlp:RequesterID" minOccurs="0" maxOccurs="unbounded"/> | ||||
|         </sequence> | ||||
|         <attribute name="ProxyCount" type="nonNegativeInteger" use="optional"/> | ||||
|     </complexType> | ||||
|     <element name="RequesterID" type="anyURI"/> | ||||
|     <element name="IDPList" type="samlp:IDPListType"/> | ||||
|     <complexType name="IDPListType"> | ||||
|         <sequence> | ||||
|             <element ref="samlp:IDPEntry" maxOccurs="unbounded"/> | ||||
|             <element ref="samlp:GetComplete" minOccurs="0"/> | ||||
|         </sequence> | ||||
|     </complexType> | ||||
|     <element name="IDPEntry" type="samlp:IDPEntryType"/> | ||||
|     <complexType name="IDPEntryType"> | ||||
|         <attribute name="ProviderID" type="anyURI" use="required"/> | ||||
|         <attribute name="Name" type="string" use="optional"/> | ||||
|         <attribute name="Loc" type="anyURI" use="optional"/> | ||||
|     </complexType> | ||||
|     <element name="GetComplete" type="anyURI"/> | ||||
|     <element name="Response" type="samlp:ResponseType"/> | ||||
|     <complexType name="ResponseType"> | ||||
|     	<complexContent> | ||||
|             <extension base="samlp:StatusResponseType"> | ||||
|                 <choice minOccurs="0" maxOccurs="unbounded"> | ||||
|                     <element ref="saml:Assertion"/> | ||||
|                     <element ref="saml:EncryptedAssertion"/> | ||||
|                 </choice> | ||||
|             </extension> | ||||
|     	</complexContent> | ||||
|     </complexType> | ||||
|     <element name="ArtifactResolve" type="samlp:ArtifactResolveType"/> | ||||
|     <complexType name="ArtifactResolveType"> | ||||
|     	<complexContent> | ||||
|             <extension base="samlp:RequestAbstractType"> | ||||
|                 <sequence> | ||||
|                     <element ref="samlp:Artifact"/> | ||||
|                 </sequence> | ||||
|             </extension> | ||||
|     	</complexContent> | ||||
|     </complexType> | ||||
|     <element name="Artifact" type="string"/> | ||||
|     <element name="ArtifactResponse" type="samlp:ArtifactResponseType"/> | ||||
|     <complexType name="ArtifactResponseType"> | ||||
|     	<complexContent> | ||||
|             <extension base="samlp:StatusResponseType"> | ||||
|                 <sequence> | ||||
|                     <any namespace="##any" processContents="lax" minOccurs="0"/> | ||||
|                 </sequence> | ||||
|             </extension> | ||||
|     	</complexContent> | ||||
|     </complexType> | ||||
|     <element name="ManageNameIDRequest" type="samlp:ManageNameIDRequestType"/> | ||||
|     <complexType name="ManageNameIDRequestType"> | ||||
|     	<complexContent> | ||||
|             <extension base="samlp:RequestAbstractType"> | ||||
|                 <sequence> | ||||
|                     <choice> | ||||
|                         <element ref="saml:NameID"/> | ||||
|                         <element ref="saml:EncryptedID"/> | ||||
|                     </choice> | ||||
|                     <choice> | ||||
|                         <element ref="samlp:NewID"/> | ||||
|                         <element ref="samlp:NewEncryptedID"/> | ||||
|                         <element ref="samlp:Terminate"/> | ||||
|                     </choice> | ||||
|                 </sequence> | ||||
|             </extension> | ||||
|     	</complexContent> | ||||
|     </complexType> | ||||
|     <element name="NewID" type="string"/> | ||||
|     <element name="NewEncryptedID" type="saml:EncryptedElementType"/> | ||||
|     <element name="Terminate" type="samlp:TerminateType"/> | ||||
|     <complexType name="TerminateType"/> | ||||
|     <element name="ManageNameIDResponse" type="samlp:StatusResponseType"/> | ||||
|     <element name="LogoutRequest" type="samlp:LogoutRequestType"/> | ||||
|     <complexType name="LogoutRequestType"> | ||||
|         <complexContent> | ||||
|             <extension base="samlp:RequestAbstractType"> | ||||
|                 <sequence> | ||||
|                     <choice> | ||||
|                         <element ref="saml:BaseID"/> | ||||
|                         <element ref="saml:NameID"/> | ||||
|                         <element ref="saml:EncryptedID"/> | ||||
|                     </choice> | ||||
|                     <element ref="samlp:SessionIndex" minOccurs="0" maxOccurs="unbounded"/> | ||||
|                 </sequence> | ||||
|                 <attribute name="Reason" type="string" use="optional"/> | ||||
|                 <attribute name="NotOnOrAfter" type="dateTime" use="optional"/> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="SessionIndex" type="string"/> | ||||
|     <element name="LogoutResponse" type="samlp:StatusResponseType"/> | ||||
|     <element name="NameIDMappingRequest" type="samlp:NameIDMappingRequestType"/> | ||||
|     <complexType name="NameIDMappingRequestType"> | ||||
|         <complexContent> | ||||
|             <extension base="samlp:RequestAbstractType"> | ||||
|                 <sequence> | ||||
|                     <choice> | ||||
|                         <element ref="saml:BaseID"/> | ||||
|                         <element ref="saml:NameID"/> | ||||
|                         <element ref="saml:EncryptedID"/> | ||||
|                     </choice> | ||||
|                     <element ref="samlp:NameIDPolicy"/> | ||||
|                 </sequence> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
|     <element name="NameIDMappingResponse" type="samlp:NameIDMappingResponseType"/> | ||||
|     <complexType name="NameIDMappingResponseType"> | ||||
|         <complexContent> | ||||
|             <extension base="samlp:StatusResponseType"> | ||||
|                 <choice> | ||||
|                     <element ref="saml:NameID"/> | ||||
|                     <element ref="saml:EncryptedID"/> | ||||
|                 </choice> | ||||
|             </extension> | ||||
|         </complexContent> | ||||
|     </complexType> | ||||
| </schema> | ||||
							
								
								
									
										146
									
								
								xml/xenc-schema.xsd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								xml/xenc-schema.xsd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,146 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!DOCTYPE schema  PUBLIC "-//W3C//DTD XMLSchema 200102//EN" | ||||
|  "http://www.w3.org/2001/XMLSchema.dtd" | ||||
|  [ | ||||
|    <!ATTLIST schema | ||||
|      xmlns:xenc CDATA #FIXED 'http://www.w3.org/2001/04/xmlenc#' | ||||
|      xmlns:ds CDATA #FIXED 'http://www.w3.org/2000/09/xmldsig#'> | ||||
|    <!ENTITY xenc 'http://www.w3.org/2001/04/xmlenc#'> | ||||
|    <!ENTITY % p ''> | ||||
|    <!ENTITY % s ''> | ||||
|   ]> | ||||
|  | ||||
| <schema xmlns='http://www.w3.org/2001/XMLSchema' version='1.0' | ||||
|         xmlns:xenc='http://www.w3.org/2001/04/xmlenc#' | ||||
|         xmlns:ds='http://www.w3.org/2000/09/xmldsig#' | ||||
|         targetNamespace='http://www.w3.org/2001/04/xmlenc#' | ||||
|         elementFormDefault='qualified'> | ||||
|  | ||||
|   <import namespace='http://www.w3.org/2000/09/xmldsig#' | ||||
|           schemaLocation='http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd'/> | ||||
|  | ||||
|   <complexType name='EncryptedType' abstract='true'> | ||||
|     <sequence> | ||||
|       <element name='EncryptionMethod' type='xenc:EncryptionMethodType' | ||||
|        minOccurs='0'/> | ||||
|       <element ref='ds:KeyInfo' minOccurs='0'/> | ||||
|       <element ref='xenc:CipherData'/> | ||||
|       <element ref='xenc:EncryptionProperties' minOccurs='0'/> | ||||
|     </sequence> | ||||
|     <attribute name='Id' type='ID' use='optional'/> | ||||
|     <attribute name='Type' type='anyURI' use='optional'/> | ||||
|     <attribute name='MimeType' type='string' use='optional'/> | ||||
|     <attribute name='Encoding' type='anyURI' use='optional'/> | ||||
|   </complexType> | ||||
|    | ||||
|   <complexType name='EncryptionMethodType' mixed='true'> | ||||
|     <sequence> | ||||
|       <element name='KeySize' minOccurs='0' type='xenc:KeySizeType'/> | ||||
|       <element name='OAEPparams' minOccurs='0' type='base64Binary'/> | ||||
|       <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/> | ||||
|     </sequence> | ||||
|     <attribute name='Algorithm' type='anyURI' use='required'/> | ||||
|   </complexType> | ||||
|  | ||||
|     <simpleType name='KeySizeType'> | ||||
|       <restriction base="integer"/> | ||||
|     </simpleType> | ||||
|  | ||||
|   <element name='CipherData' type='xenc:CipherDataType'/> | ||||
|   <complexType name='CipherDataType'> | ||||
|      <choice> | ||||
|        <element name='CipherValue' type='base64Binary'/> | ||||
|        <element ref='xenc:CipherReference'/> | ||||
|      </choice> | ||||
|     </complexType> | ||||
|  | ||||
|    <element name='CipherReference' type='xenc:CipherReferenceType'/> | ||||
|    <complexType name='CipherReferenceType'> | ||||
|        <choice> | ||||
|          <element name='Transforms' type='xenc:TransformsType' minOccurs='0'/> | ||||
|        </choice> | ||||
|        <attribute name='URI' type='anyURI' use='required'/> | ||||
|    </complexType> | ||||
|  | ||||
|      <complexType name='TransformsType'> | ||||
|        <sequence> | ||||
|          <element ref='ds:Transform' maxOccurs='unbounded'/> | ||||
|        </sequence> | ||||
|      </complexType> | ||||
|  | ||||
|  | ||||
|   <element name='EncryptedData' type='xenc:EncryptedDataType'/> | ||||
|   <complexType name='EncryptedDataType'> | ||||
|     <complexContent> | ||||
|       <extension base='xenc:EncryptedType'> | ||||
|        </extension> | ||||
|     </complexContent> | ||||
|   </complexType> | ||||
|  | ||||
|   <!-- Children of ds:KeyInfo --> | ||||
|  | ||||
|   <element name='EncryptedKey' type='xenc:EncryptedKeyType'/> | ||||
|   <complexType name='EncryptedKeyType'> | ||||
|     <complexContent> | ||||
|       <extension base='xenc:EncryptedType'> | ||||
|         <sequence> | ||||
|           <element ref='xenc:ReferenceList' minOccurs='0'/> | ||||
|           <element name='CarriedKeyName' type='string' minOccurs='0'/> | ||||
|         </sequence> | ||||
|         <attribute name='Recipient' type='string' | ||||
|          use='optional'/> | ||||
|       </extension> | ||||
|     </complexContent> | ||||
|   </complexType> | ||||
|  | ||||
|     <element name="AgreementMethod" type="xenc:AgreementMethodType"/> | ||||
|     <complexType name="AgreementMethodType" mixed="true"> | ||||
|       <sequence> | ||||
|         <element name="KA-Nonce" minOccurs="0" type="base64Binary"/> | ||||
|         <!-- <element ref="ds:DigestMethod" minOccurs="0"/> --> | ||||
|         <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/> | ||||
|         <element name="OriginatorKeyInfo" minOccurs="0" type="ds:KeyInfoType"/> | ||||
|         <element name="RecipientKeyInfo" minOccurs="0" type="ds:KeyInfoType"/> | ||||
|       </sequence> | ||||
|       <attribute name="Algorithm" type="anyURI" use="required"/> | ||||
|     </complexType> | ||||
|  | ||||
|   <!-- End Children of ds:KeyInfo --> | ||||
|  | ||||
|   <element name='ReferenceList'> | ||||
|     <complexType> | ||||
|       <choice minOccurs='1' maxOccurs='unbounded'> | ||||
|         <element name='DataReference' type='xenc:ReferenceType'/> | ||||
|         <element name='KeyReference' type='xenc:ReferenceType'/> | ||||
|       </choice> | ||||
|     </complexType> | ||||
|   </element> | ||||
|  | ||||
|   <complexType name='ReferenceType'> | ||||
|     <sequence> | ||||
|       <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/> | ||||
|     </sequence> | ||||
|     <attribute name='URI' type='anyURI' use='required'/> | ||||
|   </complexType> | ||||
|  | ||||
|  | ||||
|   <element name='EncryptionProperties' type='xenc:EncryptionPropertiesType'/> | ||||
|   <complexType name='EncryptionPropertiesType'> | ||||
|     <sequence> | ||||
|       <element ref='xenc:EncryptionProperty' maxOccurs='unbounded'/> | ||||
|     </sequence> | ||||
|     <attribute name='Id' type='ID' use='optional'/> | ||||
|   </complexType> | ||||
|  | ||||
|     <element name='EncryptionProperty' type='xenc:EncryptionPropertyType'/> | ||||
|     <complexType name='EncryptionPropertyType' mixed='true'> | ||||
|       <choice maxOccurs='unbounded'> | ||||
|         <any namespace='##other' processContents='lax'/> | ||||
|       </choice> | ||||
|       <attribute name='Target' type='anyURI' use='optional'/> | ||||
|       <attribute name='Id' type='ID' use='optional'/> | ||||
|       <anyAttribute namespace="http://www.w3.org/XML/1998/namespace"/> | ||||
|     </complexType> | ||||
|  | ||||
| </schema> | ||||
|  | ||||
							
								
								
									
										287
									
								
								xml/xml.xsd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										287
									
								
								xml/xml.xsd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,287 @@ | ||||
| <?xml version='1.0'?> | ||||
| <?xml-stylesheet href="../2008/09/xsd.xsl" type="text/xsl"?> | ||||
| <xs:schema targetNamespace="http://www.w3.org/XML/1998/namespace"  | ||||
|   xmlns:xs="http://www.w3.org/2001/XMLSchema"  | ||||
|   xmlns   ="http://www.w3.org/1999/xhtml" | ||||
|   xml:lang="en"> | ||||
|  | ||||
|  <xs:annotation> | ||||
|   <xs:documentation> | ||||
|    <div> | ||||
|     <h1>About the XML namespace</h1> | ||||
|  | ||||
|     <div class="bodytext"> | ||||
|      <p> | ||||
|       This schema document describes the XML namespace, in a form | ||||
|       suitable for import by other schema documents. | ||||
|      </p> | ||||
|      <p> | ||||
|       See <a href="http://www.w3.org/XML/1998/namespace.html"> | ||||
|       http://www.w3.org/XML/1998/namespace.html</a> and | ||||
|       <a href="http://www.w3.org/TR/REC-xml"> | ||||
|       http://www.w3.org/TR/REC-xml</a> for information  | ||||
|       about this namespace. | ||||
|      </p> | ||||
|      <p> | ||||
|       Note that local names in this namespace are intended to be | ||||
|       defined only by the World Wide Web Consortium or its subgroups. | ||||
|       The names currently defined in this namespace are listed below. | ||||
|       They should not be used with conflicting semantics by any Working | ||||
|       Group, specification, or document instance. | ||||
|      </p> | ||||
|      <p>    | ||||
|       See further below in this document for more information about <a | ||||
|       href="#usage">how to refer to this schema document from your own | ||||
|       XSD schema documents</a> and about <a href="#nsversioning">the | ||||
|       namespace-versioning policy governing this schema document</a>. | ||||
|      </p> | ||||
|     </div> | ||||
|    </div> | ||||
|   </xs:documentation> | ||||
|  </xs:annotation> | ||||
|  | ||||
|  <xs:attribute name="lang"> | ||||
|   <xs:annotation> | ||||
|    <xs:documentation> | ||||
|     <div> | ||||
|       | ||||
|       <h3>lang (as an attribute name)</h3> | ||||
|       <p> | ||||
|        denotes an attribute whose value | ||||
|        is a language code for the natural language of the content of | ||||
|        any element; its value is inherited.  This name is reserved | ||||
|        by virtue of its definition in the XML specification.</p> | ||||
|       | ||||
|     </div> | ||||
|     <div> | ||||
|      <h4>Notes</h4> | ||||
|      <p> | ||||
|       Attempting to install the relevant ISO 2- and 3-letter | ||||
|       codes as the enumerated possible values is probably never | ||||
|       going to be a realistic possibility.   | ||||
|      </p> | ||||
|      <p> | ||||
|       See BCP 47 at <a href="http://www.rfc-editor.org/rfc/bcp/bcp47.txt"> | ||||
|        http://www.rfc-editor.org/rfc/bcp/bcp47.txt</a> | ||||
|       and the IANA language subtag registry at | ||||
|       <a href="http://www.iana.org/assignments/language-subtag-registry"> | ||||
|        http://www.iana.org/assignments/language-subtag-registry</a> | ||||
|       for further information. | ||||
|      </p> | ||||
|      <p> | ||||
|       The union allows for the 'un-declaration' of xml:lang with | ||||
|       the empty string. | ||||
|      </p> | ||||
|     </div> | ||||
|    </xs:documentation> | ||||
|   </xs:annotation> | ||||
|   <xs:simpleType> | ||||
|    <xs:union memberTypes="xs:language"> | ||||
|     <xs:simpleType>     | ||||
|      <xs:restriction base="xs:string"> | ||||
|       <xs:enumeration value=""/> | ||||
|      </xs:restriction> | ||||
|     </xs:simpleType> | ||||
|    </xs:union> | ||||
|   </xs:simpleType> | ||||
|  </xs:attribute> | ||||
|  | ||||
|  <xs:attribute name="space"> | ||||
|   <xs:annotation> | ||||
|    <xs:documentation> | ||||
|     <div> | ||||
|       | ||||
|       <h3>space (as an attribute name)</h3> | ||||
|       <p> | ||||
|        denotes an attribute whose | ||||
|        value is a keyword indicating what whitespace processing | ||||
|        discipline is intended for the content of the element; its | ||||
|        value is inherited.  This name is reserved by virtue of its | ||||
|        definition in the XML specification.</p> | ||||
|       | ||||
|     </div> | ||||
|    </xs:documentation> | ||||
|   </xs:annotation> | ||||
|   <xs:simpleType> | ||||
|    <xs:restriction base="xs:NCName"> | ||||
|     <xs:enumeration value="default"/> | ||||
|     <xs:enumeration value="preserve"/> | ||||
|    </xs:restriction> | ||||
|   </xs:simpleType> | ||||
|  </xs:attribute> | ||||
|   | ||||
|  <xs:attribute name="base" type="xs:anyURI"> <xs:annotation> | ||||
|    <xs:documentation> | ||||
|     <div> | ||||
|       | ||||
|       <h3>base (as an attribute name)</h3> | ||||
|       <p> | ||||
|        denotes an attribute whose value | ||||
|        provides a URI to be used as the base for interpreting any | ||||
|        relative URIs in the scope of the element on which it | ||||
|        appears; its value is inherited.  This name is reserved | ||||
|        by virtue of its definition in the XML Base specification.</p> | ||||
|       | ||||
|      <p> | ||||
|       See <a | ||||
|       href="http://www.w3.org/TR/xmlbase/">http://www.w3.org/TR/xmlbase/</a> | ||||
|       for information about this attribute. | ||||
|      </p> | ||||
|     </div> | ||||
|    </xs:documentation> | ||||
|   </xs:annotation> | ||||
|  </xs:attribute> | ||||
|   | ||||
|  <xs:attribute name="id" type="xs:ID"> | ||||
|   <xs:annotation> | ||||
|    <xs:documentation> | ||||
|     <div> | ||||
|       | ||||
|       <h3>id (as an attribute name)</h3>  | ||||
|       <p> | ||||
|        denotes an attribute whose value | ||||
|        should be interpreted as if declared to be of type ID. | ||||
|        This name is reserved by virtue of its definition in the | ||||
|        xml:id specification.</p> | ||||
|       | ||||
|      <p> | ||||
|       See <a | ||||
|       href="http://www.w3.org/TR/xml-id/">http://www.w3.org/TR/xml-id/</a> | ||||
|       for information about this attribute. | ||||
|      </p> | ||||
|     </div> | ||||
|    </xs:documentation> | ||||
|   </xs:annotation> | ||||
|  </xs:attribute> | ||||
|  | ||||
|  <xs:attributeGroup name="specialAttrs"> | ||||
|   <xs:attribute ref="xml:base"/> | ||||
|   <xs:attribute ref="xml:lang"/> | ||||
|   <xs:attribute ref="xml:space"/> | ||||
|   <xs:attribute ref="xml:id"/> | ||||
|  </xs:attributeGroup> | ||||
|  | ||||
|  <xs:annotation> | ||||
|   <xs:documentation> | ||||
|    <div> | ||||
|     | ||||
|     <h3>Father (in any context at all)</h3>  | ||||
|  | ||||
|     <div class="bodytext"> | ||||
|      <p> | ||||
|       denotes Jon Bosak, the chair of  | ||||
|       the original XML Working Group.  This name is reserved by  | ||||
|       the following decision of the W3C XML Plenary and  | ||||
|       XML Coordination groups: | ||||
|      </p> | ||||
|      <blockquote> | ||||
|        <p> | ||||
| 	In appreciation for his vision, leadership and | ||||
| 	dedication the W3C XML Plenary on this 10th day of | ||||
| 	February, 2000, reserves for Jon Bosak in perpetuity | ||||
| 	the XML name "xml:Father". | ||||
|        </p> | ||||
|      </blockquote> | ||||
|     </div> | ||||
|    </div> | ||||
|   </xs:documentation> | ||||
|  </xs:annotation> | ||||
|  | ||||
|  <xs:annotation> | ||||
|   <xs:documentation> | ||||
|    <div xml:id="usage" id="usage"> | ||||
|     <h2><a name="usage">About this schema document</a></h2> | ||||
|  | ||||
|     <div class="bodytext"> | ||||
|      <p> | ||||
|       This schema defines attributes and an attribute group suitable | ||||
|       for use by schemas wishing to allow <code>xml:base</code>, | ||||
|       <code>xml:lang</code>, <code>xml:space</code> or | ||||
|       <code>xml:id</code> attributes on elements they define. | ||||
|      </p> | ||||
|      <p> | ||||
|       To enable this, such a schema must import this schema for | ||||
|       the XML namespace, e.g. as follows: | ||||
|      </p> | ||||
|      <pre> | ||||
|           <schema . . .> | ||||
|            . . . | ||||
|            <import namespace="http://www.w3.org/XML/1998/namespace" | ||||
|                       schemaLocation="http://www.w3.org/2001/xml.xsd"/> | ||||
|      </pre> | ||||
|      <p> | ||||
|       or | ||||
|      </p> | ||||
|      <pre> | ||||
|            <import namespace="http://www.w3.org/XML/1998/namespace" | ||||
|                       schemaLocation="http://www.w3.org/2009/01/xml.xsd"/> | ||||
|      </pre> | ||||
|      <p> | ||||
|       Subsequently, qualified reference to any of the attributes or the | ||||
|       group defined below will have the desired effect, e.g. | ||||
|      </p> | ||||
|      <pre> | ||||
|           <type . . .> | ||||
|            . . . | ||||
|            <attributeGroup ref="xml:specialAttrs"/> | ||||
|      </pre> | ||||
|      <p> | ||||
|       will define a type which will schema-validate an instance element | ||||
|       with any of those attributes. | ||||
|      </p> | ||||
|     </div> | ||||
|    </div> | ||||
|   </xs:documentation> | ||||
|  </xs:annotation> | ||||
|  | ||||
|  <xs:annotation> | ||||
|   <xs:documentation> | ||||
|    <div id="nsversioning" xml:id="nsversioning"> | ||||
|     <h2><a name="nsversioning">Versioning policy for this schema document</a></h2> | ||||
|     <div class="bodytext"> | ||||
|      <p> | ||||
|       In keeping with the XML Schema WG's standard versioning | ||||
|       policy, this schema document will persist at | ||||
|       <a href="http://www.w3.org/2009/01/xml.xsd"> | ||||
|        http://www.w3.org/2009/01/xml.xsd</a>. | ||||
|      </p> | ||||
|      <p> | ||||
|       At the date of issue it can also be found at | ||||
|       <a href="http://www.w3.org/2001/xml.xsd"> | ||||
|        http://www.w3.org/2001/xml.xsd</a>. | ||||
|      </p> | ||||
|      <p> | ||||
|       The schema document at that URI may however change in the future, | ||||
|       in order to remain compatible with the latest version of XML | ||||
|       Schema itself, or with the XML namespace itself.  In other words, | ||||
|       if the XML Schema or XML namespaces change, the version of this | ||||
|       document at <a href="http://www.w3.org/2001/xml.xsd"> | ||||
|        http://www.w3.org/2001/xml.xsd  | ||||
|       </a>  | ||||
|       will change accordingly; the version at  | ||||
|       <a href="http://www.w3.org/2009/01/xml.xsd"> | ||||
|        http://www.w3.org/2009/01/xml.xsd  | ||||
|       </a>  | ||||
|       will not change. | ||||
|      </p> | ||||
|      <p> | ||||
|       Previous dated (and unchanging) versions of this schema  | ||||
|       document are at: | ||||
|      </p> | ||||
|      <ul> | ||||
|       <li><a href="http://www.w3.org/2009/01/xml.xsd"> | ||||
| 	http://www.w3.org/2009/01/xml.xsd</a></li> | ||||
|       <li><a href="http://www.w3.org/2007/08/xml.xsd"> | ||||
| 	http://www.w3.org/2007/08/xml.xsd</a></li> | ||||
|       <li><a href="http://www.w3.org/2004/10/xml.xsd"> | ||||
| 	http://www.w3.org/2004/10/xml.xsd</a></li> | ||||
|       <li><a href="http://www.w3.org/2001/03/xml.xsd"> | ||||
| 	http://www.w3.org/2001/03/xml.xsd</a></li> | ||||
|      </ul> | ||||
|     </div> | ||||
|    </div> | ||||
|   </xs:documentation> | ||||
|  </xs:annotation> | ||||
|  | ||||
| </xs:schema> | ||||
|  | ||||
							
								
								
									
										318
									
								
								xml/xmldsig-core-schema.xsd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										318
									
								
								xml/xmldsig-core-schema.xsd
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,318 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <!DOCTYPE schema | ||||
|   PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd" | ||||
|  [ | ||||
|    <!ATTLIST schema  | ||||
|      xmlns:ds CDATA #FIXED "http://www.w3.org/2000/09/xmldsig#"> | ||||
|    <!ENTITY dsig 'http://www.w3.org/2000/09/xmldsig#'> | ||||
|    <!ENTITY % p ''> | ||||
|    <!ENTITY % s ''> | ||||
|   ]> | ||||
|  | ||||
| <!-- Schema for XML Signatures | ||||
|     http://www.w3.org/2000/09/xmldsig# | ||||
|     $Revision: 1.1 $ on $Date: 2002/02/08 20:32:26 $ by $Author: reagle $ | ||||
|  | ||||
|     Copyright 2001 The Internet Society and W3C (Massachusetts Institute | ||||
|     of Technology, Institut National de Recherche en Informatique et en | ||||
|     Automatique, Keio University). All Rights Reserved. | ||||
|     http://www.w3.org/Consortium/Legal/ | ||||
|  | ||||
|     This document is governed by the W3C Software License [1] as described | ||||
|     in the FAQ [2]. | ||||
|  | ||||
|     [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720 | ||||
|     [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD | ||||
| --> | ||||
|  | ||||
|  | ||||
| <schema xmlns="http://www.w3.org/2001/XMLSchema" | ||||
|         xmlns:ds="http://www.w3.org/2000/09/xmldsig#" | ||||
|         targetNamespace="http://www.w3.org/2000/09/xmldsig#" | ||||
|         version="0.1" elementFormDefault="qualified">  | ||||
|  | ||||
| <!-- Basic Types Defined for Signatures --> | ||||
|  | ||||
| <simpleType name="CryptoBinary"> | ||||
|   <restriction base="base64Binary"> | ||||
|   </restriction> | ||||
| </simpleType> | ||||
|  | ||||
| <!-- Start Signature --> | ||||
|  | ||||
| <element name="Signature" type="ds:SignatureType"/> | ||||
| <complexType name="SignatureType"> | ||||
|   <sequence>  | ||||
|     <element ref="ds:SignedInfo"/>  | ||||
|     <element ref="ds:SignatureValue"/>  | ||||
|     <element ref="ds:KeyInfo" minOccurs="0"/>  | ||||
|     <element ref="ds:Object" minOccurs="0" maxOccurs="unbounded"/>  | ||||
|   </sequence>   | ||||
|   <attribute name="Id" type="ID" use="optional"/> | ||||
| </complexType> | ||||
|  | ||||
|   <element name="SignatureValue" type="ds:SignatureValueType"/>  | ||||
|   <complexType name="SignatureValueType"> | ||||
|     <simpleContent> | ||||
|       <extension base="base64Binary"> | ||||
|         <attribute name="Id" type="ID" use="optional"/> | ||||
|       </extension> | ||||
|     </simpleContent> | ||||
|   </complexType> | ||||
|  | ||||
| <!-- Start SignedInfo --> | ||||
|  | ||||
| <element name="SignedInfo" type="ds:SignedInfoType"/> | ||||
| <complexType name="SignedInfoType"> | ||||
|   <sequence>  | ||||
|     <element ref="ds:CanonicalizationMethod"/>  | ||||
|     <element ref="ds:SignatureMethod"/>  | ||||
|     <element ref="ds:Reference" maxOccurs="unbounded"/>  | ||||
|   </sequence>   | ||||
|   <attribute name="Id" type="ID" use="optional"/>  | ||||
| </complexType> | ||||
|  | ||||
|   <element name="CanonicalizationMethod" type="ds:CanonicalizationMethodType"/>  | ||||
|   <complexType name="CanonicalizationMethodType" mixed="true"> | ||||
|     <sequence> | ||||
|       <any namespace="##any" minOccurs="0" maxOccurs="unbounded"/> | ||||
|       <!-- (0,unbounded) elements from (1,1) namespace --> | ||||
|     </sequence> | ||||
|     <attribute name="Algorithm" type="anyURI" use="required"/>  | ||||
|   </complexType> | ||||
|  | ||||
|   <element name="SignatureMethod" type="ds:SignatureMethodType"/> | ||||
|   <complexType name="SignatureMethodType" mixed="true"> | ||||
|     <sequence> | ||||
|       <element name="HMACOutputLength" minOccurs="0" type="ds:HMACOutputLengthType"/> | ||||
|       <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/> | ||||
|       <!-- (0,unbounded) elements from (1,1) external namespace --> | ||||
|     </sequence> | ||||
|     <attribute name="Algorithm" type="anyURI" use="required"/>  | ||||
|   </complexType> | ||||
|  | ||||
| <!-- Start Reference --> | ||||
|  | ||||
| <element name="Reference" type="ds:ReferenceType"/> | ||||
| <complexType name="ReferenceType"> | ||||
|   <sequence>  | ||||
|     <element ref="ds:Transforms" minOccurs="0"/>  | ||||
|     <element ref="ds:DigestMethod"/>  | ||||
|     <element ref="ds:DigestValue"/>  | ||||
|   </sequence> | ||||
|   <attribute name="Id" type="ID" use="optional"/>  | ||||
|   <attribute name="URI" type="anyURI" use="optional"/>  | ||||
|   <attribute name="Type" type="anyURI" use="optional"/>  | ||||
| </complexType> | ||||
|  | ||||
|   <element name="Transforms" type="ds:TransformsType"/> | ||||
|   <complexType name="TransformsType"> | ||||
|     <sequence> | ||||
|       <element ref="ds:Transform" maxOccurs="unbounded"/>   | ||||
|     </sequence> | ||||
|   </complexType> | ||||
|  | ||||
|   <element name="Transform" type="ds:TransformType"/> | ||||
|   <complexType name="TransformType" mixed="true"> | ||||
|     <choice minOccurs="0" maxOccurs="unbounded">  | ||||
|       <any namespace="##other" processContents="lax"/> | ||||
|       <!-- (1,1) elements from (0,unbounded) namespaces --> | ||||
|       <element name="XPath" type="string"/>  | ||||
|     </choice> | ||||
|     <attribute name="Algorithm" type="anyURI" use="required"/>  | ||||
|   </complexType> | ||||
|  | ||||
| <!-- End Reference --> | ||||
|  | ||||
| <element name="DigestMethod" type="ds:DigestMethodType"/> | ||||
| <complexType name="DigestMethodType" mixed="true">  | ||||
|   <sequence> | ||||
|     <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/> | ||||
|   </sequence>     | ||||
|   <attribute name="Algorithm" type="anyURI" use="required"/>  | ||||
| </complexType> | ||||
|  | ||||
| <element name="DigestValue" type="ds:DigestValueType"/> | ||||
| <simpleType name="DigestValueType"> | ||||
|   <restriction base="base64Binary"/> | ||||
| </simpleType> | ||||
|  | ||||
| <!-- End SignedInfo --> | ||||
|  | ||||
| <!-- Start KeyInfo --> | ||||
|  | ||||
| <element name="KeyInfo" type="ds:KeyInfoType"/>  | ||||
| <complexType name="KeyInfoType" mixed="true"> | ||||
|   <choice maxOccurs="unbounded">      | ||||
|     <element ref="ds:KeyName"/>  | ||||
|     <element ref="ds:KeyValue"/>  | ||||
|     <element ref="ds:RetrievalMethod"/>  | ||||
|     <element ref="ds:X509Data"/>  | ||||
|     <element ref="ds:PGPData"/>  | ||||
|     <element ref="ds:SPKIData"/> | ||||
|     <element ref="ds:MgmtData"/> | ||||
|     <any processContents="lax" namespace="##other"/> | ||||
|     <!-- (1,1) elements from (0,unbounded) namespaces --> | ||||
|   </choice> | ||||
|   <attribute name="Id" type="ID" use="optional"/>  | ||||
| </complexType> | ||||
|  | ||||
|   <element name="KeyName" type="string"/> | ||||
|   <element name="MgmtData" type="string"/> | ||||
|  | ||||
|   <element name="KeyValue" type="ds:KeyValueType"/>  | ||||
|   <complexType name="KeyValueType" mixed="true"> | ||||
|    <choice> | ||||
|      <element ref="ds:DSAKeyValue"/> | ||||
|      <element ref="ds:RSAKeyValue"/> | ||||
|      <any namespace="##other" processContents="lax"/> | ||||
|    </choice> | ||||
|   </complexType> | ||||
|  | ||||
|   <element name="RetrievalMethod" type="ds:RetrievalMethodType"/>  | ||||
|   <complexType name="RetrievalMethodType"> | ||||
|     <sequence> | ||||
|       <element ref="ds:Transforms" minOccurs="0"/>  | ||||
|     </sequence>   | ||||
|     <attribute name="URI" type="anyURI"/> | ||||
|     <attribute name="Type" type="anyURI" use="optional"/> | ||||
|   </complexType> | ||||
|  | ||||
| <!-- Start X509Data --> | ||||
|  | ||||
| <element name="X509Data" type="ds:X509DataType"/>  | ||||
| <complexType name="X509DataType"> | ||||
|   <sequence maxOccurs="unbounded"> | ||||
|     <choice> | ||||
|       <element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/> | ||||
|       <element name="X509SKI" type="base64Binary"/> | ||||
|       <element name="X509SubjectName" type="string"/> | ||||
|       <element name="X509Certificate" type="base64Binary"/> | ||||
|       <element name="X509CRL" type="base64Binary"/> | ||||
|       <any namespace="##other" processContents="lax"/> | ||||
|     </choice> | ||||
|   </sequence> | ||||
| </complexType> | ||||
|  | ||||
| <complexType name="X509IssuerSerialType">  | ||||
|   <sequence>  | ||||
|     <element name="X509IssuerName" type="string"/>  | ||||
|     <element name="X509SerialNumber" type="integer"/>  | ||||
|   </sequence> | ||||
| </complexType> | ||||
|  | ||||
| <!-- End X509Data --> | ||||
|  | ||||
| <!-- Begin PGPData --> | ||||
|  | ||||
| <element name="PGPData" type="ds:PGPDataType"/>  | ||||
| <complexType name="PGPDataType">  | ||||
|   <choice> | ||||
|     <sequence> | ||||
|       <element name="PGPKeyID" type="base64Binary"/>  | ||||
|       <element name="PGPKeyPacket" type="base64Binary" minOccurs="0"/>  | ||||
|       <any namespace="##other" processContents="lax" minOccurs="0" | ||||
|        maxOccurs="unbounded"/> | ||||
|     </sequence> | ||||
|     <sequence> | ||||
|       <element name="PGPKeyPacket" type="base64Binary"/>  | ||||
|       <any namespace="##other" processContents="lax" minOccurs="0" | ||||
|        maxOccurs="unbounded"/> | ||||
|     </sequence> | ||||
|   </choice> | ||||
| </complexType> | ||||
|  | ||||
| <!-- End PGPData --> | ||||
|  | ||||
| <!-- Begin SPKIData --> | ||||
|  | ||||
| <element name="SPKIData" type="ds:SPKIDataType"/>  | ||||
| <complexType name="SPKIDataType"> | ||||
|   <sequence maxOccurs="unbounded"> | ||||
|     <element name="SPKISexp" type="base64Binary"/> | ||||
|     <any namespace="##other" processContents="lax" minOccurs="0"/> | ||||
|   </sequence> | ||||
| </complexType>  | ||||
|  | ||||
| <!-- End SPKIData --> | ||||
|  | ||||
| <!-- End KeyInfo --> | ||||
|  | ||||
| <!-- Start Object (Manifest, SignatureProperty) --> | ||||
|  | ||||
| <element name="Object" type="ds:ObjectType"/>  | ||||
| <complexType name="ObjectType" mixed="true"> | ||||
|   <sequence minOccurs="0" maxOccurs="unbounded"> | ||||
|     <any namespace="##any" processContents="lax"/> | ||||
|   </sequence> | ||||
|   <attribute name="Id" type="ID" use="optional"/>  | ||||
|   <attribute name="MimeType" type="string" use="optional"/> <!-- add a grep facet --> | ||||
|   <attribute name="Encoding" type="anyURI" use="optional"/>  | ||||
| </complexType> | ||||
|  | ||||
| <element name="Manifest" type="ds:ManifestType"/>  | ||||
| <complexType name="ManifestType"> | ||||
|   <sequence> | ||||
|     <element ref="ds:Reference" maxOccurs="unbounded"/>  | ||||
|   </sequence> | ||||
|   <attribute name="Id" type="ID" use="optional"/>  | ||||
| </complexType> | ||||
|  | ||||
| <element name="SignatureProperties" type="ds:SignaturePropertiesType"/>  | ||||
| <complexType name="SignaturePropertiesType"> | ||||
|   <sequence> | ||||
|     <element ref="ds:SignatureProperty" maxOccurs="unbounded"/>  | ||||
|   </sequence> | ||||
|   <attribute name="Id" type="ID" use="optional"/>  | ||||
| </complexType> | ||||
|  | ||||
|    <element name="SignatureProperty" type="ds:SignaturePropertyType"/>  | ||||
|    <complexType name="SignaturePropertyType" mixed="true"> | ||||
|      <choice maxOccurs="unbounded"> | ||||
|        <any namespace="##other" processContents="lax"/> | ||||
|        <!-- (1,1) elements from (1,unbounded) namespaces --> | ||||
|      </choice> | ||||
|      <attribute name="Target" type="anyURI" use="required"/>  | ||||
|      <attribute name="Id" type="ID" use="optional"/>  | ||||
|    </complexType> | ||||
|  | ||||
| <!-- End Object (Manifest, SignatureProperty) --> | ||||
|  | ||||
| <!-- Start Algorithm Parameters --> | ||||
|  | ||||
| <simpleType name="HMACOutputLengthType"> | ||||
|   <restriction base="integer"/> | ||||
| </simpleType> | ||||
|  | ||||
| <!-- Start KeyValue Element-types --> | ||||
|  | ||||
| <element name="DSAKeyValue" type="ds:DSAKeyValueType"/> | ||||
| <complexType name="DSAKeyValueType"> | ||||
|   <sequence> | ||||
|     <sequence minOccurs="0"> | ||||
|       <element name="P" type="ds:CryptoBinary"/> | ||||
|       <element name="Q" type="ds:CryptoBinary"/> | ||||
|     </sequence> | ||||
|     <element name="G" type="ds:CryptoBinary" minOccurs="0"/> | ||||
|     <element name="Y" type="ds:CryptoBinary"/> | ||||
|     <element name="J" type="ds:CryptoBinary" minOccurs="0"/> | ||||
|     <sequence minOccurs="0"> | ||||
|       <element name="Seed" type="ds:CryptoBinary"/> | ||||
|       <element name="PgenCounter" type="ds:CryptoBinary"/> | ||||
|     </sequence> | ||||
|   </sequence> | ||||
| </complexType> | ||||
|  | ||||
| <element name="RSAKeyValue" type="ds:RSAKeyValueType"/> | ||||
| <complexType name="RSAKeyValueType"> | ||||
|   <sequence> | ||||
|     <element name="Modulus" type="ds:CryptoBinary"/>  | ||||
|     <element name="Exponent" type="ds:CryptoBinary"/>  | ||||
|   </sequence> | ||||
| </complexType>  | ||||
|  | ||||
| <!-- End KeyValue Element-types --> | ||||
|  | ||||
| <!-- End Signature --> | ||||
|  | ||||
| </schema> | ||||
		Reference in New Issue
	
	Block a user
	