View Javadoc
1   /*
2    * Copyright 2022 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.bremersee.acl.spring.data.mongodb.app;
18  
19  import java.util.Collection;
20  import java.util.List;
21  import java.util.Optional;
22  import org.bremersee.acl.AccessEvaluation;
23  import org.bremersee.acl.Acl;
24  import org.bremersee.acl.PermissionConstants;
25  import org.bremersee.acl.AclUserContext;
26  import org.bremersee.acl.model.AccessControlListModifications;
27  import org.bremersee.acl.spring.data.mongodb.AclCriteriaAndUpdateBuilder;
28  import org.bremersee.acl.spring.data.mongodb.AclIndexOperations;
29  import org.bremersee.acl.spring.data.mongodb.AclModificationUpdate;
30  import org.springframework.boot.context.event.ApplicationReadyEvent;
31  import org.springframework.context.event.EventListener;
32  import org.springframework.data.mongodb.core.FindAndModifyOptions;
33  import org.springframework.data.mongodb.core.MongoTemplate;
34  import org.springframework.data.mongodb.core.query.Criteria;
35  import org.springframework.data.mongodb.core.query.Query;
36  import org.springframework.data.mongodb.core.query.Update;
37  
38  /**
39   * The example entity repository.
40   *
41   * @author Christian Bremer
42   */
43  public class ExampleEntityRepositoryImpl implements ExampleEntityRepositoryCustom {
44  
45    private final AclCriteriaAndUpdateBuilder builder;
46  
47    private final MongoTemplate mongoTemplate;
48  
49    /**
50     * Instantiates a new example entity repository.
51     *
52     * @param mongoTemplate the mongo template
53     */
54    public ExampleEntityRepositoryImpl(MongoTemplate mongoTemplate) {
55      this.mongoTemplate = mongoTemplate;
56      builder = new AclCriteriaAndUpdateBuilder(ExampleEntity.class);
57    }
58  
59    /**
60     * Init.
61     */
62    @EventListener(ApplicationReadyEvent.class)
63    public void init() {
64      new AclIndexOperations(this.mongoTemplate).ensureAclIndexes(
65          ExampleEntity.class,
66          PermissionConstants.getAll(),
67          false);
68    }
69  
70    @Override
71    public Optional<ExampleEntity> findByOtherContent(
72        String otherContent,
73        AclUserContext userContext,
74        AccessEvaluation accessEvaluation,
75        Collection<String> permissions) {
76  
77      Criteria accessCriteria = builder.buildPermissionCriteria(
78          userContext,
79          accessEvaluation,
80          permissions);
81      Criteria otherContentCriteria = Criteria.where(ExampleEntity.OTHER_CONTENT).is(otherContent);
82      Query query = Query.query(new Criteria().andOperator(accessCriteria, otherContentCriteria));
83      return Optional.ofNullable(mongoTemplate.findOne(query, ExampleEntity.class));
84    }
85  
86    @Override
87    public Optional<ExampleEntity> modifyAclByOtherContent(
88        String otherContent,
89        AclUserContext userContext,
90        AccessControlListModifications modifications) {
91  
92      Criteria accessCriteria = builder.buildPermissionCriteria(
93          userContext,
94          AccessEvaluation.ANY_PERMISSION,
95          List.of(PermissionConstants.ADMINISTRATION));
96      Criteria otherContentCriteria = Criteria.where(ExampleEntity.OTHER_CONTENT).is(otherContent);
97      Query query = Query.query(new Criteria().andOperator(accessCriteria, otherContentCriteria));
98      AclModificationUpdate updates = builder.buildUpdate(modifications);
99      updates.getPreparationUpdates()
100         .forEach(preparationUpdate -> mongoTemplate
101             .updateFirst(query, preparationUpdate, ExampleEntity.class));
102     FindAndModifyOptions options = new FindAndModifyOptions()
103         .returnNew(true);
104     return Optional.ofNullable(mongoTemplate.findAndModify(
105         query,
106         updates.getFinalUpdate(),
107         options,
108         ExampleEntity.class));
109   }
110 
111   @Override
112   public Optional<ExampleEntity> replaceAclByOtherContent(String otherContent, Acl newAcl) {
113     Criteria otherContentCriteria = Criteria.where(ExampleEntity.OTHER_CONTENT).is(otherContent);
114     Query query = Query.query(otherContentCriteria);
115     Update update = builder.buildUpdate(newAcl);
116     FindAndModifyOptions options = new FindAndModifyOptions()
117         .returnNew(true);
118     return Optional
119         .ofNullable(mongoTemplate.findAndModify(query, update, options, ExampleEntity.class));
120   }
121 
122   @Override
123   public Optional<ExampleEntity> changeOwnerByOtherContent(
124       String otherContent,
125       AclUserContext userContext,
126       String newOwner) {
127 
128     Criteria accessCriteria = builder.buildUpdateOwnerCriteria(userContext);
129     Criteria otherContentCriteria = Criteria.where(ExampleEntity.OTHER_CONTENT).is(otherContent);
130     Query query = Query.query(new Criteria().andOperator(accessCriteria, otherContentCriteria));
131     Update update = builder.buildUpdate(newOwner);
132     FindAndModifyOptions options = new FindAndModifyOptions()
133         .returnNew(true);
134     return Optional
135         .ofNullable(mongoTemplate.findAndModify(query, update, options, ExampleEntity.class));
136   }
137 
138 }