Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

Data Model Questions /

[SOLVED] canView requires ADMIN permission? I'm obviously missing something...


Reply


7 Posts   503 Views

Avatar
BobBrown

Community Member, 5 Posts

9 June 2014 at 10:13am

Edited: 09/06/2014 10:39am

Hi all,

I'm new to SilverStripe and am working with someone else's code. I have news items that are visible in the tree (they are a custom type called NewsItemPage which extends Page with a bunch of additional fields). These news items are configured to be visible by different groups of users. This all works fine. I can set visibility permissions in the admin and the visibility for each user is correct as configured in the admin.

However they've developed an API also that lets these news items be returned as JSON. The code behind this request is simply:

$allItems = Versioned::get_by_stage('NewsItemPage', 'Live');

which is then JSON encoded and sent back.

This appears to return all news items regardless of the currently logged on user. I am trying to check whether the current user can view the items returned like so I've adjusted the code as follows:

$visibleItems = array();
foreach ($allItems as $item) {
if ($item->canView()) {
$visibleItems[] = $item;
}
}

(I also tried $item->can('view') as suggested here http://doc.silverstripe.org/framework/en/reference/permission and that failed with "Uncaught Exception: Object->__call(): the method 'can' does not exist on HelpLink

What happens here is that I get all items back if I'm logged on as an administrator and no items back if I'm logged on as a regular user. I found that the definition for canView() is simply return Permission::check('ADMIN', 'any', $member); which (I think) means allow for admins only.

What is the right way to determine whether the news items can be accessed by the currently logged on user? It feels like there's a better method to call other than Versioned::get_by_stage()?

Cheers,

- Bob -

Avatar
BobBrown

Community Member, 5 Posts

9 June 2014 at 10:38am

Actually sorry the above code works fine in the case of anything which extends the Page class. What it doesn't work for is DataObjects that are attached to the pages themselves (they're fetched via HelpLink::get() - they're associated with the HelpItem). I'm not sure how to describe this but they appear as additional items that can be added to a page that can be dragged and dropped to determine their sort order.

I think therefore my problem is more along the lines of how do I resolve View permissions on these data objects to which I think the answer is to find the associated page for it and check the permissions on that as there doesn't appear to be individual permissions for the data objects themselves - as in you can't set it via the admin. I can work on this.

Does this sound right to anyone? I will report back with what I find.

Cheers,

- Bob -

Avatar
camfindlay

Forum Moderator, 188 Posts

9 June 2014 at 4:40pm

Hey Bob,

You'll want to simply implement the canView, canEdit etc methods on your DataObjects - then in those methods perform an appropriate permission check and return a boolean (true or false). Page class and any class that inherits from that already has these set (and permissions for these can to some degree can be set in the 'access' settings in the CMS). The DataObjects being lower level building block of SilverStripe don't make assumptions as to permissions so you need to explicitly set what you need.

What you could actually to if you have set the data relationships reciprocally (something like MyPage has_many MyObjects and MyObject has_one MyPage), and you simply want a DataObject to inherit the permissions of the Page it is attached to is something like this:

class MyObject extends DataObject {
private static $has_one = array(
"MyPage" => "MyPage"
);
public function canView($member=null) {
return $this->MyPage()->canView();
}
}

There is some more info around DataObject permissions at [url]http://doc.silverstripe.org/framework/en/reference/dataobject#permissions[/url]

Hope that helps.

Avatar
BobBrown

Community Member, 5 Posts

9 June 2014 at 5:16pm

Awesome, that sounds pretty good. I'll look at doing exactly this and see how it goes. Thanks for the response.

Avatar
BobBrown

Community Member, 5 Posts

10 June 2014 at 9:57am

Edited: 10/06/2014 9:58am

Hey Cam,

The HelpLink (extends DataObject) class already had a getParent() method on it which returned the associated page so the answer - as you pointed out - was simply to do this:

public function canView($member = NULL) {
   return $this->getParent()->canView();
}


Thanks again for your response.

Cheers,

- Bob -

Avatar
BobBrown

Community Member, 5 Posts

10 June 2014 at 10:01am

And not surprisingly this is what was in getParent:

public function getParent() {
   return $this->MyPage();
}


:)

Cheers,

- Bob -

Avatar
camfindlay

Forum Moderator, 188 Posts

10 June 2014 at 10:22am

good to hear, I think also because the method is a 'getter' method you could make it further simple by just using $this->Parent()->canView().

Let's mark this one as solved then, please edit your initial post and add a [solved] to the front of your topic :)