Can you restrict the access on a custom field type? - sharepoint-2010

I want to create a custom field type (MyCompLookup) that will be used in lists that all users will have access to. However, the field type will be fairly complicated / confusing to a regular user who is creating a simple list in their department's site. Is there a way to restrict certain users from selecting the custom field when they are creating columns for their lists?

I'm afraid you can't set ACL on field types.
A few things you can do to achieve some kind of workaround:
Add a custom logic in SPField OnAdded method that removes the field immediately after it was added by a regular user. This method might be very confusing for users, so at least you should give a descriptive name to your field. You can find a similar solution here, where I add extra fields to the list in this method.
You can add a custom editor control (see a simple sample here) to your field, that interactsts with other controls on the add new field page, for example disables the OK button.
Hope it helps.

Related

Why sub resources need to be prepended with resource in URI?

Having a doubt on REST API URI design.
Let's consider each Post has one or more tags. So, a tag could be retrieved by
GET /posts/1/tags/1
Tags are stored uniquely in DB with an ID. So I could access full detail of a tag using
GET /tags/1
If Post information needed, then I could use query parameter
GET /tags/1?post=1
My question is why the first format widely suggested over second/third format.
Suggest me use case/scenario to prefer first format or complications with second/third format.
why the first format widely suggested over second/third format.
This is not the case. The three are used for different things.
You must first ask if a tag can exist without a post. I'd say yes. Because of this, the second form
GET /tags/1
is a good URI to get the representation of a tag.
Next, ask yourself if a post can have multiple tags. I'd again say yes. Because of this the first form is a good way to get a specific tag of a post. More general, the form
GET /posts/1/tags
returns all tags that are used for post 1. This is a collection resource. One of those tags is tag 1 which can be navigated to by
GET /posts/1/tags/1
Note that the first and the second form both identify tag 1. Both forms can be used at the same time.
The third form makes no sense at all. Query parameters after the ? like post=1 are generally used to filter a collection resource. One could say: "Give me all tags that are used on posts 1, 23, and 42. This could be formulated as
GET /tags?post=1,23,42
Here we filter the collection resource of all tags by a condition.
Your third form uses a query parameter post=1 on a single resource. But it makes no sense to filter a single tag.
A fourth form could be useful: Give me all posts that use a tag:
GET /tags/1/posts
This would return the collection resource of all posts that use tag 1.
And even a fith form with the same meaning as fourth would be possible:
GET /posts?tag=1
Summary:
When thinking about REST URIs, think about resources. What are your resource? What are the relations between them? Can one type of resource exist only "inside" another type of resource (a hotel room can only exist inside a hotel) or can it exist on its own (a tag can exist even if not post is tagged with it). What could be a subresource of another resource? What collection resources exist? How can they be filtered?

Is it possible to restrict part of an Ektron smart form to a specific user group?

Is it possible to restrict part of a smart to only a certain user group and if the user trying to edit the smart form content is not of that group, then the user cannot change that portion of the content?
Example:
Let's say I have an Employee smart form with fields for EmployeeBio, EmployeeHireDate, and EmployeeDept. Would it be possible to allow the general author user group to be able to edit the EmployeeBio field, but restrict the EmployeeDept and EmployeeHireDate fields to only an HRAdmin user group?
If it helps, I am using Ektron 9.00 SP3.
As far as I know, you either can edit a content block or you can't; there isn't a way to subdivide permissions on a per-smartform-field basis.
What you can do, is group the "restricted" fields into their own smartform, and then reference that via a content resource selector field.
So your Employee smart form might look like this:
/root/txtName (not in your example, I know...)
/root/rtfBio
/root/cresHRID
Side note: I'm using hungarian notation on my field names here. txt indicates a plain text field, rtf indicates a rich text (html) field, and cres indicates a content resource selector.
Then you could have a second smart form... let's call it "EmployeeHR", and it would have the following structure:
/root/hireDate
/root/txtDepartment
That would, in theory, work. However, I must say that I really don't like splitting up this particular type of data in this way. First, department feels like it would function better as a taxonomy to which you could add the content block. Second, it feels like this type of data would be better served by housing it outside of ektron and then using a DxH (Digital Experience Hub) connector to bring the data into Ektron. This way the external system could handle permissions at a more granular level, and you would still have access to the data within Ektron for use elsewhere within the site.
UPDATE
As I ponder this question some more, another option comes to mind. You could write an ASPX page or UserControl that checks to make sure you're logged in and a member of a particular group before presenting you with a custom edit screen. The following code will check if the current user is a member of the admin group; you can swap out a different group id to fit your needs:
// Not sure off hand which of these using statements provides access to EkConstants...
using Ektron.Cms;
using Ektron.Cms.Common;
using Ektron.Cms.Content;
var userGroupApi = new Ektron.Cms.Framework.User.UserGroupManager();
var isInGroup = userGroupApi.IsUserInGroup(currentUserId, EkConstants.g_AdminGroup);
This could be implemented as an ASPX page on your site, or it could be implemented as a widget and placed on the user's Smart Desktop tab of the workarea. Either way, you have a lot of options for getting what you want, just nothing "out of the box".

Can you get the field base name instead of the translated name when using the JIRA rest api?

The JIRA rest api documentation suggests that you should use the field name when sending in a custom field for a create issue request, because they are not unique across instances.
However, the field names you receive from calling the meta-data on a project are translated based on the language settings of the user. That also means that the field names are subject to change, because translations are controlled by the client.
Is there any way to recover the field's base name (which is not changeable) rather than the field's translated name, when calling the createmeta function?
(Or another best practice for determining which custom field you need to set which data to?)
I think you Can Not.
In my recent plugin I had to add fields to the settings screen to map Epic Name and Epic Link:
- Epic Name custom field name:
- Epic Link custom field name:

different permissions based on workflow state

I need to set up different permission on an object based on its workflow state. For instance, 'manager group' can edit the object only if state=draft but 'super manager group' can edit it also if state=validated.
It seems that's not possible using ir.model.access and I'm evaluating if it could be done using ir.rule. It seems not...
Is there a official way to get this or do I need to implement this feature (maybe by adding a condition into ir.model.access machinery).
This is not possible by default with ir.model.access, because this permission model is designed to act like simple Unix permission on CRUD operations, and it is statically defined, per-model and per-group.
You may be able to implement something like this using ir.rule, as it implements dynamic per-record access control based on field values. By having a set of rules defined only on the write and unlink operations and based on the state field, you will be able to prevent some groups from modifying records in certain states. By using the technique of an always-true rule [(1,'=',1)] you can then relax a non-global rule for users who have a "super-access" group. See also this answer.
This option will have important caveats however:
Be careful not to make those rules apply for read, as it will make the records completely disappear, and generally wreak havoc in your processes
The interface will not become read-only when the rule is in effect, and if you want to make the fields and buttons read-only you will have to find a way to specify this via attrs in a manner that depends on the user's groups. See also this Launchpad question.
the Save button in the UI will not be disabled
The standard error reporting in case of ir.rule restriction is not very clear, so it will certainly confuse users (note: it's being improved for 7.0)
As you see, using ir.rule filters for this purpose is far from a perfect solution, and you will first need to find appropriate solutions for the above issues.
Ultimately, you might have an easier task of implementing your own logic for this, plugging a new mechanism in the ORM primitive API methods: fields_view_get (for making fields dynamically read-only based on the user groups) and the CRUD methods (for actually restricting the operations)
There is another way instead of hacking web-client.
You can always have 2 views for the same Object .
For manager group.
For super manager group.
In manager group you can use attrs = {'readonly': [('state', '!=', 'draft')]}
or any condition as you needed.
And in the same way in super manager group, you can put his condition for fields.
I have this feature working on a production environment, using just Record Rules: in Project Issues, "basic users" can create and cancel issues, but can't open or close them.
Despite the GUI limitations mentioned by #odony, it works perfectly.
These are the Record Rules used::
There is a special case that needs attention: changing from a read-write State to a read-only State:
In the action's method, if the the State is changed after other write operations, the user will be able to change the State; but if there are some write operations after the State update, the user will not be able to change State.
In my example, the Project Issue method to Open an issue is case_open(). It first changes State and then does additional changes, like settting Open Date, User and Message history. Because of this, basic users can't Open issues. If you want them to be able to do so, case_open() must be overridden so that it changes State after all other write operations are done.
I got a similar requirement...
My requirement was to make a char field(say "test_123") readonly in the sale.order if the user comes under the group "sale user" otherwise editable for the group "Sale Manager".
That is, if the sale order is in draft state then anyone can edit, but it the sale order is confirmed then this field "test_123" is only editable for "Sale Manger"
What I did is I added a functional field (is_group_manager) which returns True if the user comes under the group "sale manager" and the state is not "draft" otherwise false.
Then in the xml view I added the field "test_123" with attribute attrs="{'readonly':[('is_group_manager','=',0)]}"
for example
<field name="is_group_manager" invisible="1"/>
<field name="test_123" attrs="{'readonly':[('is_group_manager','=',0)]}"/>
This will work only in openerp v6.0. Maybe this will be helpful for you. :)

How to associate calculated values to an object

I have some basic objects like Customer, Portfolio and ... with some association to other objects. I can easily display the required information in the web page by reading object values. The problem is that what do I do when the value associated with the object is calculated and returned by a method, a value that makes sense only in certain context and cannot be attached to the object as an instance variable? In this case if I have a list of say Users I have to pass the username of each user to the method to get the calculated value. This causes problem to keep the association while displaying the values in the page.
An example to make this clear:
An application provides the functionality for users to keep track of each others activities by letting them add whoever they want to a list. If this user performs a search on users there's the option to follow each returned user. I want to make sure this option is disabled for those user's that are already being followed. This functionality is provided by a method like isFollowed(String follower, String followee) which returnes a boolean. How can I associate this boolean values to each user in search result?
Solutions:
One thing I can think of is to add a followed instance variable to User class. But I don't think it's a good approach because this variable only makes sense in a certain context. It's not a part of User class in the domain.
The other way I can think of is to use Decoration or Wrappers in a way to extend the User class and add the attribute in the child class. But again what if I have several objects that need to be in the same context. In that case I have to extend all of them with the same boolean attribute in all classes.
I hope I could make it clear.
In principle, I don't see anything wrong with instance method on User: bool IsFollowedBy(User user).
Of course, this could lead to performance issues. If that is the case, you can create separate object for presentation purposes which bundles data from User and whether he is being followed by the user performing search. Then you can build query which retrieves all necessary data for such object in a single roundtrip to DB.
One solution is to avoid querying Entities (as in DDD/ORM) and query directly using subquery/join or even using some denormalized database. This is something CQRS pattern suggests.
Other solution is to do computations on application layer (how many Users can you show on the same page anyway), which is expensive but you can implement some caching techniques to make things easier.