How do I make wss4j not create Timestamp element in soap header - cxf

Is there any way to make wss4j not add the Timestamp element from ws-security in the SOAP header?
What I have now is this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Header>
<ns3:Security xmlns="http://docs.oasis-open.org/ws-sx/ws-trust/200512" xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ns3="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:ns4="http://www.w3.org/2005/08/addressing" xmlns:ns5="http://www.rsa.com/names/2009/12/std-ext/WS-Trust1.4/advice" xmlns:ns6="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ns7="http://www.w3.org/2000/09/xmldsig#" xmlns:ns8="http://www.rsa.com/names/2009/12/std-ext/SAML2.0" xmlns:ns9="urn:oasis:names:tc:SAML:2.0:conditions:delegation" soap:mustUnderstand="1">
<wsu:Timestamp xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="Timestamp-1"><wsu:Created>2015-11-18T16:32:21.705Z</wsu:Created><wsu:Expires>2015-11-18T16:37:21.705Z</wsu:Expires></wsu:Timestamp>
<ns2:Timestamp xmlns="http://docs.oasis-open.org/ws-sx/ws-trust/200512" xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ns3="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:ns4="http://www.w3.org/2005/08/addressing" xmlns:ns5="http://www.rsa.com/names/2009/12/std-ext/WS-Trust1.4/advice" xmlns:ns6="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ns7="http://www.w3.org/2000/09/xmldsig#" xmlns:ns8="http://www.rsa.com/names/2009/12/std-ext/SAML2.0" xmlns:ns9="urn:oasis:names:tc:SAML:2.0:conditions:delegation" ns2:Id="_32c97089-04ac-49b0-8758-3d176d110ec7"><ns2:Created>2015-11-18T16:32:19.373Z</ns2:Created><ns2:Expires>2015-11-18T16:42:19.373Z</ns2:Expires></ns2:Timestamp>
..........Truncated
The < wsu:Timestamp > element is being added by wss4j. The < ns2:Timestamp > element is added by a custom timestamp handler.
How do I prevent wss4j from adding the timestamp element so that there is only 1 timestamp(the one added by the custom timestamp handler) in the SOAP header?
Any help would be appreciated!

I'm not really familiar with CXF, but I have used WSS4J with Spring and I guess it is quite similar.
The following snippet can be found on http://cxf.apache.org/docs/ws-security.html:
outProps.put(WSHandlerConstants.ACTION,
WSHandlerConstants.TIMESTAMP + " " +
WSHandlerConstants.SIGNATURE + " " +
WSHandlerConstants.ENCRYPT);
This defines three "securement" actions that you want WSS4J to do, separated by a blank character. You probably have something similar in your config; if you want to get rid of the Timestamp header generated by WSS4J, just remove the WSHandlerConstants.TIMESTAMP.

Related

Dynamic mapping for BeanIO in Camel

I would like to achieve something like below:
from("direct:dataload")
.beanRef("headerUpdater")
.log("Log: " + simple("${in.header.contentType}").getText())
//.unmarshal().beanio(simple("${in.header.contentType}").getText(), "content")
.unmarshal(new BeanIODataFormat(
"file://C://Users//admr229//Documents//mappings.xml", "clients"))
.to("bean:headerFooterValidator")
.split(body())
.process(dataValidator).choice()
.when(header("error").isNotNull())
.to("seda:saveErrorsForReport").otherwise()
.to("seda:updateLive")
.end();
I have commented out the line which I cannot make. I wanted to pass dynamic values from previous endpoint's output to initialize beanio.
Only thing I can think of is using recipient list which will dynamically choose a predefined endpoint. Because, for my case, that endpoint will have unmarshall with beanio, unlike something like "activemq:queue:test", which is purely text.
I hope I have made my question clear. Please let me know if you need any further details.
I am using camel 2.15.2
You can use the data format component [1] where you can specify beanio as the data format, and build the uri dynamic [2]
[1] - http://camel.apache.org/dataformat-component.html
[2] - http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html
you can use do something like this but, again this not dynamic I guess as it need to have properties set before brining up the context.
.unmarshal().beanio(mapping, streamName)

Which token to use for keywords field in metatag module for a node

I want to take the value from metatag keywords field of a node and use it in a sitemap.
I have tried the below token values but nothing has worked for me. Please advice
[node:source:metatag:keywords],
[metatag:keywords],
[node:metatag:keywords],
[node:metatag:news_keywords],
[node:taxonomy-forums:metatag:keywords],
[node:original:metatag:keywords],
[node:field-category:metatag:keywords],
[node:field_search_keyword]
summery about my solution to the same problem - get keywords token -
if another one face it like me 2 hours ago - not drupal bug -
first get all tokens
use devel module or
manually
Get tokens manually
print theme('token_tree', array('node'), TRUE, TRUE);
then token_replace
print token_replace('[node:metatag:keywords]', array('node' => $node));

Salesforce:How to insert value for Goelocation datatype field using java?

I am inserting object into salesforce using REST API. I have one field with Geolocation data-type.
How can inset value to this field using java? My example code is below.
parishud.put("gps__c",?????);
there are two fields to insert(gps(Latitude) gps(Longitude)) but in API i found only one field with name gps__c
HttpClient client = new httpclient.HttpClient();
JSONObject parishud = new JSONObject();
try {
parishud.put("Name","ParishudhTest4");
parishud.put("entitled__c","Yes");
parishud.put("Comments__c","Comments");
parishud.put("fallill_count_after__c","5");
parishud.put("fallill_count_before__c","7");
parishud.put("influencedcount__c","8");
parishud.put("toiletusaseperday__c","3");
parishud.put("parishudhid__c","002");
parishud.put("Received_NBA_Incentive__c","Yes");
parishud.put("Received_NREGA_Incentive__c","Yes");
//parishud.put("gps__c",?????);
PostMethod postaccount = new PostMethod("https://ap1.salesforce.com/services/data/v20.0/sobjects/Parishudh__c/");
postaccount.setRequestHeader("Authorization", "OAuth " + accessToken);
postaccount.setRequestEntity(new StringRequestEntity(parishud.toString(),"application/json", null));
client.executeMethod(postaccount);
The Geolocation field is actually composed out of 3 fields, 2 of which are accessible for us.
If your field name is gps then you can store your data in gps__Latitude__s and gps__Longitude__s (note the double underscore in the beginning like it's a managed package and the ending is "s", not "c").
Make sure you have set profile-level security for your Java integration user to be able to access this field.
If you need code samples - you can check my answer How do I integrate Salesforce with Google Maps? or for example http://blog.internetcreations.com/2012/09/creating-a-geolocation-trigger-in-salesforce-winter-13/

How does Salesforce.com validate Email Fields?

I'm trying to store email addresses in Salesforce.com from another service that allows invalid email addresses to be specified. If one of those bad invalid email addresses is sent to Salesforce.com via their Web Services API, Salesforce.com will prevent the record from saving with an INVALID_EMAIL_ADDRESS error code.
I can't find any documentation on how to disable validation on Email fields, so it looks like I'll need to validate them in my integration and pull out those that fail. Does anyone know the validation process Salesforce.com uses to determine if an email address is valid? All I have right now is a Regex, but I'd like it to match Salesforce.com's process.
EDIT: For reference, here is my Regex (I'm using C#/.NET):
^(\w|[!#$%'*+-/=?^_`\{\}~.&])+#\w+([-.]\w+)*\.\w+([-.]\w+)*([,;]\s*\w+([-+.]\w+)*#\w+([-.]\w+)*\.\w+([-.]\w+)*)*$
Summary: we're using the following .NET RegEx:
const string SFEmailRegExPattern = #"^[A-Z0-9._%-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$";
If you can believe SF's own documentation then:
For the local part of the email address we accept the following characters. The local part is anything before the # sign.
abcdefg.hijklmnopqrstuvwxyz!#$%&'*/=?^_+-`{|}~0123456789
Note: The character dot . is supported; provided that it is not the first or last character in the local-part
For the domain part of the email address we accept. The domain part is anything after the # in an email address:
0-9 and A-Z and a-z and dash -
A couple of people have coded this up as a Java regex as:
String pat = '[a-zA-Z0-9\\.\\!\\#\\$\\%\\&\\*\\/\\=\\?\\^\\_\\+\\-\\`\\{\\|\\}\\~\'._%+-]+#[a-zA-Z0-9\\-.-]+\\.[a-zA-Z]+';
although to me this looks like it fails to reject an email that starts with a "." so isn't perfect.
I don't know how salesforce.com is validating email addresses, but since you are using .NET I'd suggest you to consider an email validation component like our EmailVerify.NET, which is 100% compliant with the current IETF standards (RFC 1123, RFC 2821, RFC 2822, RFC 3490, RFC 3696, RFC 4291, RFC 5321, RFC 5322 and RFC 5336) and does not suffer from ReDoS: if needed, it even checks the DNS records of the email domain under test, its SMTP availability, validates the related mailbox and can even tell if the target mail exchanger is a catch-all or if it is a disposable/free email address provider.
I don't know what salesforce.com uses (and I don't think there's any way for you to find out), but \b[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}\b from here is a commmon one and should work for most of the cases.
I've looked previously and not been able to find a definitive answer on exactly which rules SFDC applies to the native "Email" field type. The quickest path to success that I would suggest would be this:
in your initial data integration from the external application, map the email field that you describe into a new (non-email, just text 255) custom field in SFDC.
if this is a one-time dataload, run a separate process that, for every row in SFDC with this custom field populated, attempts to copy the contents of this custom field to the native email field. If any row fails with the email validation error, you just skip it. Then you can decide what to do with the non-compliant addresses.
if this is an ongoing integration, it may be better to do something like attempt to insert new rows one-at-a-time via WS API, and if the email validation exception is thrown, you catch it and either insert the record without an email address, store the bad email in a different field (like a custom field called "non-compliant email address"), or skip the row altogether (if bad emails == bad record).
Hope that helps.
Apex has native Pattern and Matcher classes, based on java.
You can validate your email addresses in Apex code, using your RegEx expression as a string
String emailPattern = {your regex expression);
Boolean validEmail = pattern.match(emailPattern, emailAddress);
You can't definitely create common regex for salesforce email, due to inconsistency of their own requirements.
The one rule is about to give possibilities to put IP address after the local part. Example -> email#123.123.123.123.
The second is about do not allow digits in top-level domain.
For example: test#test.com1
So, they are mutually excluded.
But as I understood the email address with IP after the local part is more important and commonly used comparing with numbers in top-level domain.
Here is some examples of valid/invalid emails for salesforce.
Valid:
a#ua.fm
email#domain.com
firstname.lastname#domain.com
email#subdomain.domain.com
firstname+lastname#domain.com
email#123.123.123.123
1234567890#domain.com
email#domain-one.com
_______#domain.com
email#domain.name
email#buyacar.co.uk
ail#github.dennis.co.uk
email#news.i.ua
firstname-lastname#domain.com
Alexka1!+1123klsn&*^%$%$#^^^#a3432.4s.c4p.uk
frw...??//||/wt'f`fe#wfwfg-----wfwef.mm
a..#test.jp
abcdefg.hijklmnopqrstuvwxyz!#$%&'*/=?^_+-`{|}~0123456789#acme-inc.com
Invalid:
aasd#sdfжжж.rf
plainaddress
##%^%#$##$##.com
#domain.com
email.domain.com
email#domain#domain.com
.email#domain.com
あいうえお#domain.com
email#domain.com (Joe Smith)
email#domain
email#domain..com
email#domain.com.e
email#domain.com.33
As result of above, the final regex is:
/^(?!\.)(([^<>()\[\]\\a-zA-Z0-9.,;:\s#"]*(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))[a-zA-Z0-9.!#$%&'‘*+\/=?^_{|}~-]+#[\w.-?]+.[A-Za-z]*(?
Here is a regular expression based on this help page + a lot of experimenting in Salesforce:
^(?=(?:\([^)]*\))*[^()]+[^#]*#)(?!(?:\([^)]*\))*\.)(?:(?:[\w!#$%&'*+-/=?^`{|}~]|\([\w!#$%&'*+-/=?^`{|}~]*\))+|"(?:[\w!#$%&'*+-/=?^`{|}~]|\([\w!#$%&'*+-/=?^`{|}~]*\))*")#(?:\([A-Za-z0-9-]*\))*(?:(?:[A-Za-z0-9]+|[A-Za-z0-9]+(?:\([A-Za-z0-9-]*\))*-(?:\([A-Za-z0-9-]*\))*[A-Za-z0-9]+)(?:\([A-Za-z0-9-]*\))*)(?:\.(?:\([A-Za-z0-9-]*\))*(?:(?:[A-Za-z0-9]+|[A-Za-z0-9]+(?:\([A-Za-z0-9-]*\))*-(?:\([A-Za-z0-9-]*\))*[A-Za-z0-9]+)(?:\([A-Za-z0-9-]*\))*))+$
See this Demo. It gives the same validation result as Salesforce for all the values I could think of testing - copied below - any counter examples are welcome...
************* VALID *************
a#a.a
-#a.a
a#1.a
a#a-a.a
a#a.a-a
!#$%&'*+-/=?^_`{|}~#test.jp
a..a#test.jp
a..#test.jp
"a"#test.jp
""#test.jp
(comment)(comment)a(comment)(comment)(comment)#(comment)a.a
(comment)(comment)a.(comment)(comment)(comment)#(comment)a.a
(comment)(comment)a(comment).(comment)(comment)#(comment)a.a
a#(comment)a(comment)-(comment)a(comment).a
john.doe#(-comment)example.com
john.doe#example.com(comment-)
()a#test.jp
(a)a#test.jp
a(a)#test.jp
a#(a)test.jp
a#test.jp(a)
simple#example.com
very.common#example.com
disposable.style.email.with+symbol#example.com
other.email-with-hyphen#example.com
fully-qualified-domain#example.com
user.name+tag+sorting#example.com
x#example.com
example-indeed#strange-example.com
test/test#test.com
example#s.example
"john..doe"#example.org
mailhost!username#example.org
user%example.com#example.org
user-#example.org
1#1234567890123456789012345678901234567890123456789012345678901234.1.2.3.4.5.6.7
************* INVALID *************
a#a
a#a.
a#-a.a
a#a-.a
a#a.a-
a#a.-a
a;a#test.jp
.a#test.jp
";"#test.jp
"#"#test.jp
"a#test.jp
a"#test.jp
a""#test.jp
""a#test.jp
()#test.jp
)(a#test.jp
(a)#test.jp
(a#test.jp
(())a#test.jp
(comment)(comment).(comment)a(comment)(comment)#(comment)a.a
john.doe#(comment).com
a#(comment)a(comment)-(comment)(comment).a
Αθήνα#email.com
admin#mailserver1
" "#example.org
"very.(),:;<>[]\".VERY.\"very#\\ \"very\".unusual"#strange.example.com
postmaster#[123.123.123.123]
postmaster#[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334]

How to export Rich Text fields as HTML from Notes with LotusScript?

I'm working on a data migration task, where I have to export a somewhat large Lotus Notes application into a blogging platform. My first task was to export the articles from Lotus Notes into CSV files.
I created a Agent in LotusScript to export the data into CSV files. I use a modified version of this IBM DeveloperWorks forum post. And it basically does the job. But the contents of the Rich Text field is stripped of any formatting. And this is not what I want, I want the Rich Text field rendered as HTML.
The documentation for the GetItemValue method explicitly states that the text is rendered into plain text. So I began to research for something that would retrieve the HTML. I found the NotesMIMEEntity class and some sample code in the IBM article How To Access HTML in a Rich Text Field Using LotusScript.
But for the technique described in the above article to work, the Rich Text field need to have the property "Store Contents as HTML and MIME". And this is not the case with my Lotus Notes database. I tried to set the property on the fields in question, but it didn't do the trick.
Is it possible to use the NotesMIMEEntity and set the "Store Contents as HTML and MIME" property after the content has been added, to export the field rendered as HTML?
Or what are my options for exporting the Notes database Rich Text fields as HTML?
Bonus information: I'm using IBM Lotus Domino Designer version 8.5
There is this fairly unknown command that does exactly what you want: retrieve the URL using the command OpenField.
Example that converts only the Body-field:
http://SERVER/your%5Fdatabase%5Fpath.nsf/NEW%5FVIEW/docid/Body?OpenField
Here is how I did it, using the OpenField command, see D.Bugger's post above
Function GetHtmlFromField(doc As NotesDocument, fieldname As String) As String
Dim obj
Set obj = CreateObject("Microsoft.XMLHTTP")
obj.open "GET", "http://www.mydomain.dk/database.nsf/0/" + doc.Universalid + "/" + fieldname + "?openfield&charset=utf-8", False, "", ""
obj.send("")
Dim html As String
html = Trim$(obj.responseText)
GetHtmlFromField = html
End Function
I'd suggest looking at Midas' Rich Text LSX (http://www.geniisoft.com/showcase.nsf/MidasLSX)
I haven't used the personally, but I remember them from years ago being the best option for working with Rich Text. I'd bet it saves you a lot of headaches.
As for the NotesMIMEEntity class, I don't believe there is a way to convert RichText to MIME, only MIME to RichText (or retain the MIME within the document for emailing purposes).
If you upgrade to Notes Domino 8.5.1 then you can use the new ConvertToMIME method of the NotesDocument class. See the docs. This should do what you want.
Alternativly the easiest way to get the Domino server to render the RichText will be to actually retrieve it via a url call. Set up a simple form that just has the RichText field and then use your favourite HTTP api to pull in the page. It should then be pretty straight forward to pull out the body.
Keep it simple.
Change the BODY field to Store contents as HTML and MIME
Open the doc in editmode.
Save.
Close.
You can now use the NotesMIMEEntity to get what you need from script.
You can use the NotesDXLExporter class to export the Rich Text and use an XSLT to transform the output to what you need.
I know you mentioned using LotusScript, but if you don't mind writing a small Java agent (in the Notes client), this can be done fairly easily - and there is no need to modify the existing form design.
The basic idea is to have your Java code open a particular document through a localhost http request (which is simple in Java) and to have your code capture that html output and save it back to that document. You basically allow the Domino rendering engine to do the heavy lifting.
You would want do this:
Create a form which contains only the rich-text field you want to convert, and with Content Type of HTML
Create a view with a selection formula for all of the documents you want to convert, and with a form formula which computes to the new form
Create the Java agent which just walks your view, and for each document gets its docid, opens a URL in the form http://SERVER/your_database_path.nsf/NEW_VIEW/docid?openDocument, grabs the http response and saves it.
I put up some sample code in a similar SO post here:
How to convert text and rich text fields in a document to html using lotusscript?
Works in Domino 10 (have not tested with 9)
HTMLStrings$ = NotesRichTextItem .Converttohtml([options] ) As String
See documentation :
https://help.hcltechsw.com/dom_designer/10.0.1/basic/H_CONVERTOHTML_METHOD_NOTESRICHTEXTITEM.html
UPDATE (2022)
HCL no longer support this method since version 11. The documentation does not include any info about the method.
I have made some tests and it still works in v12 but HCL recommended to not use it.
Casper's recommendation above works well, but make sure the ACL is such to allow Anonymous Access otherwise your HTML will be the HTML from your login form
If you do not need to get the Richtext from the items specifically, you can use ?OpenDocument, which is documented (at least) here: https://www.ibm.com/developerworks/lotus/library/ls-Domino_URL_cheat_sheet/
https://www.ibm.com/support/knowledgecenter/SSVRGU_9.0.1/com.ibm.designer.domino.main.doc/H_ABOUT_URL_COMMANDS_FOR_OPENING_DOCUMENTS_BY_KEY.html
OpenDocument also allows you to expand sections (I am unsure if OpenField does)
Syntax is:
http://Host/Database/View/DocumentUniversalID?OpenDocument
But be sure to include the charset parameter as well - Japanese documents were unreadable without specifying utf-8 as the charset.
Here is the method I use that takes a NotesDocument and returns the HTML for the doc as a string.
private string ConvertDocumentToHml(Domino.NotesDocument doc, string sectionList = null)
{
var server = doc.ParentDatabase.Server.Split('/')[0];
var dbPath = doc.ParentDatabase.FilePath;
string viewName = "0";
string documentId = doc.UniversalID.ToUpper();
var ub = new UriBuilder();
ub.Host = server;
ub.Path = dbPath.Replace("\\", "/") + "/" + viewName + "/" + documentId;
if (string.IsNullOrEmpty(sectionList))
{
ub.Query = "OpenDocument&charset=utf-8";
}
else
{
ub.Query = "OpenDocument&charset=utf-8&ExpandSection=" + sectionList;
}
var url = ub.ToString();
var req = HttpWebRequest.CreateHttp(url);
try
{
var resp = req.GetResponse();
string respText = null;
using (var sr = new StreamReader(resp.GetResponseStream()))
{
respText = sr.ReadToEnd();
}
return respText;
}
catch (WebException ex)
{
return "";
}
}

Resources