Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

Summary

Designing authorization rules within an Authorization OSID Provider can provide visibility in who has access to what and simplify base service implementations. Working from the authorization evaluation perspective can solve the puzzle that is difficult to see through data attributes. This is a case study of a project that tackles this issue.

The Student System Project

The Student System Project is using the Hold OSID as a means of restricting registration access to students. The registration process uses the Rules.Check OSID as a means of managing what hold Blocks will be checked. 

The product owner understands that one organization may place a Hold on a student while another organization is responsible for expiring it. The Issue has a single responsible Resource? The product owner asks that a list of Organizations, not Resources, who can place the Hold and a list of Organizations who can remove the Hold be added to the Issue.

Work Begins

The application programmer and OSID implementor collaborate to define an OsidRecord for these extra lists of Organizations. The application populates them from user input on a hold administrative screen. 

Holds are tested and they can be created or removed by anyone. The product owner tells the application programmer that these organizations should be checked so that only people inside the organization are allowed to perform these operations.

The application programmer scratches his head, and looks to see how he can figure out who belongs to what organization. He looks to the Personnel OSID to answer this question and sees that Persons are related to Organizations via Appointments and Positions. Dismayed at the bizarre complexity of the situation, shovels out the following code:

boolean checkPlaceHold(org.osid.id.Id issueId, org.osid.id.Id agentId)
    throws org.osid.NotFoundException,
           org.osid.OperationFailedException,
           org.osid.PermissionDeniedException {
    org.osid.resource.ResourceAgentSession resourceAgentSession = resourceMgr.getResourceAgentSession();
 
    // I'll assume the resourceId is the same as the personId
    org.osid.id.Id resourceId = resourceAgentSession.getResourceIdByAgent(agentId);
 
    org.osid.hold.IssueLookupSession issueLookupSession = holdMgr.getIssueLookupSession();
    org.osid.hold.Issue issue = issueLookupSession.getIssue(issueId);
    
    // our local org data
    OrganizationHoldRecord record = (OrganizationHoldRecord) issue.getIssueRecord(organizationHoldRecordType);
 
    // could they have made this any more difficult!
    org.osid.personnel.AppointmentLookupSession appointmentLookupSession = personnelMgr.getAppointmentLookupSession();
    appointmentLookupSession.useEffectiveAppointmentView();
    org.osid.personnel.PositionLookupSession positionLookupSession = personnelMgr.getPositionLookupSession();
    positionLookupSession.useEffectivePositionView();
 
    // get the positions of an org - blasted there's no way to get a list of people in an org!
    try (org.osid.id.IdList orgIds = record.getOrgIdsWhoCanPlaceHold()) {
        while (orgIds.hasNext()) {
            org.osid.id.Id orgId = orgIds.getNextId();
            try (org.osid.personnel.PositionList positions = positionLookupSession.getPositionsForOrganization(orgId)) {
                while (positions.hasNext()) {
                    org.osid.personnel.Position position = positions.getNextPosition();
                    try (org.osid.personnel.AppintmentList appointments = appointmentLookupSession.getAppointmentsForPersonAndPosition(resourceId, position.getNextId()) {
                        if (appointments.hasNext()) {
                            return (true);
                        }
                    }
                }
            }
        }
    }
 
    return (false);
}            

It may come as a shock but the product owner complains that it takes too long to create a hold. Both the application programmer and OSID implementation programmer are in agreement on this one. They complain that these APIs were designed to their requirements. They figure that if they can have a simple method:

boolean isAgentInAnyOfTheseOrgs(agentId, orgIds)

then they can optimize for this case in a single call and implement it in a direct SQL query. 

 

 

 

  • No labels