Project

General

Profile

« Previous | Next » 

Revision 7145

check normal access control rules for getSystemMetadata before deferring to MN replica information that may grant MNs additional access to the SM.
https://redmine.dataone.org/issues/2656

View differences:

src/edu/ucsb/nceas/metacat/dataone/D1NodeService.java
59 59
import org.dataone.service.exceptions.NotImplemented;
60 60
import org.dataone.service.exceptions.ServiceFailure;
61 61
import org.dataone.service.exceptions.UnsupportedType;
62
import org.dataone.service.types.v1.AccessPolicy;
63 62
import org.dataone.service.types.v1.AccessRule;
64 63
import org.dataone.service.types.v1.DescribeResponse;
65 64
import org.dataone.service.types.v1.Event;
......
68 67
import org.dataone.service.types.v1.Log;
69 68
import org.dataone.service.types.v1.LogEntry;
70 69
import org.dataone.service.types.v1.Node;
71
import org.dataone.service.types.v1.NodeList;
72 70
import org.dataone.service.types.v1.NodeReference;
73 71
import org.dataone.service.types.v1.NodeType;
74 72
import org.dataone.service.types.v1.ObjectFormat;
75 73
import org.dataone.service.types.v1.Permission;
76 74
import org.dataone.service.types.v1.Person;
77 75
import org.dataone.service.types.v1.Replica;
78
import org.dataone.service.types.v1.ReplicationStatus;
79 76
import org.dataone.service.types.v1.Session;
80 77
import org.dataone.service.types.v1.Subject;
81 78
import org.dataone.service.types.v1.SubjectInfo;
82
import org.dataone.service.types.v1.SubjectList;
83 79
import org.dataone.service.types.v1.SystemMetadata;
84 80
import org.dataone.service.types.v1.util.ChecksumUtil;
85 81

  
......
96 92
import edu.ucsb.nceas.metacat.properties.PropertyService;
97 93
import edu.ucsb.nceas.metacat.replication.ForceReplicationHandler;
98 94
import edu.ucsb.nceas.metacat.util.DocumentUtil;
99
import edu.ucsb.nceas.metacat.util.SystemUtil;
100 95
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
101 96

  
102 97
public abstract class D1NodeService {
......
718 713
            subject = session.getSubject();
719 714
        }
720 715
        
721
        try {
722
            // get the system metadata first because we need the replica list for auth
723
            systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
716
        // check normal authorization
717
        BaseException originalAuthorizationException = null;
718
        if (!isAuthorized) {
719
            try {
720
                isAuthorized = isAuthorized(session, pid, Permission.READ);
724 721

  
725
            // if MNs are listed as replicas, allow access
726
            if ( systemMetadata != null ) {
727
                replicaList = systemMetadata.getReplicaList();
728
                // only check if there are in fact replicas listed
729
                if ( replicaList != null ) {
730
                    
731
                    if ( subject != null ) {
732
                        // get the list of nodes with a matching node subject
733
                        try {
734
                            nodeListBySubject = listNodesBySubject(session
735
                                    .getSubject());
736

  
737
                        } catch (BaseException e) {
738
                            // Unexpected error contacting the CN via D1Client
739
                            String msg = "Caught an unexpected error while trying "
740
                                    + "to potentially authorize system metadata access "
741
                                    + "based on the session subject. The error was "
742
                                    + e.getMessage();
743
                            logMetacat.error(msg);
744
                            if (logMetacat.isDebugEnabled()) {
745
                                e.printStackTrace();
746

  
747
                            }
748
                            // isAuthorized is still false 
749
                        }
750

  
751
                    }
752
                    if (nodeListBySubject != null) {
753
                        // compare node ids to replica node ids
754
                        outer: for (Replica replica : replicaList) {
755
                            replicaNodeRef = replica.getReplicaMemberNode();
756

  
757
                            for (Node node : nodeListBySubject) {
758
                                if (node.getIdentifier().equals(replicaNodeRef)) {
759
                                    // node id via session subject matches a replica node
760
                                    isAuthorized = true;
761
                                    break outer;
762
                                }
763
                            }
764
                        }
765
                    }
766
                }
767
            }
768
            
769
            if (!isAuthorized) {
770
                try {
771
                    isAuthorized = isAuthorized(session, pid, Permission.READ);
772

  
773
                } catch (InvalidRequest e) {
774
                    throw new ServiceFailure("1090", e.getDescription());
775

  
776
                }
777
            }
778
            
779
            if (!isAuthorized) {
780
                throw new NotAuthorized("1400", Permission.READ
781
                        + " not allowed on " + pid.getValue());
782
            }
722
            } catch (InvalidRequest e) {
723
                throw new ServiceFailure("1090", e.getDescription());
724
            } catch (NotAuthorized nae) {
725
            	// catch this for later
726
            	originalAuthorizationException = nae;
727
			}
728
        }
783 729
        
784
        } catch (RuntimeException e) {
785
        	e.printStackTrace();
786
            // convert hazelcast RuntimeException to ServiceFailure
787
            throw new ServiceFailure("1090", "Unexpected error getting system metadata for: " + 
788
                pid.getValue());
730
        // get the system metadata first because we need the replica list for auth
731
        systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
732
        
733
        // check the replica information to expand access to MNs that might need it
734
        if (!isAuthorized) {
735
        	
736
	        try {
737
	        	
738
	            // if MNs are listed as replicas, allow access
739
	            if ( systemMetadata != null ) {
740
	                replicaList = systemMetadata.getReplicaList();
741
	                // only check if there are in fact replicas listed
742
	                if ( replicaList != null ) {
743
	                    
744
	                    if ( subject != null ) {
745
	                        // get the list of nodes with a matching node subject
746
	                        try {
747
	                            nodeListBySubject = listNodesBySubject(session.getSubject());
748
	
749
	                        } catch (BaseException e) {
750
	                            // Unexpected error contacting the CN via D1Client
751
	                            String msg = "Caught an unexpected error while trying "
752
	                                    + "to potentially authorize system metadata access "
753
	                                    + "based on the session subject. The error was "
754
	                                    + e.getMessage();
755
	                            logMetacat.error(msg);
756
	                            if (logMetacat.isDebugEnabled()) {
757
	                                e.printStackTrace();
758
	
759
	                            }
760
	                            // isAuthorized is still false 
761
	                        }
762
	
763
	                    }
764
	                    if (nodeListBySubject != null) {
765
	                        // compare node ids to replica node ids
766
	                        outer: for (Replica replica : replicaList) {
767
	                            replicaNodeRef = replica.getReplicaMemberNode();
768
	
769
	                            for (Node node : nodeListBySubject) {
770
	                                if (node.getIdentifier().equals(replicaNodeRef)) {
771
	                                    // node id via session subject matches a replica node
772
	                                    isAuthorized = true;
773
	                                    break outer;
774
	                                }
775
	                            }
776
	                        }
777
	                    }
778
	                }
779
	            }
780
	            
781
	            // if we still aren't authorized, then we are done
782
	            if (!isAuthorized) {
783
	                throw new NotAuthorized("1400", Permission.READ
784
	                        + " not allowed on " + pid.getValue());
785
	            }
789 786

  
787
	        } catch (RuntimeException e) {
788
	        	e.printStackTrace();
789
	            // convert hazelcast RuntimeException to ServiceFailure
790
	            throw new ServiceFailure("1090", "Unexpected error getting system metadata for: " + 
791
	                pid.getValue());	
792
	        }
793
	        
790 794
        }
791

  
795
        
792 796
        // It wasn't in the map
793 797
        if ( systemMetadata == null ) {
794 798
            throw new NotFound("1420", "No record found for: " + pid.getValue());
795

  
796 799
        }
797 800
        
798 801
        return systemMetadata;

Also available in: Unified diff