Obfuscar - skip obfuscation of anonymous types - c#

I'm using the open source obfuscation software "Obfuscar". Is there a way to configure it to not obfuscate the property names in my anonymous types?
I'm using RestSharp to send HTTP requests, and my Json body content is an anonymous type.
request.AddJsonBody(new {
data = new {
type = "attachments",
attributes = new {
name = "foo"
}
}
});
I would like it to NOT rename those properties like "data", "type" etc in the anonymous type, because renaming them affects the Json string that it gets serialized to.

In github obfuscar issues i found this answer and it worked for me
You need to create the node in Obfuscar xml configuration file:
<SkipType name="*AnonymousType*" skipProperties="true" skipMethods="true" skipFields="true" skipEvents="true" skipStringHiding="true" />
Example of full xml configuration file:
<?xml version="1.0" encoding="utf-8"?>
<Obfuscator>
<Var name="OutPath" value="C:\TMP" />
<AssemblySearchPath path="C:\Users\user\Documents\Projects\MyProject\bin\Release\net6.0" />
<AssemblySearchPath path="C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0" />
<Module file="C:\Users\user\Documents\Projects\MyProject\bin\Release\net6.0\MyProject.dll">
<SkipType name="*AnonymousType*" skipProperties="true" skipMethods="true" skipFields="true" skipEvents="true" />
</Module>
<Var name="KeepPublicApi" value="false" />
<Var name="HidePrivateApi" value="true" />
</Obfuscator>
Next, you need to start obfuscar.exe -s "path_to_xml_configuration_file"
Also see the section in the Obfuscar documentation
https://docs.obfuscar.com/getting-started/configuration#exclusion-rules-by-configuration

Related

Sitecore LinkManager GetItemUrl. Why its so tricky?

I have task to get content's url when smth is changed on website. It like CRUD operation logging (In my case i am logging that urls to other system to further processing). It should work on version 6 and higher.
When i started it seems pretty simple subscribe to event then take item and generate url for it. I subscribed to two events publish:itemProcessing (because only here item is not yet removed from web database), publish:itemProcessed (for add and update).
This events give me object of time Item, so it seems to get url pretty simple like that
var options = LinkManager.GetDefaultUrlOptions();
options.AlwaysIncludeServerUrl = true;
options.SiteResolving = true;
var url = LinkManager.GetItemUrl(item, options);
And here my problem starts. First i need to have right url and the same way as it is generated on website but here url returns me smth like "http://domain/sitecore/content/Home.aspx".
So I added new methods to find right site from site definitions
private List<KeyValuePair<string, SiteContext>> GetSites()
{
return SiteManager.GetSites()
.Where(
s =>
!string.IsNullOrEmpty(s.Properties["rootPath"]) &&
!string.IsNullOrEmpty(s.Properties["startItem"]))
.Select(
d => new KeyValuePair<string, SiteContext>($"{d.Properties["rootPath"]}{d.Properties["startItem"]}",
new SiteContext(new SiteInfo(d.Properties))))
.ToList();
}
public virtual SiteContext GetSiteContext(Item item)
{
var site = _sites.LastOrDefault(s => item.Paths.FullPath.ToLower().StartsWith(s.Key.ToLower()));
return site.Value;
}
options.Site = GetSiteContext(Item item);
Again issue is not solved because sitecore returns "http://127.0.0.1/en.aspx"
Then i continue reading and understood that site definition should have targetHostName (it actually make sense since one site can have multiple domains) but when i add targetHostName now it returns me other link "://targetHostName/en.aspx" so http|https is missing. Second problem is that it returns me EN.aspx which means that this page can be accessible throw http://targetHostName/en.aspx and http://targetHostName
Now i have following site definitions
<sites>
<site name="shell" virtualFolder="/sitecore/shell" physicalFolder="/sitecore/shell" rootPath="/sitecore/content" startItem="/home" language="en" database="core" domain="sitecore" loginPage="/sitecore/login" content="master" contentStartItem="/Home" enableWorkflow="true" enableAnalytics="false" analyticsDefinitions="content" xmlControlPage="/sitecore/shell/default.aspx" browserTitle="Sitecore" htmlCacheSize="2MB" registryCacheSize="3MB" viewStateCacheSize="200KB" xslCacheSize="5MB" />
<site name="login" virtualFolder="/sitecore/login" physicalFolder="/sitecore/login" enableAnalytics="false" database="core" domain="sitecore" disableXmlControls="true" />
<site name="admin" virtualFolder="/sitecore/admin" physicalFolder="/sitecore/admin" enableAnalytics="false" enableWorkflow="true" domain="sitecore" loginPage="/sitecore/admin/login.aspx" />
<site name="service" virtualFolder="/sitecore/service" physicalFolder="/sitecore/service" />
<site name="modules_shell" virtualFolder="/sitecore modules/shell" physicalFolder="/sitecore modules/shell" rootPath="/sitecore/content" startItem="/home" language="en" database="core" domain="sitecore" content="master" enableAnalytics="false" enableWorkflow="true" />
<site name="modules_website" virtualFolder="/sitecore modules/web" physicalFolder="/sitecore modules/web" rootPath="/sitecore/content" startItem="/home" language="en" database="web" domain="extranet" allowDebug="true" cacheHtml="true" />
<site name="website" hostName="sitecore6.target|sitecore6.local" targetHostName="sitecore6.target" schema="http" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" />
<site name="scheduler" enableAnalytics="false" domain="sitecore" />
<site name="system" enableAnalytics="false" domain="sitecore" />
<site name="publisher" domain="sitecore" enableAnalytics="false" enableWorkflow="true" />
</sites>
And link manager settings
<linkManager defaultProvider="sitecore">
<providers>
<clear />
<add name="sitecore" type="Sitecore.Links.LinkProvider, Sitecore.Kernel" addAspxExtension="true" alwaysIncludeServerUrl="false" encodeNames="true" languageEmbedding="asNeeded" languageLocation="filePath" lowercaseUrls="false" shortenUrls="true" useDisplayName="false" />
</providers>
</linkManager>
The problem is occurring because of where you are generating the link. When you have the AlwaysIncludeServerUrl option set to true, Sitecore will use the current Sitecore.Context.Site information to work out the server Url.
To set the http or https section, you need to add an attribute called scheme to your site definition - I think you just have a typo as you had one called schema:
<sites>
<site name="website" hostName="sitecore6.target|sitecore6.local" targetHostName="sitecore6.target" scheme="http" virtualFolder="/" physicalFolder="/" rootPath="/sitecore/content" startItem="/home" database="web" domain="extranet" allowDebug="true" cacheHtml="true" htmlCacheSize="10MB" registryCacheSize="0" viewStateCacheSize="0" xslCacheSize="5MB" filteredItemsCacheSize="2MB" enablePreview="true" enableWebEdit="true" enableDebugger="true" disableClientData="false" />
</sites>
During a publish event, that Context.Site will be the shell website. So it will not pickup the targetHostName for your website definition.
To force that, you need to use a SiteContextSwitcher
var website = Sitecore.Configuration.Factory.GetSite("website");
using (new SiteContextSwitcher(website))
{
var options = LinkManager.GetDefaultUrlOptions();
options.AlwaysIncludeServerUrl = true;
options.SiteResolving = true;
var url = LinkManager.GetItemUrl(item, options);
}
Then the Url will be generated using the website's targetHostName and should generate how you are expecting.
Just one last note - best practice would be to patch the new Site definition via an include file rather than edit the main Sitecore config. Check out your include folder, there should be a SiteDefinition.config.example file in there. It shows you how to do it.

How to configure Obfuscar, The Open Source Obfuscation Tool

I m trying to use the obfuscar free tool to protect my code from reverse engineering. I'm trying to obfuscate the provided example Basic Example. The problem that I can't find how to configure it.
Here's my config.xml
<configuration>
<startup><supportedRuntime version="v4.0"
sku=".NETFramework,Version=v4.0,Profile=Client"/>
</startup>
<Obfuscator>
<Var name="InPath" value="C:\Users\user\Desktop\Obfuscar_2.0.0\Examples\BasicExample\BasicExampleExe\bin\Debug" />
<Var name="OutPath" value="C:\Users\user\Desktop\Obfuscar_2.0.0\Examples\BasicExample\BasicExampleExe\bin\Debug" />
<Module file="$(InPath)\BasicExampleExe.exe" />
<Module file="$(InPath)\BasicExampleLibrary.dll" />
<Var name="KeepPublicApi" value="true" />
<Var name="HidePrivateApi" value="true" />
</Obfuscator>
</configuration>
I had the same question... the example Release.proj build file they provide in the Git attempts to build the Obfuscar binary from scratch. So you need to change two lines of the Release.proj file, assuming you're going to be using the pre-compiled Obfuscar binary file.
First, change the path to the ObfuscarExe path to where you have the binary saved similar to this:
<!-- obfuscator bits -->
<PropertyGroup>
<ObfuscatorExe>C:\Program Files (x86)\Obfuscar\obfuscar.Console.exe</ObfuscatorExe>
<ObfuscatorProject>$(BasePath)\obfuscar.xml</ObfuscatorProject>
<ObfuscatorInput>$(BasePath)\Obfuscator_Input</ObfuscatorInput>
<ObfuscatorOutput>$(BasePath)\Obfuscator_Output</ObfuscatorOutput>
</PropertyGroup>
Second, comment out the command to compile the Obfuscar solution:
<ItemGroup>
<CompileSolution Include="$(BasePath)\BasicExample.sln" />
<!-- <CompileObfuscar Include="..\..\Obfuscar\Obfuscar.sln" /> -->
</ItemGroup>

Merge .net configuration files

My application has 2 config files at the moment.
App.config
Custom.config
The App.config references the Custom.config via a custom section handler like below:
<configuration>
<configSections>
<section name="Custom" type="MyApp.CustomConfigSection, MyApp" />
</configSections>
<Custom configSource="Custom.config" />
</configuration>
The problem is the Custom.config file contains a single section with many elements. I'd like to split this out so some of the elements are in one file and some are in another.
e.g. Right now I have
'<Custom>
<Group1 ../>
<Group2 ../>
<Group3 ../>
</Custom>
I'd like to make 2 or more files like below.
'<Custom>
<Group1 ../>
</Custom>'
'<Custom>
<Group2 ../>
<Group3 ../>
</Custom>'
At the moment I call ConfigurationManager.GetSection("Custom") as MyCustomConfigSection. I then have a number of classes with various configuration attributes that are populated automatically by the .net configuration.
Is there a way to do this split or can you not split 1 section into multiple files?
Thanks in advance

XML Serialization in .NET - what's wrong with this

I have xml like this:
<?xml version="1.0" encoding="utf-8"?>
<session xmlns="http://winscp.net/schema/session/1.0" name="blah#blah.com" start="2011-10-03T15:09:30.481Z">
<ls>
<destination value="/incoming/monthly" />
<files>
<file>
<filename value="2.txt" />
<type value="D" />
<modification value="2011-09-14T12:58:26.000Z" />
<permissions value="rwxr-xr-x" />
</file>
<file>
<filename value="3.txt" />
<type value="D" />
<modification value="2011-01-03T22:04:55.000Z" />
<permissions value="rwxr-xr-x" />
</file>
</files>
<result success="true" />
</ls>
</session>
My representation of the following is:
<XmlRoot("session", Namespace:="http://winscp.net/schema/session/1.0")>
Class XMLSession
<XmlElement("ls/files/file")>
Public Property FileList As New List(Of XMLFile)
End Class
<XmlType("file")>
Class XMLFile
<XmlElement("filename")>
Public Property FileName As XMLValueAttribute
<XmlElement("type")>
Public Property TypeName As XMLValueAttribute
<XmlElement("permissions")>
Public Property Permissions As XMLValueAttribute
<XmlElement("modification")>
Public Property ModificationDate As XMLValueAttribute
End Class
Class XMLValueAttribute
<XmlAttribute("value")>
Public Property Value As String
End Class
Why is XMLSession.FileList.Count always 0. I hypothesize it has something to do with the declaration above it but I am not sure what is wrong with it. Maybe it can't accept a path, if not, how can I do it?
You can't describe multiple levels of XML with a single XmlElementAttribute. You need classes for each level.
If you don't want to build the classes by hand, you can get the tools to do it for you:
Assuming your XML is saved in data.xml:
xsd.exe data.xml
This will give you data.xsd which defines the XML.
xsd.exe /l:VB /n:SomeNamespace /c data.xsd
This will give you a codefile data.vb with your types defined, which you can add to your project.
Problem with this one is that there's some kind of bug, described here, which throws an error when you create a serializer around this new type. So you just need one manual tweak on the generated code, changing:
<XmlArrayItemAttribute("file", GetType(sessionLSFilesFile), IsNullable:=False)> _
'To
<XmlArrayItemAttribute("file", GetType(sessionLSFilesFile()), IsNullable:=False)> _

create your own settings in xml

I'm in a ASP.NET project where I need to give several parameters to the administrator that is going to install the website, like:
AllowUserToChangePanelLayout
AllowUserToDeleteCompany
etc...
My question is, will be a good thing to add this into the web.config file, using my own configSession or add as a profile varibles? or should I create a XML file for this?
What do you do and what are the cons and favs?
I originally thought about web.config but I then realized that I should mess up with Website configurations and my own web app configuration and that I should create a different file, them I read this post and now I'm on this place... should I do this or that?
I usually use Settings - available via the project properties - Settings. These can be edited and saved in code, and I write a form / web page to edit them.
If you want to use the XML configuration, there's an attribute called file that reads external files.
You could have a web.config file and a someothername.config file. The someothername.config would have settings like:
<appSettings>
<add key="ConnString" value="my conn string" />
<add key="MaxUsers" value="50" />
</appSettings>
And the web.config would have
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings file="ExternalWeb.config">
<add key="MyKey" value="MyValue" />
</appSettings>
</configuration>
See DevX for the example I stole.
just to let you guys know that I did what configurator recommended but with a twist.
instead of asking all the time (that I need) for
System.Configuration.ConfigurationManager.AppSettings["myKey"];
I just created a static class that would pull this values with what we call by Strongly typed values (so you don't need to remember all the values)
the mySettings class
public static class mySettings
{
public enum SettingsType
{ UserPermitions, WebService, Alerts }
public enum SectionType
{ AllowChangeLayout, AllowUserDelete, MaximumReturnsFromSearch, MaximumOnBatch, SendTo }
public static String GetSettings(SettingsType type, SectionType section)
{
return
ConfigurationManager.AppSettings[
String.Format("{0}_{1}",
Enum.Parse(typeof(SettingsType), type.ToString()).ToString(),
Enum.Parse(typeof(SectionType), section.ToString()).ToString())
];
}
}
the web.config appSettings part
<configuration>
<appSettings file="myApp.config">
<add key="UserPermitions_AllowChangeLayout" value="" />
<add key="UserPermitions_AllowUserDelete" value="" />
<add key="WebService_MaximumReturnsFromSearch" value="" />
<add key="Alerts_SendTo" value="" />
<add key="Alerts_MaximumOnBatch" value="" />
</appSettings>
</configuration>
the entire myApp.config file
<?xml version="1.0" encoding="utf-8" ?>
<!--
###
### This file serves the propose of a quick configuration.
### Administrator can either change this values directly or use the
### Settings tab in the application.
###
-->
<appSettings>
<!-- *** User Access Configuration *** -->
<!-- Allow user to change the panels layout {1: Yes} {0: No} -->
<add key="UserPermitions_AllowChangeLayout" value="1" />
<!-- Allow user to delete a company fro monitoring -->
<add key="UserPermitions_AllowUserDelete" value="1" />
<!-- *** Web Service configuration *** -->
<!-- Maximum responses from the search service -->
<add key="WebService_MaximumReturnsFromSearch" value="10" />
<!-- *** Allerts configuration *** -->
<!-- Send the alerts to the email writeen below -->
<add key="Alerts_SendTo" value="bruno.in.dk#gmail.com" />
<!-- Send an alert when user import more than the number bellow -->
<add key="Alerts_MaximumOnBatch" value="10" />
</appSettings>
So, now I call like this:
p.value = mySettings.GetSettings(
mySettings.SettingsType.WebService,
mySettings.SectionType.MaximumReturnsFromSearch);
Hope that helps someone with the same problem :)
You may also put your configurations in a settings file. In your project, open Properties and go to Settings which looks
like so
To access the values in your code, use Properties.Settings.YourSettingName;
Use Properties.Settings.Default.Reload(); to refresh your settings during runtime

Categories

Resources