I've got a question about the best way to allow user's information to be visible between users in certain situations.
I have certain columns in User class which are private to the user.
In some activity i'm pointing to user object as 'postedBy' or something else,In this case the entire data regarding user is getting shared.
My question is how to restrict user to get some columns in User class??
usually if you want to restrict an access in parse it should be done via ACL. In ACL you can create role for users who can read/write to the class.
ACL are executed on a class level and not on a column level. In order to expose part of the fields i think you have 2 options:
Create one to one realtionship from your User class to another Class. the second class will contain all columns that not all users can see and for this class create ACL's with the users/roles that can view this data and when you will execute your query only the users with sufficient permissions will be able to get this data
The second option is when you want to avoid relationships here you can use the select option under query. Select allows you to select specific fields of the class and the query will return only the fields that you specified under the select. here is a code snippet from parse docs which explain how to use select (in JS):
var GameScore = Parse.Object.extend("GameScore");
var query = new Parse.Query(GameScore);
query.select("score", "playerName");
query.find().then(function(results) {
// each of results will only have the selected fields available.
});
Hope its clear now :)
Related
I have entity "Work Order" for which I have defined many custom views. Work Orders can have records with statuses as "active ,cancelled, closed, inprogress, submitted" etc. My requirement is - currently logged in user who belongs to a specific team "sales representative" should be able to see all records on view.This can be done easily, but If current logged in user does not belongs to "sales representative" team, she should not be able to see "cancelled" records on view but all other record should be visible to her. How can I achieve this using custom filters if it is possible? Or by code changes?
It is possible to do this with custom code. Without questioning the "why" you'd like to do this (possibly it's sensitive information or something?), you can achieve it using a RetrieveMultiple plugin registered on the pre-operation event. Within this plugin one of the input parameters passed in is called "Query" and will have a QueryExpression. You can simply add a filter to this query in the plugin and the relevant rows will be filtered out. Something like this:
var query = (QueryExpression)context.InputParameters["Query"];
var condition= new ConditionExpression()
{
AttributeName = "statuscode",
Operator = ConditionOperator.NotIn,
Values = { 2, 3 } // Or whatever codes you want to filter!
};
query.Criteria.AddCondition(condition);
To check the current user you can grab the user id from the plugin context and retrieve the necessary info you would like to check.
Doesn't sound like this is possible with advanced find alright. You may be able to achieve it using security roles though. If you could assign cancelled work orders to a specific team, and then organise your security setup so that users who are not sales representatives can't see work orders from that specific team, then it might work. Unfortunately you would have to reassign the cancelled work orders which is not always an option.
Otherwise, you might have to go with a separate view for cancelled work orders, out of the box advanced find should allow you present a blank grid of you are not on the right team. But now obviously you are not presenting a whole view of the work orders.
In general I would go with the security option, and just make it work. Any other option is just a stop-gap. Users can always create custom views, so if you don't lock down access using security roles, the data is still accessible in indirect ways.
Does Service Now allow querying referenced fields through the GlideRecord? And if so, how?
I have an application with a local user table for preferences specific to the application. When a user fills out a new form, I would like to query the local user table to see if a record exists for the currently logged in user. If it does, then I would like to prefill some of the answers on the form.
My user table has a reference to the sys_user table in order to link the local user record to the actual service now user. When I try to run the script to check the local user table, it returns "sys_idNotValidnull" for the query statement I add.
var lscUser = new GlideRecord('x_wadm_lsc_user');
lscUser.addQuery('UserID', '=', gs.getUserID());
gs.info("Query: "+lscUser.getEncodedQuery());
lscUser.query();
Returns: "Query: sys_idNotValidnull"
If I change the query to search a different string field it works as expected.
var lscUser = new GlideRecord('x_wadm_lsc_user');
lscUser.addQuery('temp', '=', 'dan');
current.temp += " Query: "+lscUser.getEncodedQuery();
Returns: "Query: temp=dan"
I would agree with Dan that the first step should be to confirm the column names. I usually don't take anything for granted, and always double check. You can use the dictionary or right click on the field label and it will show the column name.
I have seen "sys_idNotValidnull", but usually only within scoped applications.
I'm having trouble figuring out a data model for my project. I'm using Parse as the backend.
I intend to have users who are in groups, and the groups have text posts. What should be classes, and what should be rows in those classes.
I'm guessing a good way to do this would be, have a group, user, and post class.
The columns for the group class would be: GroupID, GroupName, postID, UserID
The columns for the user class would be: UserID, GroupsUserBelongsTo, user name, password, email
The columns for the post class would be: UserIDPostBelongsTo, GroupID, TextFile, TimeCreated
Is there anything I'm missing, or I should change.
You're thinking is a very SQL / rows based way and you shouldn't, this isn't SQL, it's objects and relationships.
So, your classes are fine, and the actual data is fine, but where you're using ids you should be using relationships. Post should just have a pointer to user. Perhaps, don't bother with a relationship from user to groups (you can query that using the other relationship), though you can, particularly if you will have lots of users / groups.
You may also want to consider roles to provide security for the groups.
I have four sub-organizations defined. (/AdminOrg, /subOrgA, /SubOrgB, /subOrgA/SubOrgAA)
my directory.orgunits.list query return below data. I store the return array in a variable called orgUnits[]:
http://pastebin.com/Kzud6SAq
I have 4 users in my organization. one in each sub-organization. the users.list return below data:
http://pastebin.com/6ttSgDSe
I am trying to get no. of users within an organization (without including sub organizations in them)
Option 1:
The query directory.users.list.query("orgUnitPath=/subOrgA") includes users from sub organization (/subOrgA/SubOrgAA) too and does not meet my needs.
Option 2:
I tried the query directory.users.list.query("orgName=orgUnits[]->name"). It queries for users[]->organizations[]->name. And this field is null by default. It does not get populated with orgUnits[]->name.
My questions are
How to populate users.organizations[].name?
Is there any way I can get users within an organization without including sub-organizations in them
Unfortunately it isn't possible to search for users within an orgUnit not including sub-orgs. The orginations field in the Users resource, as well as the orgName, orgTitle, orgDepartment, orgDescription,
orgCostCenter query parameters, refer to a completely separate set of data that appears to be used by the API only. Only the orgUnitPath field and query parameter operate on the organizations visible within the Google Apps Admin Console.
I add new users.
Let's presume we add a field of 'additionaldata1' on the parse user class
I do NOT want the user to be able to see the data stored in 'additionaldata1' and as such don't want it returned when I query the current parse users.
Seeing as the code is a web.app I don't want it to be possible for a user to 'hack' the local code in order to bring back 'all' their user object data.
So my question is how do I ensure that certain fields such as 'additionaldata1' are NEVER returned on the parse.com user object? Do I have to set up an additional class that is related to the user but set the ACL as non-read? Or can I set ACL per field on the user class?
EDIT//
UPDATE: I believe I worked this out myself. It doesn't appear to be possible to set ACL per field on a class. As such I have to add this data into an additional class with a RELATION and then set the ACL on that class table to 'no read' and 'no write'. That way only cloud code can see the class values due to the master key and I can run any validation and queries via cloud code where I need that data to be secure / private from the user.
This case is mentioned in Parse Docs under one-to-one relational data https://www.parse.com/docs/relations_guide#onetoone_anchor.
They recommend that you split up the data into two tables and use a one-to-one:
In Parse, a one-to-one relationship is great for situations where you need to split one object into two objects. These situations should be rare, but two examples include:
Limiting visibility of some user data. In this scenario, you would split the object in two, where one portion of the object contains data that is visible to other users, while the related object contains data that is private to the original user (and protected via ACLs).
Splitting up an object for size. In this scenario, your original object is greater than the 128K maximum size permitted for an object, so you decide to create a secondary object to house extra data. It is usually better to design your data model to avoid objects this large, rather than splitting them up. If you can't avoid doing so, you can also consider storing large data in a Parse File.