EDIT.
I have a problem with XmlDsigXPathTransform valiation. Sad to say even when I copied 1:1 the example from docs the xpath validations ends failed. What am I missing? I can't figure anything anymore about this when even the docs example fails.
https://learn.microsoft.com/pl-pl/dotnet/api/system.security.cryptography.xml.xmldsigxpathtransform?view=netframework-4.6.1
var signatureReference = new Reference { Uri = "", };
XmlDsigXPathTransform XPathTransform =
CreateXPathTransform(XPathString);
signatureReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
signatureReference.AddTransform(XPathTransform);
signedXml.AddReference(signatureReference);
private static XmlDsigXPathTransform CreateXPathTransform(string XPathString)
{
XmlDocument doc = new XmlDocument();
XmlElement xPathElem = doc.CreateElement("XPath");
xPathElem.InnerText = XPathString;
XmlDsigXPathTransform xForm = new XmlDsigXPathTransform();
xForm.LoadInnerXml(xPathElem.SelectNodes("."));
return xForm;
}
The XmlDsigXPathTransform is no longer considered safe, so any document using it is automatically considered to have an invalid signature.
https://referencesource.microsoft.com/#System.Security/system/security/cryptography/xml/signedxml.cs,8b616077b30145cd
If you really want to use it, you have to enable it in the Windows Registry on whatever computers are going to call CheckSignature.
https://support.microsoft.com/en-us/topic/after-you-apply-security-update-3141780-net-framework-applications-encounter-exception-errors-or-unexpected-failures-while-processing-files-that-contain-signedxml-922edd45-a91e-c755-bb30-2604acf37362
SignedXml is old and outdated, my recommendation is to not use it at all, unless you have to for compatibility (the .NET team calls it legacy and says it's not being invested in on issues, e.g. https://github.com/dotnet/runtime/issues/44674#issuecomment-875163316).
Related
When programmatically creating a Cognito user pool and app client, if the app client is to have read/write access to attributes of the user pool, that access must be explicitly given. I have been able to do so successfully for custom attributes but built-in attributes always return an error of "Invalid write attributes specified while creating a client" or "Invalid read attributes specified while creating a client".
Documentation is ... both voluminous and difficult to find. I have yet to see an example of this or an actual bit of useful documentation on the CreateUserPoolClientRequest type that says anything about this other than things like "ReadAttributes is a list of strings that are the attributes that can be read".
Here is the code I'm using that always ends up with that error message and failure to create the app client. _client is an AmazonCognitoIdentityProviderClient properly instantiated and credentialed and running in a lambda function.
var request = new CreateUserPoolClientRequest { UserPoolId = userPoolId, ClientName = $"{name}AppClient" };
var builtInAttributes = new List<string>()
{
"address","birthdate","email","family name","gender","given name","locale","middle name","name","nickname","phone number", "picture","preferred username","profile","zoneinfo","updated at","website"
};
var readAttributes = new List<string>();
var writeAttributes = new List<string>();
readAttributes.InsertRange(0,builtInAttributes);
writeAttributes.InsertRange(0, builtInAttributes);
var attributeConfig = ConfigurationHelper.GetListFromSection("UserPoolCustomAttributes");
foreach (var attribute in attributeConfig)
{
readAttributes.Add($"custom:{attribute.Key}");
writeAttributes.Add($"custom:{attribute.Key}");
}
request.ReadAttributes = readAttributes;
request.WriteAttributes = writeAttributes;
var result = await _client.CreateUserPoolClientAsync(request, CancellationToken.None);
Any help is greatly appreciated.
Figured it out. Though I have yet to find it documented anywhere, default attributes with a space in the name in the ui need to have that space replaced with an underscore when using their name in the api.
I have a c# script that validates an XML document against an XSD document, as follows:
static bool IsValidXml(string xmlFilePath, string xsdFilePath)
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(null, xsdFilePath);
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Compile();
try
{
XmlReader xmlRead = XmlReader.Create(xmlFilePath, settings);
while (xmlRead.Read())
{ };
xmlRead.Close();
}
catch (Exception e)
{
return false;
}
return true;
}
I've compiled this after looking at a number of MSDN articles and questions here where this is the solution. It does correctly validate that the XSD is formed well (returns false if I mess with the file) and checks that the XML is formed well (also returns false when messed with).
I've also tried the following, but it does the exact same thing:
static bool IsValidXml(string xmlFilePath, string xsdFilePath)
{
XDocument xdoc = XDocument.Load(xmlFilePath);
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(null, xsdFilePath);
try
{
xdoc.Validate(schemas, null);
}
catch (XmlSchemaValidationException e)
{
return false;
}
return true;
}
I've even pulled a completely random XSD off the internet and thrown it into both scripts, and it still validates on both. What am I missing here?
Using .NET 3.5 within an SSIS job.
In .NET you have to check yourself if the validator actually matches a schema component; if it doesn't, there is no exception thrown, and so your code will not work as you expect.
A match means one or both of the following:
there is one global element in your schema set with a qualified name that is the same as your XML document element's qualified name.
the document element has an xsi:type attribute, that is a qualified name pointing to a global type in your schema set.
In streaming mode, you can do this check easily. This pseudo-kind-of-code should give you an idea (error handling not shown, etc.):
using (XmlReader reader = XmlReader.Create(xmlfile, settings))
{
reader.MoveToContent();
var qn = new XmlQualifiedName(reader.LocalName, reader.NamespaceURI);
// element test: schemas.GlobalElements.ContainsKey(qn);
// check if there's an xsi:type attribute: reader["type", XmlSchema.InstanceNamespace] != null;
// if exists, resolve the value of the xsi:type attribute to an XmlQualifiedName
// type test: schemas.GlobalTypes.ContainsKey(qn);
// if all good, keep reading; otherwise, break here after setting your error flag, etc.
}
You might also consider the XmlNode.SchemaInfo which represents the post schema validation infoset that has been assigned to a node as a result of schema validation. I would test different conditions and see how it works for your scenario. The first method is recommended to reduce the attack surface in DoS attacks, as it is the fastest way to detect completely bogus payloads.
I'm trying to figure out how to get the currently opened document on Lotus Notes through C#, but I cannot. Even though I researched half a day on Google, I couldn't find anything useful.
With my code I get the view I want, the database I want, etc, but I just would like to get the opened document. I tried something like IsUIDocOpen, but none of the full collection contains it as true.
Does someone know if there is any different between an opened document and a non-opened document trough Domino API? My workaround is to get the subject of the email and the size of the email and compare each one and when it matches get the Entry ID and then get the information I need - but that takes too long, especially when the inbox is big.
Any suggestions?
Here is my code:
NotesSession session = new NotesSession();
session.Initialize(sPassword);
notedb = session.GetDatabase(server, filename, false);
if (notedb.IsOpen)
{
mailView = notedb.GetView("$Inbox");
mailDoc = mailView.GetLastDocument();
//mailDoc = mailView.GetDocumentByKey();
try
{
while (mailDoc != null)
{
NotesItem item = mailDoc.GetFirstItem("From");
if (item != null)
{
MessageBox.Show("From = " + item.Text);
}
}
}
}
Solution: should be something like: mailDoc = mailView.GetCurrentDocument(); // But obviously this method does not exist :D
=====================================================================================
Solution code:
Type NotesUIWorkspaceType = Type.GetTypeFromProgID("Notes.NotesUIWorkspace", true);
object workspace = Activator.CreateInstance(NotesUIWorkspaceType);
object uiDoc = NotesUIWorkspaceType.InvokeMember("CurrentDocument", BindingFlags.GetProperty, null, workspace, null);
Type NotesUIDocument = uiDoc.GetType();
object Subject = NotesUIDocument.InvokeMember("FieldGetText", BindingFlags.InvokeMethod, null, uiDoc, new Object[] { "Subject" });
string subject = "test";
NotesUIDocument.InvokeMember("FieldSetText", BindingFlags.InvokeMethod, null, uiDoc, new Object[] { "Subject", subject });
object Body = NotesUIDocument.InvokeMember("FieldGetText", BindingFlags.InvokeMethod, null, uiDoc, new Object[] { "Body" });
What you actually need is the Notes OLE classes.
The C# Interop classes are based on the Notes COM classes. The COM classes only have access to the "back end". I.e., the root object is Lotus.NotesSession, and all the classes work against data stored in .NSF files. They have no access to anything in the Notes UI.
The Notes OLE classes have access to both the "back end", with the root object Notes.NotesSession, and the "front end" with the root object Notes.NotesUIWorkspace. As you can tell by the name of that class, it's the front end classes that give you access to elements of the Notes client UI.
Note the subtle difference: the prefix for the OLE classes is "Notes.", instead of the prefix "Lotus." for the COM classes.
In old-style VB late binding, the OLE classes are instantiated this way:
CreateObject("Notes.NotesUIWorkspace")
I'm not sure how that translates into C#.
Anyhow, once you have the NotesUIWorkspace object, the currently opened document is available with the NotesUIWorkspace.CurrentDocument method.
IF you are using the Interop Classes you need to use NotesUIView.CurrentView.Documents to get what you want... see here.
You'll need to get the NotesUIWorkspace first, then use the CurrentDocument property
NotesUIWorkspace workspace = new NotesUIWorkspace();
NotesUIDocument uidoc = workspace.CurrentDocument();
The only solution I could find was using:
mshtml.HTMLDocument htmldocu = new mshtml.HTMLDocument();
htmldocu .createDocumentFromUrl(url, "");
and I am not sure about the performance, it should be better than loading the html file in a WebBrowser and then grab the HtmlDocument from there. Anyhow, that code does not work on my machine. The application crashes when it tries to execute the second line.
Has anyone an approach to achieve this efficiently or any other way?
NOTE: Please understand that I need the HtmlDocument object for DOM processing. I do not need the html string.
Use the DownloadString method of the WebClient object. e.g.
WebClient client = new WebClient();
string reply = client.DownloadString("http://www.google.com");
In the above example, after executed, reply will contain the html markup of the endpoint http://www.google.com.
WebClient.DownloadString MSDN
In an attempt to answer your actual question from four years ago (at the time of me posting this answer), I'm providing a working solution. I wouldn't be surprised if you found another way to do this, either, so this is mostly for other people searching for a similar solution. Keep in mind, however, that this is considered
somewhat obsolete (the actual use of HtmlDocument)
not the best way to handle HTML DOM parsing (the preferred solution is to use HtmlAgilityPack or CsQuery or some other method using actual parsing and not regular expressions)
extremely hacky and therefore not the safest/most compatible way to do it
you really should not be doing what I'm about to show
Additionally, keep in mind that HtmlDocument is really just a wrapper for mshtml.HTMLDocument2, so it is technically slower than just using a COM wrapper directly, but I completely understand the use case simply for ease of coding.
If you're cool with all of the above, here's how to accomplish what you want.
public class HtmlDocumentFactory
{
private static Type htmlDocType = typeof(System.Windows.Forms.HtmlDocument);
private static Type htmlShimManagerType = null;
private static object htmlShimSingleton = null;
private static ConstructorInfo docCtor = null;
public static HtmlDocument Create()
{
if (htmlShimManagerType == null)
{
// get a type reference to HtmlShimManager
htmlShimManagerType = htmlDocType.Assembly.GetType(
"System.Windows.Forms.HtmlShimManager"
);
// locate the necessary private constructor for HtmlShimManager
var shimCtor = htmlShimManagerType.GetConstructor(
BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[0], null
);
// create a new HtmlShimManager object and keep it for the rest of the
// assembly instance
htmlShimSingleton = shimCtor.Invoke(null);
}
if (docCtor == null)
{
// get the only constructor for HtmlDocument (which is marked as private)
docCtor = htmlDocType.GetConstructors(
BindingFlags.NonPublic | BindingFlags.Instance
)[0];
}
// create an instance of mshtml.HTMLDocument2 (in the form of
// IHTMLDocument2 using HTMLDocument2's class ID)
object htmlDoc2Inst = Activator.CreateInstance(Type.GetTypeFromCLSID(
new Guid("25336920-03F9-11CF-8FD0-00AA00686F13")
));
var argValues = new object[] { htmlShimSingleton, htmlDoc2Inst };
// create a new HtmlDocument without involving WebBrowser
return (HtmlDocument)docCtor.Invoke(argValues);
}
}
To use it:
var htmlDoc = HtmlDocumentFactory.Create();
htmlDoc.Write("<html><body><div>Hello, world!</body></div></html>");
Console.WriteLine(htmlDoc.Body.InnerText);
// output:
// Hello, world!
I have not tested this code directly -- I have translated it from an old Powershell script that needed the same functionality you're requesting. If it fails, let me know. The functionality is there but the code might need very minor tweaking to get working.
Im trying to validate an XML file using a .DTD but it gives me the following error.
'ENTITY' is an unexpected token. The expected token is 'DOCTYPE'. Line 538, position 3.
public static void Validate(string xmlFilename, string schemaFilename)
{
XmlTextReader r = new XmlTextReader(xmlFilename);
XmlValidatingReader validator = new XmlValidatingReader(r);
validator.ValidationType = ValidationType.Schema;
XmlSchemaCollection schemas = new XmlSchemaCollection();
schemas.Add(null, schemaFilename);
validator.ValidationEventHandler += new ValidationEventHandler(ValidationEventHandler);
try
{
while (validator.Read())
{ }
}
catch (XmlException err)
{
Console.WriteLine(err.Message);
}
finally
{
validator.Close();
}
}
The DTD im using to validate = http://www.editeur.org/onix/2.1/reference/onix-international.dtd
I hope someone can help me thanks!
I realise this is a really old question, but for anyone else struggling with this problem, here's what I did.
I gave up trying to validate with the DTD.
Instead, I ended up using the onix 2.1 xsd available at http://www.editeur.org/15/Previous-Releases/#R%202.1%20Downloads. I had to set the default namespace:
var nt = new NameTable();
var ns = new XmlNamespaceManager(nt);
ns.AddNamespace(string.Empty, "http://www.editeur.org/onix/2.1/reference");
var context = new XmlParserContext(null, ns, null, XmlSpace.None);
and then when loading the xml, turn off DTD parsing (this is using .NET4)
var settings = XmlReaderSettings
{
ValidationType = System.Xml.ValidationType.Schema,
DtdProcessing = DtdProcessing.Ignore
}
using(var reader = XmlReader.Create("path to xml file", settings)) { ... }
Edit:
Just noticed: your validation type is also set wrong. Try setting it to ValidationType.DTD instead of Schema.
ValidationType at MSDN
--
The error means exactly as it states- the DTD that is referenced is not well formed, as DOCTYPE should be present before any other declarations in a DTD.
Document Type Definition (Wikipedia)
Introduction to DTD (w3schools)
You might be able to get around this by downloading a local copy, modifying it to add in the expected root element yourself, and then referencing your edited version in your source.