示例#1
0
        /// <summary>
        /// Attempts to load all secret values for the specified object.
        /// </summary>
        /// <param name="obj">
        /// The object where secret values will be loaded.
        /// </param>
        static public void LoadSecrets(object obj)
        {
            // Validate
            if (obj == null)
            {
                throw new ArgumentNullException(nameof(obj));
            }

            // Get all fields
            FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

            // Look for secret fields
            foreach (var field in fields)
            {
                // Try to get attribute
                SecretValueAttribute sva = field.GetCustomAttribute <SecretValueAttribute>();

                // If not a secret, skip
                if (sva == null)
                {
                    continue;
                }

                // Try to load the value
                TryLoadValue(sva, field, obj);
            }
        }
示例#2
0
        /// <summary>
        /// Attempts to load a secret value into the specified field.
        /// </summary>
        /// <param name="sva">
        /// A <see cref="SecretValueAttribute"/> that indicates the source of the secret value.
        /// </param>
        /// <param name="field">
        /// The field where the value will be loaded.
        /// </param>
        /// <param name="obj">
        /// The object instance where the value will be set.
        /// </param>
        /// <param name="overwrite">
        /// <c>true</c> to overwrite non-default values; otherwise <c>false</c>. The default is <c>false</c>.
        /// </param>
        /// <remarks>
        /// By default <see cref="SecretHelper"/> will only update fields that are set to default values
        /// (e.g. 0 for int and null or "" for string). This allows values set in the Unity inspector to
        /// override values stored in the environment. If values in the environment should always take
        /// precedence over values stored in the field set <paramref name="overwrite"/> to <c>true</c>.
        /// </remarks>
        static private void TryLoadValue(SecretValueAttribute sva, FieldInfo field, object obj, bool overwrite = false)
        {
            // Validate
            if (sva == null)
            {
                throw new ArgumentNullException(nameof(sva));
            }
            if (field == null)
            {
                throw new ArgumentNullException(nameof(field));
            }
            if (obj == null)
            {
                throw new ArgumentNullException(nameof(obj));
            }

            // Now get the current value of the field
            object curValue = field.GetValue(obj);

            // If we're not overwriting values, we need to check to check and make sure a non-default value is not already set
            if (!overwrite)
            {
                // What is the default value for the field?
                object defValue = GetDefaultValue(field.FieldType);

                // Is it the current value the same as the default value?
                bool isDefaultValue = ((curValue == defValue) || ((field.FieldType == typeof(string)) && (string.IsNullOrEmpty((string)curValue))));

                // If the current value is not the default value, the secret has already been supplied
                // and we don't need to do any more work.
                if (!isDefaultValue)
                {
                    return;
                }
            }

            // Either in overwrite mode or a default value. Let's try to read the environment variable.
            string svalue = Environment.GetEnvironmentVariable(sva.Name);

            // Check for no environment variable or no value set.
            if (string.IsNullOrEmpty(svalue))
            {
                Debug.LogWarning($"{obj.GetType().Name}.{field.Name} has the default value '{curValue}' but the environment variable {sva.Name} is missing or not set.");
                return;
            }

            // If string, just assign. Otherwise attempt to convert.
            if (field.FieldType == typeof(string))
            {
                field.SetValue(obj, svalue);
            }
            else
            {
                try
                {
                    object cvalue = Convert.ChangeType(svalue, field.FieldType);
                    field.SetValue(obj, cvalue);
                }
                catch (Exception ex)
                {
                    Debug.LogWarning($"The value '{svalue}' of environment variable {sva.Name} could not be converted to {field.FieldType.Name}. {ex.Message}");
                }
            }
        }