edu.ucsb.nceas.metacat.dataone

## Class D1AuthHelper

- java.lang.Object
- - edu.ucsb.nceas.metacat.dataone.D1AuthHelper

-     public class D1AuthHelper
      extends java.lang.Object

  This is delegate class for D1NodeService and subclasses. It centralizes authorization implementations to make them more consistent across the various API methods, and more testable. There are 6 basic authorization checks that can be done, and these are implemented as protected methods in this class. these checks are: 1. session vs. systemMetadata subjects 2. session vs. local admin credentials 3. session vs. systemMetadata authoritativeMemberNode (requires NodeList) 4. session vs. CN nodelist subjects (checking for CN admin authorization) 5. session vs. systemMetadata replica nodeReferences (via nodelist subjects) 6. session vs. expanded rightsHolder equivalent subjects and groups. (uses API calls to the CN) In practice, there are currently only a handful of combinations of authorization checks being used. These are represented by the public methods in this class. If more combinations are ever required, they should be added as a new public method, and follow the general way the other methods are implemented. The combinations in use are: 1. CNadmin only 2. Local or AuthoritativeMN only 3. Local MN or CN admin only 4. "isAuthorized" - all checks except allowing replica nodes 5. "getSystemMetadata" - all checks 6. "update" authorization - success depends on the local node being the authMN
  Author:
    rnahf

- - ### Constructor Summary

    Constructors
    Constructor and Description
    `D1AuthHelper(javax.servlet.http.HttpServletRequest request, org.dataone.service.types.v1.Identifier requestIdentifier, java.lang.String notAuthorizedCode, java.lang.String serviceFailureCode)` Each instance should correspond to a single request.

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `protected boolean` | `checkExpandedPermissions(org.dataone.service.types.v1.Session session, org.dataone.service.types.v2.SystemMetadata sysmeta, org.dataone.service.types.v1.Permission permission)` Compare all the session subjects against the expanded subjects (from listSubjects) of the object rightsholder.
    `void` | `doAdminAuthorization(org.dataone.service.types.v1.Session session)` Does MN/CN admin authorization
    `void` | `doAuthoritativeMNAuthorization(org.dataone.service.types.v1.Session session, org.dataone.service.types.v2.SystemMetadata sysmeta)` Does local and AuthMN admin authorization
    `void` | `doCNOnlyAuthorization(org.dataone.service.types.v1.Session session)` Does only localNode(CN)/CN authorization
    `void` | `doGetSysmetaAuthorization(org.dataone.service.types.v1.Session session, org.dataone.service.types.v2.SystemMetadata sysmeta, org.dataone.service.types.v1.Permission permission)` used by getSystemMetadata, describe, and getPackage, the latter two by delegation to getSystemMetadata Very similar to doIsAuthorized, but also allows replica nodes administrative access.
    `void` | `doIsAuthorized(org.dataone.service.types.v1.Session session, org.dataone.service.types.v2.SystemMetadata sysmeta, org.dataone.service.types.v1.Permission permission)` Performs all authorization steps used by isAuthorized.
    `void` | `doUpdateAuth(org.dataone.service.types.v1.Session session, org.dataone.service.types.v2.SystemMetadata sysmeta, org.dataone.service.types.v1.Permission permission, org.dataone.service.types.v1.NodeReference localNodeId)` The locus of updates is limited to the authoritativeMN.
    `static boolean` | `expandRightsHolder(org.dataone.service.types.v1.Subject rightHolder, org.dataone.service.types.v1.Subject sessionSubject)` Check if the given userSession is the member of the right holder group (if the right holder is a group subject).
    `protected org.dataone.service.types.v2.NodeList` | `getCNNodeList()` A centralized point for accessing the CN Nodelist, to make it easier to cache the nodelist in the future, if it's seen as helpful performance-wise
    `protected boolean` | `isAuthoritativeMNodeAdmin(org.dataone.service.types.v1.Session session, org.dataone.service.types.v1.NodeReference authoritativeMNode, org.dataone.service.types.v2.NodeList nodelist)` Compare the session.subject to the authoritativeMN Node.nodeSubjects list of Subjects.
    `protected boolean` | `isAuthorizedBySysMetaSubjects(org.dataone.service.types.v1.Session session, org.dataone.service.types.v2.SystemMetadata sysmeta, org.dataone.service.types.v1.Permission permission)` Returns the authorization status of the Session vs.
    `protected boolean` | `isCNAdmin(org.dataone.service.types.v1.Session session, org.dataone.service.types.v2.NodeList nodelist)` compares session.subject against CN.NodeList
    `boolean` | `isLocalCNAdmin(org.dataone.service.types.v1.Session session)` Test if the user identified by the provided token has administrative authorization on this node because they are calling themselves (the implementation uses property Settings to build a Node instance)
    `boolean` | `isLocalMNAdmin(org.dataone.service.types.v1.Session session)` Test if the user identified by the provided token has administrative authorization on this node because they are calling themselves (the implementation uses property Settings to build a Node instance)
    `protected boolean` | `isLocalNodeAdmin(org.dataone.service.types.v1.Session session, org.dataone.service.types.v1.NodeType nodeType)` Checks Metacat properties representing the local Node document for matching Node.subjects.
    `protected boolean` | `isReplicaMNodeAdmin(org.dataone.service.types.v1.Session session, org.dataone.service.types.v2.SystemMetadata sysmeta, org.dataone.service.types.v2.NodeList nodelist)` determines if the session represents a replicaMN of the given systemMetadata.
    `protected void` | `prepareAndThrowNotAuthorized(org.dataone.service.types.v1.Session session, org.dataone.service.types.v1.Identifier pid, org.dataone.service.types.v1.Permission permission, java.lang.String detailCode)`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Constructor Detail

    - #### D1AuthHelper

          public D1AuthHelper(javax.servlet.http.HttpServletRequest request,
                              org.dataone.service.types.v1.Identifier requestIdentifier,
                              java.lang.String notAuthorizedCode,
                              java.lang.String serviceFailureCode)

      Each instance should correspond to a single request.
      Parameters:
        `request` -
        `hzSystemMetadataMap` -

  - ### Method Detail

    - #### doIsAuthorized

          public void doIsAuthorized(org.dataone.service.types.v1.Session session,
                                     org.dataone.service.types.v2.SystemMetadata sysmeta,
                                     org.dataone.service.types.v1.Permission permission)
                              throws org.dataone.service.exceptions.ServiceFailure,
                                     org.dataone.service.exceptions.NotAuthorized

      Performs all authorization steps used by isAuthorized. Checks for accessPolicy & rightsHolder authorization, and authorizes local, authoritativeMN, and CN admins.
      Parameters:
        `session` -
        `sysmeta` -
        `permission` -
      Throws:
        `org.dataone.service.exceptions.ServiceFailure`
        `org.dataone.service.exceptions.NotAuthorized`

    - #### doAuthoritativeMNAuthorization

          public void doAuthoritativeMNAuthorization(org.dataone.service.types.v1.Session session,
                                                     org.dataone.service.types.v2.SystemMetadata sysmeta)
                                              throws org.dataone.service.exceptions.ServiceFailure,
                                                     org.dataone.service.exceptions.NotAuthorized

      Does local and AuthMN admin authorization
      Parameters:
        `session` -
        `sysmeta` -
      Throws:
        `org.dataone.service.exceptions.ServiceFailure`
        `org.dataone.service.exceptions.NotAuthorized`

    - #### doUpdateAuth

          public void doUpdateAuth(org.dataone.service.types.v1.Session session,
                                   org.dataone.service.types.v2.SystemMetadata sysmeta,
                                   org.dataone.service.types.v1.Permission permission,
                                   org.dataone.service.types.v1.NodeReference localNodeId)
                            throws org.dataone.service.exceptions.NotAuthorized,
                                   org.dataone.service.exceptions.ServiceFailure

      The locus of updates is limited to the authoritativeMN. Therefore, the authorization rules are somewhat specialized:
      1. If the update is happening on the authoritative MN, either
      - the session has the appropriate permission vs the systemmetadata or
      - the session represents the MN Admin Subject
      2. If the session represents the D1 CN, it is allowed.
      Throws:
        `org.dataone.service.exceptions.NotAuthorized`
        `org.dataone.service.exceptions.ServiceFailure`

    - #### doCNOnlyAuthorization

          public void doCNOnlyAuthorization(org.dataone.service.types.v1.Session session)
                                     throws org.dataone.service.exceptions.ServiceFailure,
                                            org.dataone.service.exceptions.NotAuthorized

      Does only localNode(CN)/CN authorization
      Parameters:
        `session` -
      Throws:
        `org.dataone.service.exceptions.ServiceFailure`
        `org.dataone.service.exceptions.NotAuthorized`

    - #### doAdminAuthorization

          public void doAdminAuthorization(org.dataone.service.types.v1.Session session)
                                    throws org.dataone.service.exceptions.ServiceFailure,
                                           org.dataone.service.exceptions.NotAuthorized

      Does MN/CN admin authorization
      Parameters:
        `session` -
      Throws:
        `org.dataone.service.exceptions.ServiceFailure`
        `org.dataone.service.exceptions.NotAuthorized`

    - #### doGetSysmetaAuthorization

          public void doGetSysmetaAuthorization(org.dataone.service.types.v1.Session session,
                                                org.dataone.service.types.v2.SystemMetadata sysmeta,
                                                org.dataone.service.types.v1.Permission permission)
                                         throws org.dataone.service.exceptions.ServiceFailure,
                                                org.dataone.service.exceptions.NotAuthorized

      used by getSystemMetadata, describe, and getPackage, the latter two by delegation to getSystemMetadata Very similar to doIsAuthorized, but also allows replica nodes administrative access.
      Parameters:
        `session` -
        `sysmeta` -
        `permission` -
      Throws:
        `org.dataone.service.exceptions.ServiceFailure`
        `org.dataone.service.exceptions.NotAuthorized`

    - #### prepareAndThrowNotAuthorized

          protected void prepareAndThrowNotAuthorized(org.dataone.service.types.v1.Session session,
                                                      org.dataone.service.types.v1.Identifier pid,
                                                      org.dataone.service.types.v1.Permission permission,
                                                      java.lang.String detailCode)
                                               throws org.dataone.service.exceptions.NotAuthorized

      Throws:
        `org.dataone.service.exceptions.NotAuthorized`

    - #### checkExpandedPermissions

          protected boolean checkExpandedPermissions(org.dataone.service.types.v1.Session session,
                                                     org.dataone.service.types.v2.SystemMetadata sysmeta,
                                                     org.dataone.service.types.v1.Permission permission)
                                              throws org.dataone.service.exceptions.ServiceFailure

      Compare all the session subjects against the expanded subjects (from listSubjects) of the object rightsholder.
      Parameters:
        `sessionSubjects` -
        `sysmeta` -
        `permission` -
      Returns:
        true or false, depending...
      Throws:
        `org.dataone.service.exceptions.ServiceFailure`

    - #### getCNNodeList

          protected org.dataone.service.types.v2.NodeList getCNNodeList()
                                                                 throws org.dataone.service.exceptions.ServiceFailure

      A centralized point for accessing the CN Nodelist, to make it easier to cache the nodelist in the future, if it's seen as helpful performance-wise
      Returns:
      Throws:
        `org.dataone.service.exceptions.ServiceFailure`
        `org.dataone.service.exceptions.NotImplemented`

    - #### expandRightsHolder

          public static boolean expandRightsHolder(org.dataone.service.types.v1.Subject rightHolder,
                                                   org.dataone.service.types.v1.Subject sessionSubject)
                                            throws org.dataone.service.exceptions.ServiceFailure,
                                                   org.dataone.service.exceptions.NotImplemented,
                                                   org.dataone.service.exceptions.InvalidRequest,
                                                   org.dataone.service.exceptions.NotAuthorized,
                                                   org.dataone.service.exceptions.InvalidToken

      Check if the given userSession is the member of the right holder group (if the right holder is a group subject). If the right holder is not a group, it will be false of course.
      Parameters:
        `rightHolder` - the subject of the right holder.
        `sessionSubject` - the subject will be compared
      Returns:
        true if the user session is a member of the right holder group; false otherwise.
      Throws:
        `org.dataone.service.exceptions.NotImplemented`
        `org.dataone.service.exceptions.ServiceFailure`
        `org.dataone.service.exceptions.NotAuthorized`
        `org.dataone.service.exceptions.InvalidToken`
        `org.dataone.service.exceptions.InvalidRequest`

    - #### isLocalMNAdmin

          public boolean isLocalMNAdmin(org.dataone.service.types.v1.Session session)
                                 throws org.dataone.service.exceptions.ServiceFailure

      Test if the user identified by the provided token has administrative authorization on this node because they are calling themselves (the implementation uses property Settings to build a Node instance)
      Parameters:
        `session` - - the Session object containing the credentials for the Subject
      Returns:
        true if the user is this node
      Throws:
        `org.dataone.service.exceptions.ServiceFailure`
        `org.dataone.service.exceptions.NotImplemented`

    - #### isLocalCNAdmin

          public boolean isLocalCNAdmin(org.dataone.service.types.v1.Session session)
                                 throws org.dataone.service.exceptions.ServiceFailure

      Test if the user identified by the provided token has administrative authorization on this node because they are calling themselves (the implementation uses property Settings to build a Node instance)
      Parameters:
        `session` - - the Session object containing the credentials for the Subject
      Returns:
        true if the user is this node
      Throws:
        `org.dataone.service.exceptions.ServiceFailure`
        `org.dataone.service.exceptions.NotImplemented`

    - #### isLocalNodeAdmin

          protected boolean isLocalNodeAdmin(org.dataone.service.types.v1.Session session,
                                             org.dataone.service.types.v1.NodeType nodeType)
                                      throws org.dataone.service.exceptions.ServiceFailure

      Checks Metacat properties representing the local Node document for matching Node.subjects. The NodeType parameter can be set to limit this authorization check if needed.
      Parameters:
        `session` -
        `nodeType` -
      Returns:
      Throws:
        `org.dataone.service.exceptions.ServiceFailure`

    - #### isAuthorizedBySysMetaSubjects

          protected boolean isAuthorizedBySysMetaSubjects(org.dataone.service.types.v1.Session session,
                                                          org.dataone.service.types.v2.SystemMetadata sysmeta,
                                                          org.dataone.service.types.v1.Permission permission)

      Returns the authorization status of the Session vs. the given SystemMetadata based on the rightsHolder and AccessPolicy fields
      Parameters:
        `session` -
        `sysmeta` -
        `permission` -
      Returns:
        true|false

    - #### isReplicaMNodeAdmin

          protected boolean isReplicaMNodeAdmin(org.dataone.service.types.v1.Session session,
                                                org.dataone.service.types.v2.SystemMetadata sysmeta,
                                                org.dataone.service.types.v2.NodeList nodelist)

      determines if the session represents a replicaMN of the given systemMetadata.
      Parameters:
        `session` - - the session, uses only the session.subject field
        `sysmeta` -
        `nodelist` -
      Returns:
        true|false

    - #### isAuthoritativeMNodeAdmin

          protected boolean isAuthoritativeMNodeAdmin(org.dataone.service.types.v1.Session session,
                                                      org.dataone.service.types.v1.NodeReference authoritativeMNode,
                                                      org.dataone.service.types.v2.NodeList nodelist)

      Compare the session.subject to the authoritativeMN Node.nodeSubjects list of Subjects. According the the DataONE documentation, the authoritative member node has all the rights of the *rightsHolder*. Any null parameter will result in return of false
      Parameters:
        `session` -
        `authoritativeMNode` -
        `nodelist` -
      Returns:

    - #### isCNAdmin

          protected boolean isCNAdmin(org.dataone.service.types.v1.Session session,
                                      org.dataone.service.types.v2.NodeList nodelist)

      compares session.subject against CN.NodeList
      Parameters:
        `session` -
        `nodelist` -

Copyright © 2023 Regents of the University of California. All Rights Reserved.