Obfuscate Connection Data
Obfuscating the connection data is used to mask information exchanged with the server, like DB name and host, which can be considered sensitive. The encoding of information in DataSource or DataSourceItems, happens server-side before returning the objects to the client. DataSource and DataSourceItems information is typically sent from the server to the client when editing a dashboard. Alongside with the IRVObjectEncoder implementation, decoding must be done using an IRVDataSourceProvider implementation. Only supported for Database and REST providers.
Obfuscate MS Sql Server Data Source
Step 1 - In the ASP.NET Web API server application, create a class that implements IRVObjectEncoder
.
This class will perform the actual replacement of the MS SQL Server information with the encoded values.
internal class SampleEncoder : IRVObjectEncoder
{
public Task<RVDashboardDataSource> Encode(IRVUserContext userContext, RVDashboardDataSource dataSource)
{
var sqlDs = dataSource as RVSqlServerDataSource;
if (sqlDs != null)
{
sqlDs = (RVSqlServerDataSource)dataSource;
EncodeDatasource(sqlDs);
return Task.FromResult((RVDashboardDataSource)sqlDs);
}
return Task.FromResult<RVDashboardDataSource>(null);
}
public Task<RVDataSourceItem> Encode(IRVUserContext userContext, RVDataSourceItem dataSourceItem)
{
var sqlServerDsi = dataSourceItem as RVSqlServerDataSourceItem;
if (sqlServerDsi!= null)
{
var sqlServerDS = (RVSqlServerDataSource)sqlServerDsi.DataSource;
EncodeDatasource(sqlServerDS);
EncodeDataSourceItem(sqlServerDsi);
return Task.FromResult((RVDataSourceItem)sqlServerDsi);
}
return Task.FromResult((RVDataSourceItem)null);
}
private static void EncodeDatasource(RVSqlServerDataSource sqlServerDS)
{
sqlServerDS.Host = EncodeHost(sqlServerDS.Host);
sqlServerDS.Database = EncodeDatabase(sqlServerDS.Database);
sqlServerDS.Schema = EncodeSchema(sqlServerDS.Schema);
}
private static void EncodeDataSourceItem(RVSqlServerDataSourceItem sqlServerDsi)
{
sqlServerDsi.Database = EncodeDatabase(sqlServerDsi.Database);
sqlServerDsi.Table = EncodeTableName(sqlServerDsi.Table);
sqlServerDsi.Schema = EncodeSchema(sqlServerDsi.Schema);
sqlServerDsi.Id = sqlServerDsi.Database + "__" + sqlServerDsi.Schema + "__" + sqlServerDsi.Table;
}
private static string EncodeTableName(string name)
{
if (name == "real_table_name_1")
{
name = "Table_1";
}
else if (name == "real_table_name_2")
{
name = "Table_2"
}
// else etc.
return name;
}
private static string EncodeHost(string host)
{
if (host == "real_host_name")
{
host = "Host";
}
// else etc.
return host;
}
private static string EncodeDatabase(string database)
{
if (database == "real_database_name")
{
database = "Database";
}
// else etc.
return database;
}
private static string EncodeSchema(string schema)
{
if (schema == "real_schema")
{
schema = "Schema";
}
// else etc.
return schema;
}
}
The Encode
method of this class returns the RVDataSourceItem
that the visualization will use to get its data.
By modifying the RVDataSourceItem
item that is provided as an argument in the Encode
method, you can change sensitive information of the Datasource/DatasourceItem.
Step 2 - Update the AddReveal
method in the Program.cs
file to add the IRVObjectEncoder
you just created to the RevealSetupBuilder
using the RevealSetupBuilder.AddObjectEncoder
method.
.AddReveal(builder =>
{
builder
.AddObjectEncoder<SampleEncoder>()
.AddSettings(settings =>
{
settings.LocalFileStoragePath = "Data";
settings.DataCachePath = cacheFilePath;
settings.CachePath = cacheFilePath;
});
});
Step 3 - In the ASP.NET Web API server application, create a class that implements IRVDataSourceProvider
. This class will perform the actual replacement of the Database/REST settings. The ChangeDataSourceItemAsync
method of this class returns the RVDataSourceItem
that the visualization will use to get its data. By modifying the RVDataSourceItem
item that is provided as an argument in the ChangeDataSourceItemAsync
method, you can change which server or table to get your data from. You can change the MS SQL Server host, database,id and table name of every MS SQL Server data source item in your dashboard by casting each RVDataSource
as a RVSqlServerDataSource
and every RVDataSourceItem
as a RVSqlServerDataSourceItem
, modifying it's properties as follows:
internal class LocalSamplesDataSourceProvider : IRVDataSourceProvider
{
public Task<RVDashboardDataSource> ChangeDataSourceAsync(IRVUserContext userContext, RVDashboardDataSource dataSource)
{
var sqlDs = dataSource as RVSqlServerDataSource;
if (sqlDs != null)
{
sqlDs = (RVSqlServerDataSource)dataSource;
DecodeDataSource(sqlDs);
return Task.FromResult((RVDashboardDataSource)dataSource);
}
return Task.FromResult<RVDashboardDataSource>(null);
}
public Task<RVDataSourceItem> ChangeDataSourceItemAsync(IRVUserContext userContext, string dashboardId, RVDataSourceItem dataSourceItem)
{
var sqlServerDsi = dataSourceItem as RVSqlServerDataSourceItem;
if (sqlServerDsi != null)
{
var sqlServerDS = (RVSqlServerDataSource)sqlServerDsi.DataSource;
DecodeDataSource(sqlServerDS);
DecodeDataSourceItem(sqlServerDsi);
return Task.FromResult((RVDataSourceItem)sqlServerDsi);
}
return Task.FromResult<RVDataSourceItem>(null);
}
private static void DecodeDataSource(RVSqlServerDataSource sqlServerDS)
{
sqlServerDS.Host = DecodeHost(sqlServerDS.Host);
sqlServerDS.Database = DecodeDatabase(sqlServerDS.Database);
sqlServerDS.Schema = DecodeSchema(sqlServerDS.Schema);
}
private static void DecodeDataSourceItem(RVSqlServerDataSourceItem sqlServerDsi)
{
sqlServerDsi.Database = DecodeDatabase(sqlServerDsi.Database);
sqlServerDsi.Schema = DecodeSchema(sqlServerDsi.Schema);
sqlServerDsi.Table = DecodeTableName(sqlServerDsi.Table);
}
private static string DecodeTableName(string name)
{
if (name == "Table_1")
{
name = "real_table_name_1";
}
else if (name == "Table_2")
{
name = "real_table_name_2"
}
// else etc.
return name;
}
private static string DecodeHost(string host)
{
if (host == "Host")
{
host = "real_host_name";
}
// else etc.
return host;
}
private static string DecodeSchema(string schema)
{
if (schema == "Schema")
{
schema = "real_schema";
}
// else etc.
return schema;
}
private static string DecodeDatabase(string database)
{
if (database == "Database")
{
database = "real_database_name";
}
// else etc.
return database;
}
}
Step 4 - Update the AddReveal
method in the Program.cs
file to add the IRVDataSourceProvider
you just created to the RevealSetupBuilder
using the RevealSetupBuilder.AddDataSourceProvider
method.
.AddReveal(builder =>
{
builder
// Registers LocalSamplesDataSourceProvider, which in step 3 decodes the previously encoded values.
.AddDataSourceProvider<LocalSamplesDataSourceProvider>()
.AddObjectEncoder<SamplesDataSource>()
.AddSettings(settings =>
{
settings.LocalFileStoragePath = "Data";
settings.DataCachePath = cacheFilePath;
settings.CachePath = cacheFilePath;
});
});