I'm trying to test if items can be viewed by an anonymous user:
var anon = User.FromName("domain\\Anonymous");
if (item.Security.CanRead(anonymousUser))
return true;
But it always returns true, even when I know that for particular items, they must have a certain role to view it, as I can see from the access viewer:
The responsible crawler -which actually executes ComputeFieldValue code- is designed in such way to wrap this code in a SecurityDisabler. That is why it is not possible inside a computed field to verify whether has access to the field or not.
Sitecore does recommend to do the security check during the search (ootb) but indeed the TotalResults do not match if you do - which sucks ;)
If you would try to get security in the index - first try to find a solution for keeping the item security updated. E.g. if you would break inheritance somewhere, how would your index know what items to update? ...
Related
I have tried finding an answer to this question practically everywhere I could imagine, including here on StackOverflow. Unfortunately to no avail. So here it is.
I'm working on an Outlook Add-in (with Outlook 2021), and have developed some code that creates some ItemProperties specifically for use with that add-in. Now, when those properties are created, I can see them when I go to View->Settings->Advanced View Settings->Columns, as illustrated in the screenshot.
Screenshot of User-defined fields in Outlook
In some cases, though, I want to completely delete the properties. And as I know how to do that manually, as pointed out in the figure, I can't find out how to do that programmatically via C#. I have gone that far as to remove the properties from each mail containing that kind of property, like this:
IEnumerable<MailItem> listOfAssignedEmails = itemsToProcess.Where(
t => t.ItemProperties[MailExpiration.ExpirationDatePropertyName] != null);
foreach (MailItem email in listOfAssignedEmails)
{
// Note: The Delete() operation is deprecated. A more up-to-date method must be found.
email.ItemProperties[MailExpiration.ExpirationDatePropertyName].Delete();
email.Save();
}
... and yes, I know that the Delete() operation is deprecated; however, I couldn't find another method for removing the ItemProperty from the email (any suggestions are welcome).
Basically, the deletion of this Property is only going to be done very rarely (t. ex. if the user chooses to uninstall the Add-in. However, if there's any way to remove that property automatically, I would be happy to know.
Any suggestions will be greatly appreciated.
It is really a bad idea to remove a custom property from all emails that already have it: there is really no point since the user will never see them, but you will have to retouch (and thus change the last modified date) of a large number of emails.
Also note that named properties in MAPI are a finite resource - you can have at most 64k of them in a mailbox. Once a particular property mapping is used, you can never unmap it, even if there are no items that use that property.
Thirdly, doing anything Outlook related from an installer (rather than a VSTO addin) is a really bad idea - Windows installer runs in a service.
If you want to make sure the user no longer sees your custom fields as available properties in a view, you need to deal with the folder fields - they ar stored in a blob in a hidden (associated) message in that folder. OOM does not expose folder fields at all (if you don't count the AddToFolderFields parameter when calling UserProperties.Add). If using Redemption is an option (I am its author), it exposed RDOFolderFields object (accessible from RDOFolder2.FolderFields property) that allows to add or delete folder fields.
The list of properties shown on the screenshot belongs to the Folder.UserDefinedProperties property which returns a UserDefinedProperties object that represents the user-defined custom properties for the Folder object.
Use the ItemProperties.Remove method removes an object from the collection (from an item).
Use the ItemProperties property to return the ItemProperties collection. Use ItemProperties.Item(index), where index is the name of the object or the numeric position of the item within the collection, to return a single ItemProperty object.
We use the Cache object as a flag to identify if a certain username is already logged in.
System.Web.HttpContext.Current.Cache.Insert(SessionObjects.CurrentUserId.ToString(), Session.SessionID);
There is a action filter which basically checks if this item exists in the cache. If it does then the user is logged out
However sometimes I'm finding this object miraculously disappears and causes null exceptions when trying to retrieve it from the cache within the action filter.
I notice we don't seem to specify any expiration/ dependency specifics. Given the sample code above, are there any conditions where .net could of removed this entry for me without my permission?
May sound like a dumb question but here goes.
I instantiate a LIST from my homepage, the list is in a global class file, and returns all the information about the person logging in. the person, could have one or more accounts associated with the site, and therefore i need to code against a default flag to display their default account informaiton. However, i then also need to build their other account information and display this for them.
The additional account(s) are listed in a drop down box. when the drop down box fires off, instead of calling out to the class again, and retrieving all the necessary information, as i've already done this once, how can i store the object, so that it can be used?
I've looked at Session Variables, but this gets a bit messy (I have 35 fields being returned in my list), plus, the Session variables only get set the first time around, not on DDL changed.
therefore, I need a way of having quick access to the object. - what's the best approach?
As per me , Session is the best possible object for your type of requirement and on DDL changed event try to rebind the Session object with new modified values
I'm building a DAL for a widget-based reporting application, its been designed in such a way that users pick, configure and deploy reporting 'widgets' to their home screens. Widgets can report across various kinds of company data - sites, brands, employees and so on.
Whilst all users can access all the widgets/reports, all users are not authorised to access all data. If I work for Company-A I can't view sales reports for Company-B or staff attendance data for a salesman at Company-C, however I can configure such a report and add it to my 'dashboard'.
At runtime, an intermediate 'DataService' class has the job of checking the user's credentials and, if access is permitted, returning the appropriate object collection to the client.
On the initial build I just returned an empty List if access to the data was not allowed, but this is also what I do if no data is returned by the report (which can happen). I'd like to show an 'Access Denied' message on the front end if the user isn't authorised to view the data but obviously if all I get back in either eventuality is an empty collection its impossible to know if this was because of insufficients rights or just no data.
I'd be grateful if you could suggest a way of coding around this, my first thought was to move the credential-checking into another object which in turn calls the data access class but time constraints mean this isn't an option.
The only thing I can think of, which goes against everything I've ever learnt, is to throw a custom exception e.g. InsufficientApplicationPrivilegeException if access isn't granted, but this smells bad.
Thanks for reading.
I think you have a couple of options. One is to make a composite object that your data service class returns. The composite object looks something like this: -
class DataResult<T>
{
IEnumerable<T> Data;
Result ServiceResult;
}
ServiceResult contains metadata about the outcome of your service call - it could be an enum which contains e.g. Success, AuthenticationFailure etc. etc.. You can then switch on this in order to do different behaviour.
An alternative option might be to use the NullObject pattern that shows a single item of data in the view which instead of real data simply shows "Access Denied" for the display properties of the object. The advantage of this approach is that your front-end doesn't need to have any conditional logic etc.; however if you want to show a specific message box or similar rather than just displaying a dummy row of data in your widget, then this probably isn't appropriate.
I'm writing a workflow that needs to perform certain actions depending on which fields are changed when someone edit's an item. For example, if a user goes in and removes a role (job) from an item (staff member) then I need the workflow to realise that the role field was changed, deduce which role was removed (or potentially added) and then notify the manager of that role and do any other necessary tasks. Another example would be if the address fields in an item get changed then the appropiate HR department need to be notified of the change.
To do this I'm going to try a code block when the workflow is started that compares the top two history entries and any fields that differ will be flagged as changed and I'll take the appropriate actions dependent on each field.
Could anyone please tell me what the other options are for getting this functionality as I'd like to know if there's a better way. Thanks
Using SPD workflows it would not be that hard, depending on number of roles.
Create a column and then go into the content type and hide it. Create a SPD workflow that executes on new or change. Compare the hidden column and the one the user entered, if changed compare values against a role name and do what needs to be done. When that is done copy the user entered column into the hidden column.
Ugly and long but if you don't have the abaility to get workflow code implemented on the server, thanks corporate IT, then it is an option.
I would enable versioning on the list and then use:
SPListItem currentItem = workflowProperties.Item;
SPListItemVersion previousItemVersion = currentItem.Versions[1];
//Compare the fields in currentItem and previousItemVersion
But if i understand your question correctly, that’s what you’re about to do already.