summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.OpenId/OpenId/Extensions/OpenIdExtensionsInteropHelper.cs
blob: d90dd2aa00d7f2af4204fefe8eb6f3310275dd06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//-----------------------------------------------------------------------
// <copyright file="OpenIdExtensionsInteropHelper.cs" company="Outercurve Foundation">
//     Copyright (c) Outercurve Foundation. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace DotNetOpenAuth.OpenId.Extensions {
	using System;
	using System.Collections.Generic;
	using System.Diagnostics.CodeAnalysis;
	using System.Linq;
	using DotNetOpenAuth.Messaging;
	using DotNetOpenAuth.OpenId.Extensions.AttributeExchange;
	using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
	using DotNetOpenAuth.OpenId.Messages;
	using Validation;

	/// <summary>
	/// A set of methods designed to assist in improving interop across different
	/// OpenID implementations and their extensions.
	/// </summary>
	internal static class OpenIdExtensionsInteropHelper {
		/// <summary>
		/// The gender decoder to translate AX genders to Sreg.
		/// </summary>
		private static GenderEncoder genderEncoder = new GenderEncoder();

		/// <summary>
		/// Gets the gender decoder to translate AX genders to Sreg.
		/// </summary>
		internal static GenderEncoder GenderEncoder {
			get { return genderEncoder; }
		}

		/// <summary>
		/// Splits the AX attribute format flags into individual values for processing.
		/// </summary>
		/// <param name="formats">The formats to split up into individual flags.</param>
		/// <returns>A sequence of individual flags.</returns>
		internal static IEnumerable<AXAttributeFormats> ForEachFormat(AXAttributeFormats formats) {
			if ((formats & AXAttributeFormats.AXSchemaOrg) != 0) {
				yield return AXAttributeFormats.AXSchemaOrg;
			}

			if ((formats & AXAttributeFormats.OpenIdNetSchema) != 0) {
				yield return AXAttributeFormats.OpenIdNetSchema;
			}

			if ((formats & AXAttributeFormats.SchemaOpenIdNet) != 0) {
				yield return AXAttributeFormats.SchemaOpenIdNet;
			}
		}

		/// <summary>
		/// Transforms an AX attribute type URI from the axschema.org format into a given format.
		/// </summary>
		/// <param name="axSchemaOrgFormatTypeUri">The ax schema org format type URI.</param>
		/// <param name="targetFormat">The target format.  Only one flag should be set.</param>
		/// <returns>The AX attribute type URI in the target format.</returns>
		internal static string TransformAXFormat(string axSchemaOrgFormatTypeUri, AXAttributeFormats targetFormat) {
			Requires.NotNullOrEmpty(axSchemaOrgFormatTypeUri, "axSchemaOrgFormatTypeUri");

			switch (targetFormat) {
				case AXAttributeFormats.AXSchemaOrg:
					return axSchemaOrgFormatTypeUri;
				case AXAttributeFormats.SchemaOpenIdNet:
					return axSchemaOrgFormatTypeUri.Replace("axschema.org", "schema.openid.net");
				case AXAttributeFormats.OpenIdNetSchema:
					return axSchemaOrgFormatTypeUri.Replace("axschema.org", "openid.net/schema");
				default:
					throw new ArgumentOutOfRangeException("targetFormat");
			}
		}

		/// <summary>
		/// Detects the AX attribute type URI format from a given sample.
		/// </summary>
		/// <param name="typeURIs">The type URIs to scan for recognized formats.</param>
		/// <returns>The first AX type URI format recognized in the list.</returns>
		internal static AXAttributeFormats DetectAXFormat(IEnumerable<string> typeURIs) {
			Requires.NotNull(typeURIs, "typeURIs");

			if (typeURIs.Any(uri => uri.StartsWith("http://axschema.org/", StringComparison.Ordinal))) {
				return AXAttributeFormats.AXSchemaOrg;
			}

			if (typeURIs.Any(uri => uri.StartsWith("http://schema.openid.net/", StringComparison.Ordinal))) {
				return AXAttributeFormats.SchemaOpenIdNet;
			}

			if (typeURIs.Any(uri => uri.StartsWith("http://openid.net/schema/", StringComparison.Ordinal))) {
				return AXAttributeFormats.OpenIdNetSchema;
			}

			return AXAttributeFormats.None;
		}

		/// <summary>
		/// Adds an attribute fetch request if it is not already present in the AX request.
		/// </summary>
		/// <param name="ax">The AX request to add the attribute request to.</param>
		/// <param name="format">The format of the attribute's Type URI to use.</param>
		/// <param name="axSchemaOrgFormatAttribute">The attribute in axschema.org format.</param>
		/// <param name="demandLevel">The demand level.</param>
		internal static void FetchAttribute(FetchRequest ax, AXAttributeFormats format, string axSchemaOrgFormatAttribute, DemandLevel demandLevel) {
			Requires.NotNull(ax, "ax");
			Requires.NotNullOrEmpty(axSchemaOrgFormatAttribute, "axSchemaOrgFormatAttribute");

			string typeUri = TransformAXFormat(axSchemaOrgFormatAttribute, format);
			if (!ax.Attributes.Contains(typeUri)) {
				switch (demandLevel) {
					case DemandLevel.Request:
						ax.Attributes.AddOptional(typeUri);
						break;
					case DemandLevel.Require:
						ax.Attributes.AddRequired(typeUri);
						break;
					default:
						break;
				}
			}
		}
	}
}