Project

General

Profile

« Previous | Next » 

Revision 6644

Calls to setReplicationStatus() can only be made by a CN or the MN that is the target replica node. Implement this service restriction in CNodeService using CertificateManager's equalsDN() method.

View differences:

src/edu/ucsb/nceas/metacat/dataone/CNodeService.java
37 37
import org.apache.log4j.Logger;
38 38
import org.dataone.client.CNode;
39 39
import org.dataone.client.D1Client;
40
import org.dataone.client.auth.CertificateManager;
40 41
import org.dataone.service.cn.v1.CNAuthorization;
41 42
import org.dataone.service.cn.v1.CNCore;
42 43
import org.dataone.service.cn.v1.CNRead;
......
166 167
      try {
167 168
        systemMetadata.setSerialVersion(systemMetadata.getSerialVersion().add(BigInteger.ONE));
168 169
        systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
169
	      HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
170
	      HazelcastService.getInstance().getSystemMetadataMap().unlock(systemMetadata.getIdentifier());
171
	      
170
        HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
171
        HazelcastService.getInstance().getSystemMetadataMap().unlock(systemMetadata.getIdentifier());
172
        
172 173
      } catch (Exception e) {
173
		      throw new ServiceFailure("4882", e.getMessage());
174
		  
175
	    } finally {
176
	        HazelcastService.getInstance().getSystemMetadataMap().unlock(systemMetadata.getIdentifier());
177
	        
178
	    }
174
          throw new ServiceFailure("4882", e.getMessage());
175
      
176
      } finally {
177
          HazelcastService.getInstance().getSystemMetadataMap().unlock(systemMetadata.getIdentifier());
178
          
179
      }
179 180
    
180 181
      return true;
181 182
  }
......
199 200
   */
200 201
  @Override
201 202
  public boolean setReplicationStatus(Session session, Identifier pid,
202
    NodeReference targetNode, ReplicationStatus status, long serialVersion) 
203
    throws ServiceFailure, NotImplemented, InvalidToken, NotAuthorized, 
204
    InvalidRequest, NotFound {
203
      NodeReference targetNode, ReplicationStatus status, long serialVersion) 
204
      throws ServiceFailure, NotImplemented, InvalidToken, NotAuthorized, 
205
      InvalidRequest, NotFound {
206
      
207
      boolean allowed = false;
208
      int replicaEntryIndex = -1;
209
      List<Replica> replicas = null;
210
      // get the subject
211
      Subject subject = session.getSubject();
212
      
213
      SystemMetadata systemMetadata = null;
214
      try {      
215
          HazelcastService.getInstance().getSystemMetadataMap().lock(pid);
216
          systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
217
          
218
          replicas = systemMetadata.getReplicaList();
219
          int count = 0;
220
          
221
          // find the target replica index in the replica list
222
          for (Replica replica: replicas) {
223
              if (replica.getReplicaMemberNode().getValue().equals(targetNode.getValue())) {
224
                  replicaEntryIndex = count;
225
                  break;
226
              }
227
              count++;
228
              
229
          }
205 230

  
206
    // get the subject
207
    Subject subject = session.getSubject();
208
    
209
    // are we allowed to do this?
210
    if (!isAuthorized(session, pid, Permission.WRITE)) {
211
      throw new NotAuthorized("4720", Permission.WRITE + " not allowed by " + 
212
          subject.getValue() + " on " + pid.getValue());  
213
    }
214
    
215
    SystemMetadata systemMetadata = null;
216
    try {      
217
        HazelcastService.getInstance().getSystemMetadataMap().lock(pid);
218
        systemMetadata = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
231
          // are we allowed to do this? only CNs and target MNs are allowed
232
          CNode cn = D1Client.getCN();
233
          List<Node> nodes = cn.listNodes().getNodeList();
234
          
235
          // find the node in the node list
236
          for ( Node node : nodes ) {
237
              
238
              NodeReference nodeReference = node.getIdentifier();
239
              logMetacat.debug("In setReplicationStatus(), Node reference is: " + nodeReference.getValue());
240
              
241
              // allow target MN certs and CN certs
242
              if (targetNode.getValue().equals(nodeReference.getValue()) ||
243
                  node.getType() == NodeType.CN) {
244
                  List<Subject> nodeSubjects = node.getSubjectList();
245
                  
246
                  // check if the session subject is in the node subject list
247
                  for (Subject nodeSubject : nodeSubjects) {
248
                      if ( CertificateManager.getInstance().equalsDN(
249
                              nodeSubject.getValue(), subject.getValue()) ) {
250
                          allowed = true; // subject of session == target node subject
251
                          break;
252
                          
253
                      }
254
                  }                 
255
              }
256
          }
219 257

  
220

  
221
        // does the request have the most current system metadata?
222
        if ( systemMetadata.getSerialVersion().longValue() != serialVersion ) {
223
           String msg = "The requested system metadata version number " + 
224
               serialVersion + "differs from the current version at " +
225
               systemMetadata.getSerialVersion().longValue() +
226
               " Please get the latest copy in order to modify it.";
227
           throw new InvalidRequest("4730", msg);
228
        }
258
          if ( !allowed ) {
259
              String msg = "The subject identified by " + subject.getValue() +
260
                " does not have permission to set the replication status for " +
261
                "the replica identified by " + targetNode.getValue() + ".";
262
              logMetacat.info(msg);
263
              throw new NotAuthorized("4720", msg);
264
              
265
          }
266
          
267
          // does the request have the most current system metadata?
268
          if ( systemMetadata.getSerialVersion().longValue() != serialVersion ) {
269
             String msg = "The requested system metadata version number " + 
270
                 serialVersion + "differs from the current version at " +
271
                 systemMetadata.getSerialVersion().longValue() +
272
                 " Please get the latest copy in order to modify it.";
273
             throw new InvalidRequest("4730", msg);
274
          }
275
          
276
      } catch (Exception e) { // Catch is generic since HZ throws RuntimeException
277
        throw new NotFound("4740", "No record found for: " + pid.getValue() +
278
            " : " + e.getMessage());
229 279
        
230
    } catch (Exception e) { // Catch is generic since HZ throws RuntimeException
231
      throw new NotFound("4740", "No record found for: " + pid.getValue() +
232
          " : " + e.getMessage());
280
      }
281
          
282
      // set the status for the replica
283
      if ( replicaEntryIndex != -1 ) {          
284
          replicas.get(replicaEntryIndex).setReplicationStatus(status);
285
          
286
      }
287
            
288
      // update the metadata
289
      try {
290
          systemMetadata.setSerialVersion(systemMetadata.getSerialVersion().add(BigInteger.ONE));
291
          systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
292
          HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
293
          HazelcastService.getInstance().getSystemMetadataMap().unlock(systemMetadata.getIdentifier());
294
        
295
      } catch (Exception e) {
296
          throw new ServiceFailure("4700", e.getMessage());
233 297
      
234
    }
235
        
236
    // set the status for the replica
237
    List<Replica> replicas = systemMetadata.getReplicaList();
238
    for (Replica replica: replicas) {
239
        if (replica.getReplicaMemberNode().getValue().equals(targetNode.getValue())) {
240
            replica.setReplicationStatus(status);
241
            
242
        }
243
    }
244
    
245
    // [re]set the list -- redundant?
246
    systemMetadata.setReplicaList(replicas);
247
    
248
    // update the metadata
249
    try {
250
        systemMetadata.setSerialVersion(systemMetadata.getSerialVersion().add(BigInteger.ONE));
251
        systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
252
	      HazelcastService.getInstance().getSystemMetadataMap().put(systemMetadata.getIdentifier(), systemMetadata);
253
	      HazelcastService.getInstance().getSystemMetadataMap().unlock(systemMetadata.getIdentifier());
254
	    
255
    } catch (Exception e) {
256
		    throw new ServiceFailure("4700", e.getMessage());
257
		
258
	  } finally {
259
	      HazelcastService.getInstance().getSystemMetadataMap().unlock(systemMetadata.getIdentifier());
260
	      
261
	  }
262
	
263
    return true;
298
      } finally {
299
          HazelcastService.getInstance().getSystemMetadataMap().unlock(systemMetadata.getIdentifier());
300
          
301
      }
302
      
303
      return true;
264 304
  }
265 305

  
266 306
  /**
......
615 655
          HazelcastService.getInstance().getSystemMetadataMap().unlock(sysmeta.getIdentifier());
616 656
          
617 657
      } catch (Exception e) {
618
      	logMetacat.error("Problem registering system metadata: " + pid.getValue(), e);
658
        logMetacat.error("Problem registering system metadata: " + pid.getValue(), e);
619 659
          throw new ServiceFailure("4862", "Error inserting system metadata: " + 
620 660
              e.getClass() + ": " + e.getMessage());
621 661
          
......
755 795
      try {
756 796
          systemMetadata.setSerialVersion(systemMetadata.getSerialVersion().add(BigInteger.ONE));
757 797
          systemMetadata.setDateSysMetadataModified(Calendar.getInstance().getTime());
758
	        HazelcastService.getInstance().getSystemMetadataMap().put(pid, systemMetadata);
759
	        HazelcastService.getInstance().getSystemMetadataMap().unlock(pid);
760
	        
798
          HazelcastService.getInstance().getSystemMetadataMap().put(pid, systemMetadata);
799
          HazelcastService.getInstance().getSystemMetadataMap().unlock(pid);
800
          
761 801
      } catch (Exception e) {
762
		  throw new ServiceFailure("4490", e.getMessage());
763
		  
764
	    } finally {
765
	        HazelcastService.getInstance().getSystemMetadataMap().unlock(pid);
766
	    }
802
      throw new ServiceFailure("4490", e.getMessage());
767 803
      
804
      } finally {
805
          HazelcastService.getInstance().getSystemMetadataMap().unlock(pid);
806
      }
807
      
768 808
      return pid;
769 809
  }
770 810

  
......
792 832
    throws NotImplemented, NotAuthorized, InvalidToken, ServiceFailure, 
793 833
    NotFound, InvalidRequest {
794 834

  
795
	  boolean isAllowed = false;
796
	  SystemMetadata sysmeta = null;
835
    boolean isAllowed = false;
836
    SystemMetadata sysmeta = null;
797 837
    NodeReference targetNode = null;
798 838
    
799
	  try {
800
	    // get the target node reference from the nodes list
801
	    CNode cn = D1Client.getCN();
802
	    List<Node> nodes = cn.listNodes().getNodeList();
839
    try {
840
      // get the target node reference from the nodes list
841
      CNode cn = D1Client.getCN();
842
      List<Node> nodes = cn.listNodes().getNodeList();
803 843

  
804
	    for ( Node node : nodes ) {
805
	        Subject nodeSubject = node.getSubject(0);
806
	        if (nodeSubject.getValue().equals(targetNodeSubject)) {
807
	            targetNode = node.getIdentifier();
808
	            
809
	        }
810
	    }
811
	    
844
      for ( Node node : nodes ) {
845
          Subject nodeSubject = node.getSubject(0);
846
          if (nodeSubject.getValue().equals(targetNodeSubject)) {
847
              targetNode = node.getIdentifier();
848
              
849
          }
850
      }
851
      
812 852

  
813
	    //lock, get, and unlock the pid
814
	    HazelcastService.getInstance().getSystemMetadataMap().lock(pid);
815
	    sysmeta = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
816
	    List<Replica> replicaList = sysmeta.getReplicaList();
817
	    
853
      //lock, get, and unlock the pid
854
      HazelcastService.getInstance().getSystemMetadataMap().lock(pid);
855
      sysmeta = HazelcastService.getInstance().getSystemMetadataMap().get(pid);
856
      List<Replica> replicaList = sysmeta.getReplicaList();
857
      
818 858
      // find the replica with the status set to 'requested'
819 859
      for (Replica replica : replicaList) {
820 860
          ReplicationStatus status = replica.getReplicationStatus();
......
829 869
      
830 870
      HazelcastService.getInstance().getSystemMetadataMap().unlock(pid);
831 871

  
832
	  } catch(RuntimeException e) {
833
	      // Catch Hazelcast RuntimeExceptions
834
	      throw new ServiceFailure("4872", 
835
	          "RuntimeException: Couldn't determine if node is allowed: " + 
836
	          e.getStackTrace().toString());
837
	    
872
    } catch(RuntimeException e) {
873
        // Catch Hazelcast RuntimeExceptions
874
        throw new ServiceFailure("4872", 
875
            "RuntimeException: Couldn't determine if node is allowed: " + 
876
            e.getStackTrace().toString());
877
      
838 878
    } catch(Exception e) {
839 879
        throw new ServiceFailure("4872", 
840 880
                "General Exception: Couldn't determine if node is allowed: " + 
841 881
                e.getStackTrace().toString());
842 882
        
843
	  } finally {
844
	    // always unlock the pid
883
    } finally {
884
      // always unlock the pid
845 885
      HazelcastService.getInstance().getSystemMetadataMap().unlock(pid);
846 886

  
847
	  }
848
	    
849
	  return isAllowed;
887
    }
888
      
889
    return isAllowed;
850 890
    
851 891
  }
852 892

  
......
1097 1137
      
1098 1138
  }
1099 1139
  
1100
  	@Override
1101
  	public ObjectList listObjects(Session session, Date startTime, 
1140
    @Override
1141
    public ObjectList listObjects(Session session, Date startTime, 
1102 1142
            Date endTime, ObjectFormatIdentifier formatid, Boolean replicaStatus,
1103 1143
            Integer start, Integer count)
1104
			throws InvalidRequest, InvalidToken, NotAuthorized, NotImplemented,
1105
			ServiceFailure {
1106
  		
1107
  		ObjectList objectList = null;
1144
      throws InvalidRequest, InvalidToken, NotAuthorized, NotImplemented,
1145
      ServiceFailure {
1146
      
1147
      ObjectList objectList = null;
1108 1148
        try {
1109 1149
            objectList = IdentifierManager.getInstance().querySystemMetadata(startTime, endTime, formatid, replicaStatus, start, count);
1110 1150
        } catch (Exception e) {
......
1112 1152
        }
1113 1153

  
1114 1154
        return objectList;
1115
	}
1155
  }
1116 1156
}

Also available in: Unified diff