Precedence Logic using apex - salesforce

I hope you all are doing well. I am beginner to salesforce and I am working on one of the requirement. Below are the details:
I am using SOSL to retrieve accounts based on some condition and need to show an account based on precedence on Status field.
There can be more than 2 accounts as well.
Example 1: If 2 accounts are retrieved by SOSL and both accounts have RETAIN as status, then it should return any of 2 accounts.
Example 2: If 3 accounts are retrieved by SOSL and all of them have different status(RETAIN, GRANTED, OTHER) then it should return account with status as RG
I have tried using so many if-else conditions but results are not expected when there are complex scenarios. I would like to know if there is any approach I can use here using apex?

Related

Ldapsearch and groups and Active Directory

I am trying to get a list of groups/users using ldapsearch.
Most the searches I have seen show that the way to only enabled/active users are to use a query similar to the following:
(&(objectCategory=person)
(objectClass=user)
(sAMAccountType=805306368)
(!(userAccountControl:1.2.840.113556.1.4.803:=2))
(sAMAccountName=<username>))
The issue I am having is I need a list of ALL AD Groups and their Users that are active with the disabled users removed.
Typically I have seen groups pulled with something like this
(&(objectClass=group)(member=*))
This query pulls the groups and users but pulls ALL users disabled and enabled.
What I need is a way to accomplish both.
So far I have tried combining the commands but it has proven to be unsuccessful.
(&(objectCategory=group)
(objectclass=group)
(!(isCriticalSystemObject=TRUE))
(!(userAccountControl:1.2.840.113556.1.4.803:=2)))
Is there a way to accomplish the task of pulling only enabled users while still getting all the groups?
The problem is that by querying groups objectclass=group, you can only filter which groups, not which member (active or not) of those groups, so you would have to intersect the members (all) of each group with the set of active users, which implies another query to grab those users in the first place, and a bit more client code to process the results.
The good news is that AD implements the memberOf attribute, so you can do the other way around, searching for all active users and list the groups they belong to by reading this attribute.

How to restrict user's Solr searching scope based on his/her entitlement

I have data that can only expose to people with entitlement, the data has a meta field call "system", there are hundreds of systems, we have authorized user pre-defined in a database, how can I design the system to allow the authorized user be granted only the data that he or she is entitled to? e.g. if Adam is from Equity team, he can view the search result from system 1-10 and not the rest; if Amily is from Audit team, she can view search result from all systems 1-200.
Thank you very much.
For small-ish number of systems (i.e. where the count doesn't exceed the maximum number of boolean terms in a query), adding a fq=system:(1 OR 2 OR 3 OR 4 OR 5 ... OR 10) is the easiest way to limit the result set - this assumes that the user is allowed to access all fields in the document. Your external system can provide a list of system ids that the user is allowed to access, and you then apply the fq for every request to Solr.
It's important that this is done on every request, since a user can otherwise get exposed to data they should not have access to through facets and other metainformation.
Bloomberg has a nice presentation about how they attacked this problem in one of their 2014 Lucene/Solr Revolution talks - Efficient Scalable Search in a Multi-Tenant Environment - where they went as far down as implementing different access rights for parts of the values in a field.
I think best solution for your query, you can created documents and for each document you can add multivalued field we called it as userAllow.
Whenever you query for solr pass userid in filter query in below way and solr returns only those documents who having rights rights for those users.
if Adam userid is 1 then,
q:(Your Query)
fq:SolrAllow:1
Result set contain only those records having rights for userid 1.
you can also implement it using this way.

Dynamic distribution groups: Which DDGs is user part of?

I know how to get all the members of a dynamic distribution group: I can take the distribution group, get the AD filters from msExchDynamicDLFilter and msExchQueryFilter properties and query the AD for the users who match that filter.
Now, how do I go the other way? E.g. show which dynamic distribution groups a user is part of? Is there any better way than taking all the hundreds of dynamic distribution groups from AD, resolving each of them, one after the other, and looking whether the user is in the resolved list?
No there is not. DDGs where created for Exchange. So upon message submission, the DDGs are resolved.
That being said, you can only retrieve all DDGs, do the queries and check to see which one yield the desired user.

SOLR Permissions / Filtering Results depending on Access Rights

For example I have Documents A, B, C. User 1 must only be able to see Documents A, B. User 2 must only be able to see Document C. Is it possible to do it in SOLR without filtering by metadata? If I use metadata filter, everytime there are access right changes, I have to reindex.
[update 2/14/2012] Unfortunately, in the client's case, change is frequent. Data is confidential and usually only managed by the owners which are internal users. Then the specific case is they need to be able to share those documents to certain external users and specify access levels for those users. And most of the time this is an adhoc task, and not identified ahead of time
I would suggest storing the access roles (yes, its plural) as document metadata. Here the required field access_roles is a facet-able multi-valued string field.
Doc1: access_roles:[user_jane, manager_vienna] // Jane and the Vienna branch manager may see it
Doc2: access_roles:[user_john, manager_vienna, special_team] // Jane, the Vienna branch manager and a member of special team may see it
The user owning the document is a default access role for that document.
To change the access roles of a document, you edit access_roles.
When Jane searches, the access roles she belongs to will be part of the query. Solr will retrieve only the documents that match the user's access role.
When Jane (user_jane), manager at vienna office (manager_vienna) searches, her searches go like:
q=mainquery
&fq=access_roles:user_jane
&fq=access_roles:manager_vienna
&facet=on
&facet.field=access_roles
which fetches all documents which contains user_jane OR manager_vienna in access_roles; Doc1 and Doc2.
When Bob, (user_bob), member of a special team (specia_team) searches,
q=mainquery
&fq=access_roles:user_bob
&fq=access_roles:special_team
&facet=on
&facet.field=access_roles
which fetches Doc2 for him.
Queries adapted from http://wiki.apache.org/solr/SimpleFacetParameters#Multi-Select_Faceting_and_LocalParams
Might want to check the Document level Security patches.
https://issues.apache.org/jira/browse/SOLR-1872
https://issues.apache.org/jira/browse/SOLR-1834
I think my approach would be similar to #aitchnyu's answer. I would however NOT use individual users in the meta data.
If you create groups for each document, then you will have to reindex for security reason less often.
For a given document, you might have access_roles: group_1, group_3
In this way, the group_1 and group_3 always retain rights to the document. However, I can vary what groups each user belongs to and adjust the query accordingly.
When the query then is generated, it always passes as a part of the query the user's groups. If I belong to group_1 and group_2, my query will look like this:
q=mainquery
&fq=access_roles:group_1
&fq=access_roles:group_2
Since the groups are dynamically generated in the query, I simply remove a user from the group, and when a new query is issued, they will no longer include the removed group in the query. So removing the user from group_1 would new create a query like this:
q=mainquery
&fq=access_roles:group_2
All documents that require group 1 will no longer be accessible to the user.
This allows most changes to be done in real-time w/out the need to reindex the documents. The only reason you would have to reindex for security reasons is if you decided that a particular group should no longer have access to a document.
In many real-world scenarios, that should be a relatively uncommon occurrence. It seems much more likely that HR documents will always be available to the HR department, however a specific user may not always be part of the HR group.
Hope that helps.
You can implement your security model using Solr's PostFilter. For more information see http://searchhub.org/2012/02/22/custom-security-filtering-in-solr/
Note: you should probably cache your access rights otherwise performance will be terrible.
Keeping in mind that solr is pure text based search engine,indexing system,to facilitate fast searching, you should not expect RDMS style capabilities from it. solr does not provide security for documents being indexed, you have to write such an implementation if you want. In that case you have two options.
1)Just index documents into solr and keep authorization details into RDBMS.Now query solr for your search and collect the results returned.Now fire another query to DB for the doc ids returned by solr to see if the user has an access to them or not.Filter out those documents on which user in action has no access.You are done ! But not really, your problem starts from here only.Assume, what if all results returned by solr gets filtered out ? (Assuming you are not accessing all the documents at a time,means you are retrieving top 1000 results only from solr result set,otherwise you can not get fast search) You have to query solr again for next bunch of result set and have to iterate these steps until you get enough results to display.
2)Second approach to this is to index authorization meta data along with document in solr.Same as aitchnyu has explained.But to answer your query for document sharing to an external user,along with usergroup and role detail, you index these external user's userid into access_roles field or you can just add an another field to your schema 'access_user' too. Now you can modify search queries for external user's sharing to include access_user field into your filter query.
e.g
q=mainquery
&fq=access_roles:group_1
&fq=access_user:externaluserid
Now the most important thing, update to an indexed documents.Well its off course tedious task, but with careful design and async processing along with solrs partial document update feature(solr 4.0=>), you can achieve reasonably good TPS with solr. If you are using solr <4.0 you can have separate systems for both searching and updates and with care full use of load balancer and master slave replication strategies you will have smile on your face !
There are no built in mechanisms for Solr that I am aware of that will allow you to control access to documents without maintaining the rights in the metadata. The approach outlined by aitchnyu seems reasonable if you keep it a true role level and not assign user specific permissions to a document. That way you can assign roles to users and this will grant them the ability to see documents in the index. Granted you will still need to reindex documents when the roles change, but hopefully you can identify most of the needed roles ahead if time and reduce the need for frequent reindexing.

Is it possible to LDAP query users common to a set of groups

I need a list of all the users common to a known collection of groups, using a single LDAP query of our Active Directory. It would seem, from the our reading so far, that such is not possible, but I thought it best to ask the hive mind.
Try this:
(&(objectCategory=Person)
(&
(memberOf=CN=group1,dc=company,dc=local)
(memberOf=CN=group2,dc=company,dc=local)
(memberOf=CN=group3,dc=company,dc=local)
)
)
This is similar to my question, except there I wanted all users who were NOT members of groups. You'll need to delete all the whitespace for most query tools to work.
Yes it's possible with an attribute scoped query. It requires W2K3 AD or later but will give you the all of the users that have a particular attribue i.e. membership in a group or in your case multiple groups (intersection of groups). One of the best examples is from Joe Kaplan and Ryan Dunns book "The .NET Developers Guide to Directory Services Programming" for AD work it's hard to beat look at page 179 for a good walk through.
Caveat:At this point you are past trivial searches in AD and a number of things are becoming important like the search root, scope and the effect of searching through some potentially HUGE set of data for the items you want. Looking through 50 or 60K users to find the members of a group does have an effect on performance and be prepared to do paged results or similar in case the dataset is large. Kaplan/Ryan do an excellent job of down to earth work to get you where you need to be. That said, I have used them on two AD projects with great success. Being able retrieve the data from AD without recursive queries is VERY worth while and I found that it is fast as long as I control the size of my dataset.
It's not possible in a single query if your groups contain nested groups.
You would need to write some code that recursively resolves the group members and does the logical equivalent of an "inner join" on the results, producing a list of users that are common to all the original groups.

Resources