diff --git a/access-control-app/src/cmr/access_control/services/acl_service.clj b/access-control-app/src/cmr/access_control/services/acl_service.clj index 47745ca..4376802 100644 --- a/access-control-app/src/cmr/access_control/services/acl_service.clj +++ b/access-control-app/src/cmr/access_control/services/acl_service.clj @@ -53,7 +53,8 @@ (common-enabled/validate-write-enabled context "access control") (v/validate-acl-save! context acl :create) (acl-auth/authorize-acl-action context :create acl) - (acl-util/create-acl context acl)) + (let [acl (acl-util/sync-entry-titles-concept-ids context acl)] + (acl-util/create-acl context acl))) (defn update-acl "Update the ACL with the given concept-id in Metadata DB. Returns map with concept and revision id of updated acl." @@ -73,7 +74,8 @@ (errors/throw-service-error :invalid-data (format "ACL legacy guid cannot be updated, was [%s] and now [%s]" existing-legacy-guid legacy-guid))) - (let [new-concept (merge (acl-util/acl->base-concept context acl) + (let [acl (acl-util/sync-entry-titles-concept-ids context acl) + new-concept (merge (acl-util/acl->base-concept context acl) {:concept-id concept-id :native-id (:native-id existing-concept)}) resp (mdb/save-concept context new-concept)] diff --git a/access-control-app/src/cmr/access_control/services/acl_util.clj b/access-control-app/src/cmr/access_control/services/acl_util.clj index 982ac5f..4887563 100644 --- a/access-control-app/src/cmr/access_control/services/acl_util.clj +++ b/access-control-app/src/cmr/access_control/services/acl_util.clj @@ -14,6 +14,7 @@ [cmr.common-app.services.search.query-model :as qm] [cmr.transmit.echo.tokens :as tokens] [cmr.transmit.metadata-db2 :as mdb] + [cmr.transmit.metadata-db :as mdb1] [cmr.common-app.services.search.group-query-conditions :as gc])) (def acl-provider-id @@ -102,3 +103,25 @@ (qm/string-condition :target target)) identity-type-condition)] (get-acls-by-condition context condition))) + +(defn sync-entry-titles-concept-ids + "If the given ACL is a catalog item acl with a collection identifier that includes concept-ids or + entry-titles, return the ACL such that both are unioned with each other." + [context acl] + (if-let [collection-identifier (get-in acl [:catalog-item-identity :collection-identifier])] + (let [entry-titles (:entry-titles collection-identifier) + concept-ids (:concept-ids collection-identifier) + provider-id (get-in acl [:catalog-item-identity :provider-id]) + colls-from-entry-titles (when (seq entry-titles) + (mdb1/find-concepts context {:provider-id provider-id :entry-title entry-titles} :collection)) + colls-from-concept-ids (when (seq concept-ids) + (mdb1/find-concepts context {:provider-id provider-id :concept-id concept-ids} :collection)) + collections (distinct (concat colls-from-entry-titles colls-from-concept-ids)) + concept-ids (map :concept-id collections) + entry-titles (map #(get-in % [:extra-fields :entry-title]) collections) + collection-identifier (-> collection-identifier + (assoc :entry-titles entry-titles) + (assoc :concept-ids concept-ids) + util/remove-nil-keys)] + (assoc-in acl [:catalog-item-identity :collection-identifier] collection-identifier)) + acl)) diff --git a/access-control-app/src/cmr/access_control/services/event_handler.clj b/access-control-app/src/cmr/access_control/services/event_handler.clj index 9cafb46..000c25b 100644 --- a/access-control-app/src/cmr/access_control/services/event_handler.clj +++ b/access-control-app/src/cmr/access_control/services/event_handler.clj @@ -81,28 +81,27 @@ [context {:keys [concept-id revision-id]}] (let [concept-map (mdb/get-concept context concept-id revision-id) collection-concept (acl-matchers/add-acl-enforcement-fields-to-concept concept-map)] - (doseq [key-path [:entry-titles :concept-ids] - acl-concept (acl-service/get-all-acl-concepts context) + (doseq [acl-concept (acl-service/get-all-acl-concepts context) :let [parsed-acl (acl-service/get-parsed-acl acl-concept) catalog-item-id (:catalog-item-identity parsed-acl) - value (if (= key-path :entry-titles) - (:EntryTitle collection-concept) - (:concept-id collection-concept)) - acl-values (get (:collection-identifier catalog-item-id) key-path)] + concept-ids (get (:collection-identifier catalog-item-id) :concept-ids)] :when (and (= (:provider-id collection-concept) (:provider-id catalog-item-id)) - (some #{value} acl-values))] - (if (= 1 (count acl-values)) + (some #{concept-id} concept-ids))] + (if (= 1 (count concept-ids)) ;; The ACL only references the collection being deleted, and therefore the ACL should be deleted. ;; With the addition of concept-ids, this assumes entry-titles and concept-ids are in sync. (acl-service/delete-acl (transmit-config/with-echo-system-token context) (:concept-id acl-concept)) ;; Otherwise the ACL references other collections, and will be updated - (let [new-acl (update-in parsed-acl - [:catalog-item-identity :collection-identifier key-path] - #(remove #{value} %))] + (let [new-acl (-> parsed-acl + (assoc-in [:catalog-item-identity :collection-identifier :concept-ids] + (remove #(= % concept-id) concept-ids)) + (update-in [:catalog-item-identity :collection-identifier] + dissoc :entry-titles))] (acl-service/update-acl (transmit-config/with-echo-system-token context) (:concept-id acl-concept) new-acl)))))) + (defn subscribe-to-events "Subscribe to event messages on various queues" [context]