Patch data source (gateways)

 

Updated: March 12, 2018



Request | Response

The Patch data source operation updates the credentials for a data source.

Required scope: Dataset.ReadWrite.All

PATCH https://api.powerbi.com/v1.0/myorg/gateways/{gateway_id}/datasources/{data_source_id}

Uri parameter

NameDescriptionData Type
gateway_idGuid of the gateway to use. You can get the Gateway id from the Get Gateways operation.String
data_source_idGuid of the data source to get. You can get the Data source id from the Get data sources operation.String

Header

Authorization: Bearer eyJ0eX ... FWSXfwtQ

Status code

CodeDescription
200OK. Indicates success.
400Bad request
403Unauthorized
404Not found
500Internal service error

Content-Type

application/json

Body schema

{    
    "credentialDetails": {
        "credentials": "{string – depends on credential type and datasource type}",        
        "encryptionAlgorithm": "RSA-OAEP|None",
        "encryptedConnection": "Encrypted|NotEncrypted", 
        "privacyLevel": "None|Public|Organizational|Private",
        "credentialType": "Basic|Windows|Anonymous|OAuth|Key"
    }
}

Credentials schema by credential type:

For credential of type Basic or Windows:

    Credentials = {
        "credentialData": [
        {
            "name":"username", 
            "value":"{ActualUserName}"
        },
        { 
            "name":"password",
            "value":"{ActualPassword}" 
        }]
    }

For credential of type OAuth2:

    Credentials = {
        "credentialData": [
        {
            "name":"AccessToken", 
            "value":"{OAuth2 bearer token}"
        }]
    }

For credential of type Key:

    Credentials = {
        "credentialData": [
        {
            "name":"Key", 
            "value":"{API Key}"
        }]
    }

Notes

On-premises data sources requires the credentials value to be encrypted using the enterprise gateway public key (see below code example on how to perform the encryption for on-premises data sources).

Cloud data sources, doesn’t require the credentials to be encrypted.

Encrypt credentials

public static class AsymmetricKeyEncryptionHelper
    {
 
        private const int SegmentLength = 85;
        private const int EncryptedLength = 128;
 
        public static string EncodeCredentials(string userName, string password, string publicKeyExponent, string publicKeyModulus)
        {
            // using json serializer to handle escape characters in username and password
            var plainText = string.Format("{{\"credentialData\":[{{\"value\":{0},\"name\":\"username\"}},{{\"value\":{1},\"name\":\"password\"}}]}}", JsonConvert.SerializeObject(userName), JsonConvert.SerializeObject(password));
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(EncryptedLength * 8))
            {
                var parameters = rsa.ExportParameters(false);
                parameters.Exponent = Convert.FromBase64String(publicKeyExponent);
                parameters.Modulus = Convert.FromBase64String(publicKeyModulus);
                rsa.ImportParameters(parameters);
                return Encrypt(plainText, rsa);
            }
        }
 
        private static string Encrypt(string plainText, RSACryptoServiceProvider rsa)
        {
            byte[] plainTextArray = Encoding.UTF8.GetBytes(plainText);
 
            // Split the message into different segments, each segment's length is 85. So the result may be 85,85,85,20.
            bool hasIncompleteSegment = plainTextArray.Length % SegmentLength != 0;
 
            int segmentNumber = (!hasIncompleteSegment) ? (plainTextArray.Length / SegmentLength) : ((plainTextArray.Length / SegmentLength) + 1);
 
            byte[] encryptedData = new byte[segmentNumber * EncryptedLength];
            int encryptedDataPosition = 0;
 
            for (var i = 0; i < segmentNumber; i++)
            {
                int lengthToCopy;
 
                if (i == segmentNumber - 1 && hasIncompleteSegment)
                    lengthToCopy = plainTextArray.Length % SegmentLength;
                else
                    lengthToCopy = SegmentLength;
 
                var segment = new byte[lengthToCopy];
 
                Array.Copy(plainTextArray, i * SegmentLength, segment, 0, lengthToCopy);
 
                var segmentEncryptedResult = rsa.Encrypt(segment, true);
 
                Array.Copy(segmentEncryptedResult, 0, encryptedData, encryptedDataPosition, segmentEncryptedResult.Length);
 
                encryptedDataPosition += segmentEncryptedResult.Length;
            }
 
            return Convert.ToBase64String(encryptedData);
        }
    }
                  

Show: