checkPermissions only lets admins write
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
MUGLE |
Fix Released
|
High
|
Matt Giuca |
Bug Description
It's hard to demonstrate at the moment, but I believe that checkPermissions in all of the *ServiceImpl classes, except for UserService, will prevent non-admins from writing to objects, even if they own them.
This is because all of the checks check the current user's key against the object in question's key (which obviously never match), and set it to private if they match, public otherwise. This means it will ALWAYS result in the public interface. Admins can still write to such an interface, but nobody else can.
Therefore, each ServiceImpl class needs that logic to change to a real check to see whether the user owns that object (which is usually going to be the same condition as the exception check above).
Related branches
Changed in mugle: | |
status: | Triaged → New |
Changed in mugle: | |
status: | Fix Committed → Fix Released |
Ok so i completely screwed these up when i implemented them based on my interpretations of what the ServiceImpl should be doing;
What each checkPermissions should look like:
/** s(ModelClass object, PersistenceManager pm) { getCurrentUser( pm); getDevTeam( object. getDevTeamKey( )); getPrimaryKey( ) {
* Gets the Role of the current user, and the View they should see of the object passed to it
* @param object the object to get the permissions for
* @param pm the PersistenceManager
* @return the Role of the current user and the ClientView it should see
private RoleAndView checkPermission
//The currently logged in user
UserData curUser = UserGetter.
/*TODO: look up the user that the object belongs to through the heirachy of relationships
* For example suppose object is of type Game:
* DevTeamData dtd = DevTeamGetter.
* ClientView cv = ClientView.PUBLIC; //assume by default
* for (Key k : dtd.getUsers()) {
* if (k.getID() == curUser.
* cv = ClientView.PRIVATE; //CurUser is part of the devteam the object belongs to
* }
* }
*/
return new RoleAndView( curUser. getRole( ), cv, curUser);
}
Then you pass the ClientView and Role from the returned RoleAndView to the ModelWrapper. getClient/ DataClone calls which will construct/store the object based on the role and view recieved.
This should be in _EVERY_ ServerSideImpl that accesses/writes to the datastore.
Hope this helps.