- if(renew.isOK()) {
- return Result.err(Result.ERR_NotImplemented,"Not implemented yet");
- } else {
- return Result.err(renew);
- }
- }
-
- public Result<Void> dropCert(AuthzTrans trans, Result<CertDrop> drop) {
- if(drop.isOK()) {
- return Result.err(Result.ERR_NotImplemented,"Not implemented yet");
- } else {
- return Result.err(drop);
- }
- }
-
- public Result<List<Data>> readCertsByMechID(AuthzTrans trans, String mechID) {
- // Policy 1: To Read, must have NS Read or is Sponsor
- String ns = Question.domain2ns(mechID);
- try {
- if( trans.user().equals(mechID)
- || trans.fish(new AAFPermission(ns + ".access", "*", "read"))
- || (trans.org().validate(trans,Organization.Policy.OWNS_MECHID,null,mechID))==null) {
- return certDAO.readID(trans, mechID);
- } else {
- return Result.err(Result.ERR_Denied,"%s is not the ID, Sponsor or NS Owner/Admin for %s at %s",
- trans.user(),mechID,trans.org().getName());
- }
- } catch(OrganizationException e) {
- return Result.err(e);
- }
- }
-
- public Result<CertResp> requestPersonalCert(AuthzTrans trans, CA ca) {
- if(ca.inPersonalDomains(trans.getUserPrincipal())) {
- Organization org = trans.org();
-
- // Policy 1: MechID must be current
- Identity ouser;
- try {
- ouser = org.getIdentity(trans, trans.user());
- } catch (OrganizationException e1) {
- trans.error().log(e1);
- ouser = null;
- }
- if(ouser == null) {
- return Result.err(Result.ERR_Policy,"Requesting User must exist in %s",org.getName());
- }
-
- // Set Email from most current Sponsor
-
- CSRMeta csrMeta;
- try {
- csrMeta = BCFactory.createPersonalCSRMeta(
- ca,
- trans.user(),
- ouser.email());
- X509andChain x509ac = ca.sign(trans, csrMeta);
- if(x509ac==null) {
- return Result.err(Result.ERR_ActionNotCompleted,"x509 Certificate not signed by CA");
- }
- X509Certificate x509 = x509ac.getX509();
- CertDAO.Data cdd = new CertDAO.Data();
- cdd.ca=ca.getName();
- cdd.serial=x509.getSerialNumber();
- cdd.id=trans.user();
- cdd.x500=x509.getSubjectDN().getName();
- cdd.x509=Factory.toString(trans, x509);
- certDAO.create(trans, cdd);
-
- CertResp cr = new CertResp(trans, ca, x509, csrMeta, x509ac.getTrustChain(), ca.getTrustedCAs(), compileNotes(null));
- return Result.ok(cr);
- } catch (Exception e) {
- trans.error().log(e);
- return Result.err(Result.ERR_ActionNotCompleted,e.getMessage());
- }
- } else {
- return Result.err(Result.ERR_Denied,trans.user()," not supported for CA",ca.getName());
- }
- }
-
- ///////////////
- // Artifact
- //////////////
- public Result<Void> createArtifact(AuthzTrans trans, List<ArtiDAO.Data> list) {
- CertmanValidator v = new CertmanValidator().artisRequired(list, 1);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
- }
- for(ArtiDAO.Data add : list) {
- try {
- // Policy 1: MechID must exist in Org
- Identity muser = trans.org().getIdentity(trans, add.mechid);
- if(muser == null) {
- return Result.err(Result.ERR_Denied,"%s is not valid for %s", add.mechid,trans.org().getName());
- }
-
- // Policy 2: MechID must have valid Organization Owner
- Identity ouser = muser.responsibleTo();
- if(ouser == null) {
- return Result.err(Result.ERR_Denied,"%s is not a valid Sponsor for %s at %s",
- trans.user(),add.mechid,trans.org().getName());
- }
-
- // Policy 3: Calling ID must be MechID Owner
- if(!trans.user().equals(ouser.fullID())) {
- return Result.err(Result.ERR_Denied,"%s is not the Sponsor for %s at %s",
- trans.user(),add.mechid,trans.org().getName());
- }
-
- // Policy 4: Renewal Days are between 10 and 60 (constants, may be parameterized)
- if(add.renewDays<MIN_RENEWAL) {
- add.renewDays = STD_RENEWAL;
- } else if(add.renewDays>MAX_RENEWAL) {
- add.renewDays = MAX_RENEWAL;
- }
-
- // Policy 5: If Notify is blank, set to Owner's Email
- if(add.notify==null || add.notify.length()==0) {
- add.notify = "mailto:"+ouser.email();
- }
-
- // Policy 6: Only do Domain by Exception
- if(add.machine.startsWith("*")) { // Domain set
- CA ca = certman.getCA(add.ca);
-
-
- if(!trans.fish(new AAFPermission(ca.getPermType(), add.ca, DOMAIN))) {
- return Result.err(Result.ERR_Denied,"Domain Artifacts (%s) requires specific Permission",
- add.machine);
- }
- }
-
- // Set Sponsor from Golden Source
- add.sponsor = ouser.fullID();
-
-
- } catch (OrganizationException e) {
- return Result.err(e);
- }
- // Add to DB
- Result<ArtiDAO.Data> rv = artiDAO.create(trans, add);
- // TODO come up with Partial Reporting Scheme, or allow only one at a time.
- if(rv.notOK()) {
- return Result.err(rv);
- }
- }
- return Result.ok();
- }
-
- public Result<List<ArtiDAO.Data>> readArtifacts(AuthzTrans trans, ArtiDAO.Data add) throws OrganizationException {
- CertmanValidator v = new CertmanValidator().keys(add);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
- }
- Result<List<ArtiDAO.Data>> data = artiDAO.read(trans, add);
- if(data.notOKorIsEmpty()) {
- return data;
- }
- add = data.value.get(0);
- if( trans.user().equals(add.mechid)
- || trans.fish(new AAFPermission(add.ns + ".access", "*", "read"))
- || trans.fish(new AAFPermission(add.ns+".certman",add.ca,"read"))
- || trans.fish(new AAFPermission(add.ns+".certman",add.ca,"request"))
- || (trans.org().validate(trans,Organization.Policy.OWNS_MECHID,null,add.mechid))==null) {
- return data;
- } else {
- return Result.err(Result.ERR_Denied,"%s is not %s, is not the sponsor, and doesn't have delegated permission.",trans.user(),add.mechid,add.ns+".certman|"+add.ca+"|read or ...|request"); // note: reason is set by 2nd case, if 1st case misses
- }
-
- }
-
- public Result<List<ArtiDAO.Data>> readArtifactsByMechID(AuthzTrans trans, String mechid) throws OrganizationException {
- CertmanValidator v = new CertmanValidator();
- v.nullOrBlank("mechid", mechid);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
- }
- String ns = FQI.reverseDomain(mechid);
-
- String reason;
- if(trans.fish(new AAFPermission(ns + ".access", "*", "read"))
- || (reason=trans.org().validate(trans,Organization.Policy.OWNS_MECHID,null,mechid))==null) {
- return artiDAO.readByMechID(trans, mechid);
- } else {
- return Result.err(Result.ERR_Denied,reason); // note: reason is set by 2nd case, if 1st case misses
- }
-
- }
-
- public Result<List<ArtiDAO.Data>> readArtifactsByMachine(AuthzTrans trans, String machine) {
- CertmanValidator v = new CertmanValidator();
- v.nullOrBlank("machine", machine);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
- }
-
- // TODO do some checks?
-
- Result<List<ArtiDAO.Data>> rv = artiDAO.readByMachine(trans, machine);
- return rv;
- }
-
- public Result<List<ArtiDAO.Data>> readArtifactsByNs(AuthzTrans trans, String ns) {
- CertmanValidator v = new CertmanValidator();
- v.nullOrBlank("ns", ns);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
- }
-
- // TODO do some checks?
-
- Result<List<ArtiDAO.Data>> rv = artiDAO.readByNs(trans, ns);
- return rv;
- }
-
-
- public Result<Void> updateArtifact(AuthzTrans trans, List<ArtiDAO.Data> list) throws OrganizationException {
- CertmanValidator v = new CertmanValidator();
- v.artisRequired(list, 1);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
- }
-
- // Check if requesting User is Sponsor
- //TODO - Shall we do one, or multiples?
- for(ArtiDAO.Data add : list) {
- // Policy 1: MechID must exist in Org
- Identity muser = trans.org().getIdentity(trans, add.mechid);
- if(muser == null) {
- return Result.err(Result.ERR_Denied,"%s is not valid for %s", add.mechid,trans.org().getName());
- }
-
- // Policy 2: MechID must have valid Organization Owner
- Identity ouser = muser.responsibleTo();
- if(ouser == null) {
- return Result.err(Result.ERR_Denied,"%s is not a valid Sponsor for %s at %s",
- trans.user(),add.mechid,trans.org().getName());
- }
-
- // Policy 3: Renewal Days are between 10 and 60 (constants, may be parameterized)
- if(add.renewDays<MIN_RENEWAL) {
- add.renewDays = STD_RENEWAL;
- } else if(add.renewDays>MAX_RENEWAL) {
- add.renewDays = MAX_RENEWAL;
- }
-
- // Policy 4: Data is always updated with the latest Sponsor
- // Add to Sponsor, to make sure we are always up to date.
- add.sponsor = ouser.fullID();
-
- // Policy 5: If Notify is blank, set to Owner's Email
- if(add.notify==null || add.notify.length()==0) {
- add.notify = "mailto:"+ouser.email();
- }
- // Policy 6: Only do Domain by Exception
- if(add.machine.startsWith("*")) { // Domain set
- CA ca = certman.getCA(add.ca);
- if(ca==null) {
- return Result.err(Result.ERR_BadData, "CA is required in Artifact");
- }
- if(!trans.fish(new AAFPermission(ca.getPermType(), add.ca, DOMAIN))) {
- return Result.err(Result.ERR_Denied,"Domain Artifacts (%s) requires specific Permission",
- add.machine);
- }
- }
-
- // Policy 7: only Owner may update info
- if(trans.user().equals(add.sponsor)) {
- return artiDAO.update(trans, add);
- } else {
- return Result.err(Result.ERR_Denied,"%s may not update info for %s",trans.user(),muser.fullID());
- }
- }
- return Result.err(Result.ERR_BadData,"No Artifacts to update");
- }
-
- public Result<Void> deleteArtifact(AuthzTrans trans, String mechid, String machine) throws OrganizationException {
- CertmanValidator v = new CertmanValidator();
- v.nullOrBlank("mechid", mechid)
- .nullOrBlank("machine", machine);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
- }
-
- Result<List<ArtiDAO.Data>> rlad = artiDAO.read(trans, mechid, machine);
- if(rlad.notOKorIsEmpty()) {
- return Result.err(Result.ERR_NotFound,"Artifact for %s %s does not exist.",mechid,machine);
- }
-
- return deleteArtifact(trans,rlad.value.get(0));
- }
-
- private Result<Void> deleteArtifact(AuthzTrans trans, ArtiDAO.Data add) throws OrganizationException {
- // Policy 1: Record should be delete able only by Existing Sponsor.
- String sponsor=null;
- Identity muser = trans.org().getIdentity(trans, add.mechid);
- if(muser != null) {
- Identity ouser = muser.responsibleTo();
- if(ouser!=null) {
- sponsor = ouser.fullID();
- }
- }
- // Policy 1.a: If Sponsorship is deleted in system of Record, then
- // accept deletion by sponsor in Artifact Table
- if(sponsor==null) {
- sponsor = add.sponsor;
- }
-
- String ns = FQI.reverseDomain(add.mechid);
-
- if(trans.fish(new AAFPermission(ns + ".access", "*", "write"))
- || trans.user().equals(sponsor)) {
- return artiDAO.delete(trans, add, false);
- }
- return Result.err(Result.ERR_Denied, "%1 is not allowed to delete this item",trans.user());
- }
-
- public Result<Void> deleteArtifact(AuthzTrans trans, List<ArtiDAO.Data> list) {
- CertmanValidator v = new CertmanValidator().artisRequired(list, 1);
- if(v.err()) {
- return Result.err(Result.ERR_BadData,v.errs());
- }
-
- try {
- boolean partial = false;
- Result<Void> result=null;
- for(ArtiDAO.Data add : list) {
- result = deleteArtifact(trans, add);
- if(result.notOK()) {
- partial = true;
- }
- }
- if(result == null) {
- result = Result.err(Result.ERR_BadData,"No Artifacts to delete");
- } else if(partial) {
- result.partialContent(true);
- }
- return result;
- } catch(Exception e) {
- return Result.err(e);
- }
- }
-
- private String[] compileNotes(List<String> notes) {
- String[] rv;
- if(notes==null) {
- rv = NO_NOTES;
- } else {
- rv = new String[notes.size()];
- notes.toArray(rv);
- }
- return rv;
- }
-
- private ByteBuffer getChallenge256SaltedHash(String challenge, int salt) throws NoSuchAlgorithmException {
- ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE + challenge.length());
- bb.putInt(salt);
- bb.put(challenge.getBytes());
- byte[] hash = Hash.hashSHA256(bb.array());
- return ByteBuffer.wrap(hash);
- }
-}
+ if (renew.isOK()) {
+ return Result.err(Result.ERR_NotImplemented, "Not implemented yet");
+ } else {
+ return Result.err(renew);
+ }
+ }
+
+ public Result<Void> dropCert(AuthzTrans trans, Result<CertDrop> drop) {
+ if (drop.isOK()) {
+ return Result.err(Result.ERR_NotImplemented, "Not implemented yet");
+ } else {
+ return Result.err(drop);
+ }
+ }
+
+ public Result<List<Data>> readCertsByMechID(AuthzTrans trans, String mechID) {
+ // Policy 1: To Read, must have NS Read or is Sponsor
+ String ns = Question.domain2ns(mechID);
+ try {
+ if (trans.user().equals(mechID) || trans.fish(new AAFPermission(ns,ACCESS, "*", "read"))
+ || (trans.org().validate(trans, Organization.Policy.OWNS_MECHID, null, mechID)) == null) {
+ return certDAO.readID(trans, mechID);
+ } else {
+ return Result.err(Result.ERR_Denied, "%s is not the ID, Sponsor or NS Owner/Admin for %s at %s",
+ trans.user(), mechID, trans.org().getName());
+ }
+ } catch (OrganizationException e) {
+ return Result.err(e);
+ }
+ }
+
+ public Result<CertResp> requestPersonalCert(AuthzTrans trans, CA ca) {
+ if (ca.inPersonalDomains(trans.getUserPrincipal())) {
+ Organization org = trans.org();
+
+ // Policy 1: MechID must be current
+ Identity ouser;
+ try {
+ ouser = org.getIdentity(trans, trans.user());
+ } catch (OrganizationException e1) {
+ trans.debug().log(e1);
+ ouser = null;
+ }
+ if (ouser == null) {
+ return Result.err(Result.ERR_Policy, "Requesting User must exist in %s", org.getName());
+ }
+
+ // Set Email from most current Sponsor
+
+ CSRMeta csrMeta;
+ try {
+ csrMeta = BCFactory.createPersonalCSRMeta(ca, trans.user(), ouser.email());
+ X509andChain x509ac = ca.sign(trans, csrMeta);
+ if (x509ac == null) {
+ return Result.err(Result.ERR_ActionNotCompleted, "x509 Certificate not signed by CA");
+ }
+ X509Certificate x509 = x509ac.getX509();
+ CertDAO.Data cdd = new CertDAO.Data();
+ cdd.ca = ca.getName();
+ cdd.serial = x509.getSerialNumber();
+ cdd.id = trans.user();
+ cdd.x500 = x509.getSubjectDN().getName();
+ cdd.x509 = Factory.toString(trans, x509);
+ certDAO.create(trans, cdd);
+
+ CertResp cr = new CertResp(trans, ca, x509, csrMeta, x509ac.getTrustChain(), compileNotes(null));
+ return Result.ok(cr);
+ } catch (Exception e) {
+ trans.debug().log(e);
+ return Result.err(Result.ERR_ActionNotCompleted, e.getMessage());
+ }
+ } else {
+ return Result.err(Result.ERR_Denied, trans.user(), " not supported for CA", ca.getName());
+ }
+ }
+
+ ///////////////
+ // Artifact
+ //////////////
+ public Result<Void> createArtifact(AuthzTrans trans, List<ArtiDAO.Data> list) {
+ CertmanValidator v = new CertmanValidator().artisRequired(list, 1);
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
+ }
+ for (ArtiDAO.Data add : list) {
+ try {
+ // Policy 1: MechID must exist in Org
+ Identity muser = trans.org().getIdentity(trans, add.mechid);
+ if (muser == null) {
+ return Result.err(Result.ERR_Denied, "%s is not valid for %s", add.mechid, trans.org().getName());
+ }
+
+ // Policy 2: MechID must have valid Organization Owner
+ Identity emailUser;
+ if (muser.isPerson()) {
+ emailUser = muser;
+ } else {
+ Identity ouser = muser.responsibleTo();
+ if (ouser == null) {
+ return Result.err(Result.ERR_Denied, "%s is not a valid Sponsor for %s at %s", trans.user(),
+ add.mechid, trans.org().getName());
+ }
+
+ // Policy 3: Calling ID must be MechID Owner
+ if (!trans.user().startsWith(ouser.id())) {
+ return Result.err(Result.ERR_Denied, "%s is not the Sponsor for %s at %s", trans.user(),
+ add.mechid, trans.org().getName());
+ }
+ emailUser = ouser;
+ }
+
+ // Policy 4: Renewal Days are between 10 and 60 (constants, may be
+ // parameterized)
+ if (add.renewDays < MIN_RENEWAL) {
+ add.renewDays = STD_RENEWAL;
+ } else if (add.renewDays > MAX_RENEWAL) {
+ add.renewDays = MAX_RENEWAL;
+ }
+
+ // Policy 5: If Notify is blank, set to Owner's Email
+ if (add.notify == null || add.notify.length() == 0) {
+ add.notify = "mailto:" + emailUser.email();
+ }
+
+ // Policy 6: Only do Domain by Exception
+ if (add.machine.startsWith("*")) { // Domain set
+ CA ca = certManager.getCA(add.ca);
+ if (!trans.fish(new AAFPermission(ca.getPermNS(),ca.getPermType(), add.ca, DOMAIN))) {
+ return Result.err(Result.ERR_Denied, "Domain Artifacts (%s) requires specific Permission",
+ add.machine);
+ }
+ }
+
+ // Set Sponsor from Golden Source
+ add.sponsor = emailUser.fullID();
+
+ } catch (OrganizationException e) {
+ return Result.err(e);
+ }
+ // Add to DB
+ Result<ArtiDAO.Data> rv = artiDAO.create(trans, add);
+ // come up with Partial Reporting Scheme, or allow only one at a time.
+ if (rv.notOK()) {
+ return Result.err(rv);
+ }
+ }
+ return Result.ok();
+ }
+
+ public Result<List<ArtiDAO.Data>> readArtifacts(AuthzTrans trans, ArtiDAO.Data add) throws OrganizationException {
+ CertmanValidator v = new CertmanValidator().keys(add);
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
+ }
+ Result<List<ArtiDAO.Data>> data = artiDAO.read(trans, add);
+ if (data.notOKorIsEmpty()) {
+ return data;
+ }
+ add = data.value.get(0);
+ if (trans.user().equals(add.mechid)
+ || trans.fish(root_read_permission,
+ new AAFPermission(add.ns,ACCESS, "*", "read"),
+ new AAFPermission(add.ns,CERTMAN, add.ca, "read"),
+ new AAFPermission(add.ns,CERTMAN, add.ca, REQUEST))
+ || (trans.org().validate(trans, Organization.Policy.OWNS_MECHID, null, add.mechid)) == null) {
+ return data;
+ } else {
+ return Result.err(Result.ERR_Denied,
+ "%s is not %s, is not the sponsor, and doesn't have delegated permission.", trans.user(),
+ add.mechid, add.ns + ".certman|" + add.ca + "|read or ...|request"); // note: reason is set by 2nd
+ // case, if 1st case misses
+ }
+
+ }
+
+ public Result<List<ArtiDAO.Data>> readArtifactsByMechID(AuthzTrans trans, String mechid)
+ throws OrganizationException {
+ CertmanValidator v = new CertmanValidator();
+ v.nullOrBlank("mechid", mechid);
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
+ }
+ String ns = FQI.reverseDomain(mechid);
+
+ String reason;
+ if (trans.fish(new AAFPermission(ns, ACCESS, "*", "read"))
+ || (reason = trans.org().validate(trans, Organization.Policy.OWNS_MECHID, null, mechid)) == null) {
+ return artiDAO.readByMechID(trans, mechid);
+ } else {
+ return Result.err(Result.ERR_Denied, reason); // note: reason is set by 2nd case, if 1st case misses
+ }
+
+ }
+
+ public Result<List<ArtiDAO.Data>> readArtifactsByMachine(AuthzTrans trans, String machine) {
+ CertmanValidator v = new CertmanValidator();
+ v.nullOrBlank("machine", machine);
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
+ }
+
+ // do some checks?
+
+ return artiDAO.readByMachine(trans, machine);
+ }
+
+ public Result<List<ArtiDAO.Data>> readArtifactsByNs(AuthzTrans trans, String ns) {
+ CertmanValidator v = new CertmanValidator();
+ v.nullOrBlank("ns", ns);
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
+ }
+
+ // do some checks?
+ return artiDAO.readByNs(trans, ns);
+ }
+
+ public Result<Void> updateArtifact(AuthzTrans trans, List<ArtiDAO.Data> list) throws OrganizationException {
+ CertmanValidator v = new CertmanValidator();
+ v.artisRequired(list, 1);
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
+ }
+
+ // Check if requesting User is Sponsor
+ // Shall we do one, or multiples?
+ for (ArtiDAO.Data add : list) {
+ // Policy 1: MechID must exist in Org
+ Identity muser = trans.org().getIdentity(trans, add.mechid);
+ if (muser == null) {
+ return Result.err(Result.ERR_Denied, "%s is not valid for %s", add.mechid, trans.org().getName());
+ }
+
+ // Policy 2: MechID must have valid Organization Owner
+ Identity ouser = muser.responsibleTo();
+ if (ouser == null) {
+ return Result.err(Result.ERR_Denied, "%s is not a valid Sponsor for %s at %s", trans.user(), add.mechid,
+ trans.org().getName());
+ }
+
+ // Policy 3: Renewal Days are between 10 and 60 (constants, may be
+ // parameterized)
+ if (add.renewDays < MIN_RENEWAL) {
+ add.renewDays = STD_RENEWAL;
+ } else if (add.renewDays > MAX_RENEWAL) {
+ add.renewDays = MAX_RENEWAL;
+ }
+
+ // Policy 4: Data is always updated with the latest Sponsor
+ // Add to Sponsor, to make sure we are always up to date.
+ add.sponsor = ouser.fullID();
+
+ // Policy 5: If Notify is blank, set to Owner's Email
+ if (add.notify == null || add.notify.length() == 0) {
+ add.notify = "mailto:" + ouser.email();
+ }
+ // Policy 6: Only do Domain by Exception
+ if (add.machine.startsWith("*")) { // Domain set
+ CA ca = certManager.getCA(add.ca);
+ if (ca == null) {
+ return Result.err(Result.ERR_BadData, "CA is required in Artifact");
+ }
+ if (!trans.fish(new AAFPermission(null,ca.getPermType(), add.ca, DOMAIN))) {
+ return Result.err(Result.ERR_Denied, "Domain Artifacts (%s) requires specific Permission",
+ add.machine);
+ }
+ }
+
+ // Policy 7: only Owner may update info
+ if (trans.user().startsWith(ouser.id())) {
+ return artiDAO.update(trans, add);
+ } else {
+ return Result.err(Result.ERR_Denied, "%s may not update info for %s", trans.user(), muser.fullID());
+ }
+ }
+ return Result.err(Result.ERR_BadData, "No Artifacts to update");
+ }
+
+ public Result<Void> deleteArtifact(AuthzTrans trans, String mechid, String machine) throws OrganizationException {
+ CertmanValidator v = new CertmanValidator();
+ v.nullOrBlank("mechid", mechid).nullOrBlank("machine", machine);
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
+ }
+
+ Result<List<ArtiDAO.Data>> rlad = artiDAO.read(trans, mechid, machine);
+ if (rlad.notOKorIsEmpty()) {
+ return Result.err(Result.ERR_NotFound, "Artifact for %s %s does not exist.", mechid, machine);
+ }
+
+ return deleteArtifact(trans, rlad.value.get(0));
+ }
+
+ private Result<Void> deleteArtifact(AuthzTrans trans, ArtiDAO.Data add) throws OrganizationException {
+ // Policy 1: Record should be delete able only by Existing Sponsor.
+ String sponsor = null;
+ Identity muser = trans.org().getIdentity(trans, add.mechid);
+ if (muser != null) {
+ Identity ouser = muser.responsibleTo();
+ if (ouser != null) {
+ sponsor = ouser.fullID();
+ }
+ }
+ // Policy 1.a: If Sponsorship is deleted in system of Record, then
+ // accept deletion by sponsor in Artifact Table
+ if (sponsor == null) {
+ sponsor = add.sponsor;
+ }
+
+ String ns = FQI.reverseDomain(add.mechid);
+
+ if (trans.fish(new AAFPermission(ns,ACCESS, "*", "write")) || trans.user().equals(sponsor)) {
+ return artiDAO.delete(trans, add, false);
+ }
+ return Result.err(Result.ERR_Denied, "%1 is not allowed to delete this item", trans.user());
+ }
+
+ public Result<Void> deleteArtifact(AuthzTrans trans, List<ArtiDAO.Data> list) {
+ CertmanValidator v = new CertmanValidator().artisRequired(list, 1);
+ if (v.err()) {
+ return Result.err(Result.ERR_BadData, v.errs());
+ }
+
+ try {
+ boolean partial = false;
+ Result<Void> result = null;
+ for (ArtiDAO.Data add : list) {
+ result = deleteArtifact(trans, add);
+ if (result.notOK()) {
+ partial = true;
+ }
+ }
+ if (result == null) {
+ result = Result.err(Result.ERR_BadData, "No Artifacts to delete");
+ } else if (partial) {
+ result.partialContent(true);
+ }
+ return result;
+ } catch (Exception e) {
+ return Result.err(e);
+ }
+ }
+
+ private String[] compileNotes(List<String> notes) {
+ String[] rv;
+ if (notes == null) {
+ rv = NO_NOTES;
+ } else {
+ rv = new String[notes.size()];
+ notes.toArray(rv);
+ }
+ return rv;
+ }
+
+ private ByteBuffer getChallenge256SaltedHash(String challenge, int salt) throws NoSuchAlgorithmException {
+ ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE + challenge.length());
+ bb.putInt(salt);
+ bb.put(challenge.getBytes());
+ byte[] hash = Hash.hashSHA256(bb.array());
+ return ByteBuffer.wrap(hash);
+ }
+}
\ No newline at end of file