예제 #1
0
 /// <summary>
 /// Constructor used when this object is being created manually, vs populated thru JSON Converter.
 /// </summary>
 /// <param name="manualCreation"></param>
 public SecretReadReturnObjData(bool manualCreation = true)
 {
     SecretObj = (V)Activator.CreateInstance(typeof(V));
     //SecretObj = new V();
     Metadata = new KV2VaultReadSaveReturnObj();
 }
예제 #2
0
        /// <summary>
        ///     Saves the provided K2Secret object.  You must specify a save option and optionally what the current version of
        ///     the secret is.  The KV2Secret object's version # will be updated on success with what the new version of the
        ///     secret it.
        ///     If the CAS setting is set on the backend then the following errors may be returned:
        ///     <para></para>
        ///     <para>Commonly Throws the Following Errors:</para>
        ///     <para>
        ///         [VaultForbiddenException] - Errors with access.  The SpecifiedErrorCode field will be set to
        ///         EnumVaultExceptionCodes.PermissionDenied if token does not have
        ///         appropriate permissions to access the path.
        ///     </para>
        ///     <para>   [VaultInvalidDataException]</para>
        ///     <para>
        ///         [SpecificErrorCode] = EnumVaultExceptionCodes.CheckAndSetMissing - You specified an invalid casSaveOption
        ///         (AlwaysAllow is not valid for backend with CAS Set)
        ///         or the currentVersion parameter was invalid.
        ///     </para>
        ///     <para>
        ///         [SpecificErrorCode] = EnumVaultExceptionCodes.CAS_SecretExistsAlready - You set the casSaveOption to
        ///         only allow save to succeed if the secret does not yet exist.
        ///     </para>
        ///     <para>
        ///         [SpecificErrorCode] = EnumVaultExceptionCodes.CAS_VersionMissing - The version you specified was
        ///         invalid.  It must be equal to the current version number of the secret.
        ///     </para>
        /// </summary>
        /// <param name="secret">
        ///     IKV2Secret object to be saved.  This must contain minimally the Name and the Path of the secret
        ///     and one or more optional attributes.
        /// </param>
        /// <param name="casSaveOption">
        ///     This must be set to the CAS option you desired:
        ///     - OnlyIfKeyDoesNotExist = 0,
        ///     - OnlyOnExistingVersionMatch = 1,
        ///     - AlwaysAllow = 2  - Set to this value if the backend is not CAS enabled.  If CAS is enabled then this option will
        ///     result in an error.
        /// </param>
        /// <param name="currentVersion">
        ///     What the current version of the secret is.  Required if the backend is in CAS mode
        ///     (Default mode).
        /// </param>
        /// <returns></returns>
        //public async Task<bool> SaveSecret(IKV2Secret secret, KV2EnumSecretSaveOptions casSaveOption,
        //    int currentVersion = 0)
        public async Task <bool> SaveSecret <T>(T secret, KV2EnumSecretSaveOptions casSaveOption,
                                                int currentVersion = 0) where T : KV2SecretBase <T>
        {
            string path = MountPointPath + "data/" + secret.FullPath;


            Dictionary <string, object> reqData = new Dictionary <string, object>();
            Dictionary <string, string> options = new Dictionary <string, string>();

            // Set CAS depending on option coming from caller.
            switch (casSaveOption)
            {
            case KV2EnumSecretSaveOptions.OnlyIfKeyDoesNotExist:
                options.Add("cas", "0");
                break;

            case KV2EnumSecretSaveOptions.OnlyOnExistingVersionMatch:
                if (currentVersion != 0)
                {
                    options.Add("cas", currentVersion.ToString());
                }
                else
                {
                    throw new ArgumentException(
                              "The option OnlyOnExistingVersionMatch was chosen, but the currentVersion parameter was not set.  It must be set to the value of the current version of the key as stored in Vault.");
                }

                break;
            }


            // CAS - Check and Set needs to be passed in from caller.
            reqData.Add("options", options);
            reqData.Add("data", secret);

            try {
                VaultDataResponseObjectB vdro = await ParentVault._httpConnector.PostAsync_B(path, "SaveSecret", reqData);

                if (vdro.Success)
                {
                    KV2VaultReadSaveReturnObj obj = await vdro.GetDotNetObject <KV2VaultReadSaveReturnObj>();

                    if (obj != null)
                    {
                        secret.Version      = obj.Version;
                        secret.CreatedTime  = obj.CreatedTime;
                        secret.DeletionTime = (DateTimeOffset)obj.DeletionTime;
                        secret.IsDestroyed  = obj.Destroyed;
                    }

                    return(true);
                }

                return(false);
            }
            catch (VaultInvalidDataException e) {
                if (e.Message.Contains("check-and-set parameter required for this call"))
                {
                    VaultInvalidDataException eNew = new VaultInvalidDataException(Constants.Error_CAS_Set + " | Original Error message was: " + e.Message);
                    eNew.SpecificErrorCode = EnumVaultExceptionCodes.CheckAndSetMissing;
                    throw eNew;
                }

                // Check for Version errors:

                if (e.Message.Contains("did not match the current version"))
                {
                    // If user requested that the save happen only if the key does not already exist then return customized error message.
                    if (casSaveOption == KV2EnumSecretSaveOptions.OnlyIfKeyDoesNotExist)
                    {
                        VaultInvalidDataException eNew = new VaultInvalidDataException(
                            Constants.Error_CAS_SecretAlreadyExists + " | Original Error message was: " + e.Message);
                        eNew.SpecificErrorCode = EnumVaultExceptionCodes.CAS_SecretExistsAlready;
                        throw eNew;
                    }

                    // Customize the version discrepancy message
                    else
                    {
                        VaultInvalidDataException eNew = new VaultInvalidDataException(
                            Constants.Error_CAS_InvalidVersion + " Version specified was: " + currentVersion + " | Original Error message was: " + e.Message);
                        eNew.SpecificErrorCode = EnumVaultExceptionCodes.CAS_VersionMissing;
                        throw eNew;
                    }
                }

                throw new VaultInvalidDataException(e.Message);
            }
            catch (VaultForbiddenException e) {
                if (e.Message.Contains("* permission denied"))
                {
                    e.SpecificErrorCode = EnumVaultExceptionCodes.PermissionDenied;
                }

                throw e;
            }
            catch (Exception e) { throw e; }
        }