最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Parse Pointer Permissions don't allow create - Stack Overflow

programmeradmin3浏览0评论

I've followed every step of this walkthrough, but when I try to create a new row, I get a 403:

code: 119

message: "This user is not allowed to perform the create operation on Messages. You can change this setting in the Data Browser."

My code:

Messages = Parse.Object.extend("Messages")
var message = new Messages();
message.set("sender", Parse.User.current());
message.set("receiver", *anotherUser*);
message.set("subject", "foo")
message.set("body", "bar")
message.save()
.then(
  function(message){
    console.log("success!")
  },function(error){
    console.log("error: ", error);
});

My CLPs are set as follows:

It looks like someone else posted the same issue in a google group. What are we missing?

I've followed every step of this walkthrough, but when I try to create a new row, I get a 403:

code: 119

message: "This user is not allowed to perform the create operation on Messages. You can change this setting in the Data Browser."

My code:

Messages = Parse.Object.extend("Messages")
var message = new Messages();
message.set("sender", Parse.User.current());
message.set("receiver", *anotherUser*);
message.set("subject", "foo")
message.set("body", "bar")
message.save()
.then(
  function(message){
    console.log("success!")
  },function(error){
    console.log("error: ", error);
});

My CLPs are set as follows:

It looks like someone else posted the same issue in a google group. What are we missing?

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Oct 23, 2015 at 16:50 adamdportadamdport 12.6k14 gold badges72 silver badges92 bronze badges 5
  • Have you checked to see if the what the value is of Parse.User.current()? My guess is that it's returning a nil user. Also, I've always used PFUser.currentUser(), so maybe give that a go too – Russell Commented Oct 23, 2015 at 18:45
  • Just double-checked–I console.log it out just before I save it, and it is a valid user object with an id. – adamdport Commented Oct 23, 2015 at 20:12
  • Is it different from request.user? Try logging that too to see if they are different – Russell Commented Oct 23, 2015 at 21:08
  • They're the same. Just modified my cloudcode as requested and see in my logs, before_save triggered for Messages for user xxxx, where xxxx is the same as the sender field. – adamdport Commented Oct 23, 2015 at 21:36
  • @Russell have you ever used pointer permissions and had create work as expected? – adamdport Commented Oct 24, 2015 at 21:37
Add a comment  | 

3 Answers 3

Reset to default 17

I've submitted this as a bug to Parse (Facebook), and they replied:

We have managed to reproduce this issue and it appears to be a valid bug. We are assigning this to the appropriate team.

I will update this answer once the issue has been resolved. If this issue is impacting you, please subscribe to the bug, as this will help prioritize the fix.

UPDATE

Facebook replied:

Turns out that this is actually by design. To create an object, the class should have public create permissions on it

Unfortunately, with this solution, I can create a message "from" any other user (another user set as the sender). This is unacceptable and unusable IMHO.

That has been a bug since the launch of Pointer Permissions, which effectively makes them useless. My impression is they built this with the idea of letting developers secure existing schemas in one go, but of course you need it to work for future creation.

One workaround would involve combining the older Class Level Permissions and per-row ACL's while being careful to not disable your Data Browser. Let's assume you have classes "Puppy" and "Cat" and both have a field called "owner".

  1. In your Data Browser, for each class where it makes sense to have an owner field, you set its Class Level Permissions for Puppy and Cat each to:

Public - Read: Yes or No, depends on your use case, Write: Yes

Add a Pointer Permission for "owner" - Read: Yes, Write: Yes (can skip this for now, see below)

  1. Then in your cloud/main.js, you can use the following as a starting point (which I often call "types" below, sorry).

  2. When Parse fixes the creation issue, you remove the Public Write Class Level permission (above), leave the Pointer Permission one, and get rid of the workaround code below.

--

var validateAndUpdateOwnerWritePerms = function(request){
    var object = request.object;
    var error = null;
    var owner = object.get('owner');

    if (!Parse.User.current()) {
        error = 'User session required to create or modify object.';
    } else if (!owner) {
        error = 'Owner expected, but not found.';
    } else if (owner && owner.id != Parse.User.current().id && !object.existed()) {
        error = 'User session must match the owner field in the new object.';
    }

    if (request.master) {
        error = null;
    }

    if (error) {
        return error;
    }

    if (object.existed()) {
        return null;
    }

    var acl = new Parse.ACL();
    acl.setReadAccess(owner, true);
    acl.setWriteAccess(owner, true);

    object.setACL(acl);

    return null;
}

// Wrapper that makes beforeSave, beforeDelete, etc. respect master-key calls.
// If you use one of those hooks directly, your tests or admin
// console may not work.
var adminWriteHook = function(cloudHook, dataType, callback) {
    cloudHook(dataType, function(request, response) {
        if (request.master) {
            Parse.Cloud.useMasterKey();
        } else {
            var noUserAllowed = false;
            if (cloudHook == Parse.Cloud.beforeSave &&
                (dataType == Parse.Installation || dataType == Parse.User)) {
                    noUserAllowed = true;
            }
            if (!noUserAllowed && !Parse.User.current()) {
                response.error('Neither user session, nor master key was found.');
                return null;
            }
        }

        return callback(request, response);
    });
};

// Set hooks for permission checks to run on delete and save.
var beforeOwnedTypeWriteHook = function(type) {
    var callback = function (request, response) {
        var error = validateAndUpdateOwnerWritePerms(request);
        if (error) {
            response.error(error);
            return;
        }
        response.success();
    };
    return adminWriteHook(Parse.Cloud.beforeSave, type, callback);
    return adminWriteHook(Parse.Cloud.beforeDelete, type, callback);
};

beforeOwnedTypeWriteHook('Puppy');
beforeOwnedTypeWriteHook('Cat');

Unfortunately it seems that Parse Pointer Permissions do not work as you expect it on Create. The quick fix would be to allow Create permission to Public. Then to ensure that the user who is creating a record is the same as the sender. So you need to perform a manual check in the beforeSave trigger for Messages class in cloud code and if that check fails, reject the record being created.

发布评论

评论列表(0)

  1. 暂无评论