aboutsummaryrefslogtreecommitdiffstats
path: root/src/IOL.VippsEcommerce/Models/VippsConfiguration.cs
blob: 2fcc91a0a8dc01d8899986009c6c73e080415cc3 (plain) (blame)
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
using System;

namespace IOL.VippsEcommerce.Models
{
	/// <summary>
	/// Configuration fields for the vipps api and integration.
	/// </summary>
	public class VippsConfiguration
	{
		/// <summary>
		/// Url for the vipps api. This property is required.
		/// <example>https://apitest.vipps.no</example>
		/// <example>https://api.vipps.no</example>
		/// <para>Corresponding environment variable name: VIPPS_API_URL</para>
		/// </summary>
		[VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_API_URL)]
		public string ApiUrl { get; set; }

		/// <summary>
		/// Client ID for the merchant (the "username"). This property is required.
		/// <para>Corresponding environment variable name: VIPPS_CLIENT_ID</para>
		/// </summary>
		[VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_CLIENT_ID)]
		public string ClientId { get; set; }

		/// <summary>
		/// Client Secret for the merchant (the "password"). This property is required.
		/// <para>Corresponding environment variable name: VIPPS_CLIENT_SECRET</para>
		/// </summary>
		[VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_CLIENT_SECRET)]
		public string ClientSecret { get; set; }

		/// <summary>
		///	Primary subscription key for the API product.
		/// <para>The primary subscription key take precedence over the secondary subscription key.</para>
		/// <para>Either primary subscription key or secondary subscription key is required.</para>
		/// <para>Corresponding environment variable name: VIPPS_SUBSCRIPTION_KEY_PRIMARY</para>
		/// </summary>
		[VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_SUBSCRIPTION_KEY_PRIMARY)]
		public string PrimarySubscriptionKey { get; set; }

		/// <summary>
		///	Secondary subscription key for the API product.
		/// <para>The primary subscription key take precedence over the secondary subscription key.</para>
		/// <para>Either primary subscription key or secondary subscription key is required.</para>
		/// <para>Corresponding environment variable name: VIPPS_SUBSCRIPTION_KEY_SECONDARY</para>
		/// </summary>
		[VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_SUBSCRIPTION_KEY_SECONDARY)]
		public string SecondarySubscriptionKey { get; set; }

		/// <summary>
		/// The Merchant Serial Number (MSN) is a unique id for the sale unit that this payment is made for.
		/// <para>Corresponding environment variable name: VIPPS_MSN</para>
		/// </summary>
		[VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_MSN)]
		public string MerchantSerialNumber { get; set; }

		/// <summary>
		/// The name of the ecommerce solution. One word in lowercase letters is good.
		/// <para>Corresponding environment variable name: VIPPS_SYSTEM_NAME</para>
		/// </summary>
		[VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_SYSTEM_NAME)]
		public string SystemName { get; set; }

		/// <summary>
		/// The version number of the ecommerce solution.
		/// <para>Corresponding environment variable name: VIPPS_SYSTEM_VERSION</para>
		/// </summary>
		[VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_SYSTEM_VERSION)]
		public string SystemVersion { get; set; }

		/// <summary>
		/// The name of the ecommerce plugin (if applicable). One word in lowercase letters is good.
		/// <para>Corresponding environment variable name: VIPPS_SYSTEM_PLUGIN_NAME</para>
		/// </summary>
		[VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_SYSTEM_PLUGIN_NAME)]
		public string SystemPluginName { get; set; }

		/// <summary>
		/// The version number of the ecommerce plugin (if applicable).
		/// <para>Corresponding environment variable name: VIPPS_SYSTEM_PLUGIN_VERSION</para>
		/// </summary>
		[VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_SYSTEM_PLUGIN_VERSION)]
		public string SystemPluginVersion { get; set; }

		/// <summary>
		/// Optional path to a writable directory wherein a credential cache file can be placed.
		/// <para>Corresponding environment variable name: VIPPS_CACHE_PATH</para>
		/// </summary>
		[VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_CACHE_PATH)]
		public string CacheDirectoryPath { get; set; }

		/// <summary>
		/// Optional key for AES encryption of the credential cache file.
		/// <para>Corresponding environment variable name: VIPPS_CACHE_KEY</para>
		/// </summary>
		[VippsConfigurationKeyName(VippsConfigurationKeyNames.VIPPS_CACHE_KEY)]
		public string CacheEncryptionKey { get; set; }

		/// <summary>
		/// Specify how to retrieve configuration and/or in what order. Defaults to VippsConfigurationMode.ENVIRONMENT_THEN_OBJECT.
		/// </summary>
		public VippsConfigurationMode ConfigurationMode { get; set; } = VippsConfigurationMode.ENVIRONMENT_THEN_OBJECT;

		/// <summary>
		/// Get value from configuration, either from Dependency injection or from the environment.
		/// </summary>
		/// <param name="key">Configuration key.</param>
		/// <returns>A string containing the configuration value.</returns>
		public string GetValue(string key) {
			switch (ConfigurationMode) {
				case VippsConfigurationMode.ONLY_OBJECT:
					return GetValueFromObject(key);
				case VippsConfigurationMode.ONLY_ENVIRONMENT:
					return GetValueFromEnvironment(key);
				case VippsConfigurationMode.OBJECT_THEN_ENVIRONMENT:
					return GetValueFromObject(key) ?? GetValueFromEnvironment(key);
				case VippsConfigurationMode.ENVIRONMENT_THEN_OBJECT:
					return GetValueFromEnvironment(key) ?? GetValueFromObject(key);
				default:
					return default;
			}
		}

		/// <summary>
		/// Ensure that the configuration can be used to issue requests to the vipps api.
		/// <exception cref="ArgumentNullException">Throws if a required value is null or whitespace.</exception>
		/// </summary>
		public void Verify() {
			if (GetValue(VippsConfigurationKeyNames.VIPPS_API_URL).IsNullOrWhiteSpace()) {
				throw new ArgumentNullException(nameof(ApiUrl),
												"VippsEcommerceService: ApiUrl is not provided in configuration.");
			}

			if (GetValue(VippsConfigurationKeyNames.VIPPS_CLIENT_ID).IsNullOrWhiteSpace()) {
				throw new ArgumentNullException(nameof(ClientId),
												"VippsEcommerceService: ClientId is not provided in configuration.");
			}

			if (GetValue(VippsConfigurationKeyNames.VIPPS_CLIENT_SECRET).IsNullOrWhiteSpace()) {
				throw new ArgumentNullException(nameof(ClientSecret),
												"VippsEcommerceService: ClientSecret is not provided in configuration.");
			}

			if (GetValue(VippsConfigurationKeyNames.VIPPS_SUBSCRIPTION_KEY_PRIMARY).IsNullOrWhiteSpace()
				&& GetValue(VippsConfigurationKeyNames.VIPPS_SUBSCRIPTION_KEY_SECONDARY).IsNullOrWhiteSpace()) {
				throw new ArgumentNullException(nameof(PrimarySubscriptionKey)
												+ nameof(SecondarySubscriptionKey),
												"VippsEcommerceService: Neither PrimarySubscriptionKey nor SecondarySubscriptionKey was provided in configuration.");
			}
		}

		private string GetValueFromEnvironment(string key) {
#if DEBUG
			var value = Environment.GetEnvironmentVariable(key);
			Console.WriteLine("Getting VippsConfiguration value for " + key + " from environment.");
			Console.WriteLine("Key: " + key + " Value: " + value);
			return value;
#else
			return Environment.GetEnvironmentVariable(key);
#endif
		}

		private string GetValueFromObject(string key) {
			foreach (var prop in typeof(VippsConfiguration).GetProperties()) {
				foreach (var attribute in prop.CustomAttributes) {
					foreach (var argument in attribute.ConstructorArguments) {
						if (argument.Value as string == key) {
#if DEBUG
							var value = prop.GetValue(this, null)?.ToString();
							Console.WriteLine("Getting VippsConfiguration value for " + key + " from object.");
							Console.WriteLine("Key: " + key + " Value: " + value);
							return value;
#else
							return prop.GetValue(this, null)?.ToString();
#endif
						}
					}
				}
			}

			return default;
		}
	}
}