What does DirectorySynchronizationOptions.PublicDataOnly mean? - active-directory

There is a PublicDataOnly member in the DirectorySynchronizationOptions enum.
On MSDN it says "Do not return private data in the search results".
What does the "private data" here means?
I tried to get all users with DirSync in given domain with and without this PublicDataOnly option and set the PropertiesToLoad as "*". Same set of attributes and users are returned.

Found it from the AD technical spec:
http://msdn.microsoft.com/en-us/library/cc223347.aspx
PublicDataOnly has no effect :).

Related

cloud firestore role based access example: can user create a comment?

While reading the cloud firestore role based access example https://firebase.google.com/docs/firestore/solutions/role-based-access#rules, step 4, I find it not clear whether the user can create a comment or not.
According to the above link, the comment is owned by a user, here is the data model:
/stories/{storyid}/comments/{commentid}
{
user: "alice",
content: "I think this is a great story!"
}
And the rules:
match /comments/{comment} {
allow read: if isOneOfRoles(get(/databases/$(database)/documents/stories/$(story)),
['owner', 'writer', 'commenter', 'reader']);
// Owners, writers, and commenters can create comments. The
// user id in the comment document must match the requesting
// user's id.
//
// Note: we have to use get() here to retrieve the story
// document so that we can check the user's role.
allow create: if isOneOfRoles(get(/databases/$(database)/documents/stories/$(story)),
['owner', 'writer', 'commenter'])
&& request.resource.data.user == request.auth.uid;
}
Note the last line of the rules, to create the comment, the authenticated user (request.auth.uid) has to be the user who is the owner of the comment. However, before even create this comment, how can this user property exist? Maybe, when create the comment, do not require the last segment of the rule "&& request.resource.data.user == request.auth.uid". But when update the comment, can add this rule.
Did I miss anything? Btw, do they actually test examples before using them for online reference? It is also a pity that there is no timestamp when these online documents are created. I was told nowadays things two years old can be obsolete.
The request.resource variable contains the document as it will exist after this operation is completed (assuming it is allowed). So request.resource.data.user is the value of the user field that the operation is trying to write, not the value as it currently exists (that'd be resource.data.user, without request.).

How do you check in code if a request matches an EPiServer Visitor Group

We've set up a new "visitor group" in EPiServer 6r2, and we want to add a css class to the <body> tag of the site if the user is in that group, so different groups get different site designs. I'm trying to find out if the current visitor is in a matching group in the code-behind of a masterpage file in order to add this extra class and can't get the below code to return anything but false.
I'm not sure if the role name mentioned is the name you enter in the CMS UI when adding a visitor group.
Paul Smith blogged a proposed solution to this but I haven't been able to get it to return anything but false yet, and judging by the only comment on the blog article I'm not alone. Code sample #1 from this link (which is the one I'm using):
using EPiServer.Personalization.VisitorGroups;
...
bool match = EPiServer.Security.PrincipalInfo.CurrentPrincipal
.IsInRole("My Visitor Group", SecurityEntityType.VisitorGroup);
I found the developer guide to membership and role providers which states that replacePrincipal must be set to true for the correct principal to be in place. I checked and this is already the case for my config.
Documentation
EPiServer 7 doc
IPrincipal.IsInRole() extension
SecurityEntityType enum
Oddly I searched the 6r2 documentation from http://sdk.episerver.com/ and can't find the documentation for IPrincipalExtensions at all, even though I see the class in object browser in 6.2. in my sln. Details: Assembly EPiServer.ApplicationModules - C:\Windows\assembly\GAC_MSIL\EPiServer.ApplicationModules\6.2.267.1__8fe83dea738b45b7\EPiServer.ApplicationModules.dll - public static bool IsInRole(this System.Security.Principal.IPrincipal principal, string role, EPiServer.Security.SecurityEntityType type)
Member of EPiServer.Personalization.VisitorGroups.IPrinicipalExtensions
Please comment if you spot errors or I've missed anything as coding for EPiServer is a bit of a fog-of-war affair and I'm a little battle-weary.
Found it by browsing the object model and guessing. So much for documentation.
using EPiServer.Personalization.VisitorGroups;
using EPiServer.Security;
const string visitorGroupName = "Some users";
var groupHelper = new VisitorGroupHelper();
bool isPrincipalInGroup = groupHelper.IsPrincipalInGroup(
PrincipalInfo.CurrentPrincipal, visitorGroupName);
Tested and working in EPiServer 6r2 (aka 6.1).
String visitorGroupName must match the string entered into the "Name" box on the EPiServer admin interface when creating / editing the visitor group. See screenshot below:

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 do I import Active Directory users into JIRA only from specific groups?

A caveat to begin with - I don't actually know if what I want to do is possible, particularly because I'm not well versed with LDAP/Active Directory or JIRA.
I'm trying to integrate my shiny new installation of JIRA with my existing active directory. What I want to do is set up some specific JIRA groups (e.g. in London\Security Groups\JIRA*) and then have JIRA only import the users who have membership of those groups. However, in the directory set up page in JIRA, I don't understand how to do this. It seems to indicate that I can import users and groups, but not users from groups.
What am I missing? (apart from expert level knowledge of AD!)
Update
Under my domain, I have an organisational structure like this:
London\Users
London\Security Groups\JIRA
Under the latter organisational unit, I have a security group called "jira-users". The former contains all users.
So far I've tried the following queries and none of them have worked :
(all prefixed with &(objectCategory=Person)(sAMAccountName=*)")
memberof=CN=jira-users,ou=London,ou=Security Groups,ou=JIRA,dc=mycompany,dc=local
memberof=CN=JIRA,ou=London,ou=Security Groups,dc=mycompany,dc=local
(prefixed with just &(objectCategory=Person)")
memberof=CN=jira-users,ou=London,ou=Security Groups,ou=JIRA,dc=mycompany,dc=local
Completed
The query that works is this :
memberof=CN=jira-users,OU=JIRA,OU=Security Groups,OU=London,DC=mycompany,DC=local
I hadn't realised that for a folder structure that is logically, left to right, London\Security Groups\JIRA, the organisational units need to be listed in reverse order.
Further Update
This only works when using the DirectorySearcher class for some reason, e.g.
DirectoryEntry rootEntry = new DirectoryEntry("LDAP://dc=mycompany,dc=local");
DirectorySearcher srch = new DirectorySearcher(rootEntry);
srch.SearchScope = SearchScope.Subtree;
srch.Filter = "(&(objectCategory=Person)(sAMAccountName=*)(memberof=CN=jira-users,ou=London,ou=Security Groups,ou=JIRA,dc=mycompany,dc=local))";
SearchResultCollection results = srch.FindAll();
This doesn't work in the LDAP explorer tool and subsequently, not in JIRA itself.
Last Update
So...for JIRA, you need to reverse the order AND remove the wildcard. Working query in the end is :
(&(objectCategory=Person)(memberof=CN=jira-users,OU=JIRA,OU=Security Groups,OU=London,DC=mycomapny,DC=local))
When you are setting up the user directory look under the User Schema settings. You should see a "User Object Filter" field. In there you should be able to add something like this:
(memberOf=cn=jira-users,ou=London,dc=mydomain,dc=com)
This will allow you to filter based on a specific LDAP group. Of course you will need to edit the values above to reflect your own environment.

How to get LDAP unboundid AttributeSyntax?

I'm trying to find out the unboundid AttributeSyntax type for a specific attribute name and it's simply not working.
Here's the example test code that I'm using to achieve this:
#Test
public void testLDAPSchema() {
try {
LDAPConnection connection = new LDAPConnection();
connection.connect("hessmain", 389);
connection.bind("CN=Administrator,CN=Users,DC=FISHBOWL,DC=NET", "password");
Schema s = connection.getSchema();
System.out.println(s.toString());
AttributeTypeDefinition atd = s.getAttributeType("directReports");
Set<AttributeTypeDefinition> oat = s.getOperationalAttributeTypes();
Set<AttributeSyntaxDefinition> l = s.getAttributeSyntaxes();
AttributeSyntaxDefinition asd1 = s.getAttributeSyntax(atd.getOID());
AttributeSyntaxDefinition asd2 = s.getAttributeSyntax(atd.getSyntaxOID());
AttributeSyntaxDefinition asd3 = s.getAttributeSyntax(atd.getBaseSyntaxOID());
connection.close();
} catch (Exception e) {
Assert.fail(e.getMessage());
}
}
From the above code, all the sets are empty. This also means that no matter which OID I pass to the schema getAttributeSyntax method that I will simply get a null return.
Is there any reason why I can't get the attribute syntaxes from an Active Directory server schema?
Thanks
I don't think that this is specific to the UnboundID LDAP SDK for Java. I'm not sure that Active Directory exposes this information over LDAP. When I perform a general LDAP search to retrieve schema information, I can see the attributeTypes and objectClasses attributes, but ldapSyntaxes isn't returned (and in fact ldapSyntaxes doesn't appear in the list of attribute types).
Similarly, none of the attribute type definitions includes a USAGE element, which is what is used to indicate that the attribute type is operational (e.g., "USAGE directoryOperation").
It may well be that Active Directory simply doesn't report this information at all. It could be that it provides some other non-standard way to get this information (e.g., a control or extended operation, or some other entry that can be retrieved), but if there is then I don't know about it.

Resources