View Javadoc
1   package de.dlr.shepard.auth.apikey.services;
2   
3   import de.dlr.shepard.auth.apikey.daos.ApiKeyDAO;
4   import de.dlr.shepard.auth.apikey.entities.ApiKey;
5   import de.dlr.shepard.auth.apikey.io.ApiKeyIO;
6   import de.dlr.shepard.auth.users.entities.User;
7   import de.dlr.shepard.auth.users.services.UserService;
8   import de.dlr.shepard.common.exceptions.InvalidAuthException;
9   import de.dlr.shepard.common.exceptions.InvalidPathException;
10  import de.dlr.shepard.common.util.DateHelper;
11  import de.dlr.shepard.common.util.PkiHelper;
12  import io.jsonwebtoken.Jwts;
13  import jakarta.annotation.Nonnull;
14  import jakarta.enterprise.context.RequestScoped;
15  import jakarta.inject.Inject;
16  import java.util.List;
17  import java.util.UUID;
18  
19  @RequestScoped
20  public class ApiKeyService {
21  
22    @Inject
23    ApiKeyDAO apiKeyDAO;
24  
25    @Inject
26    UserService userService;
27  
28    @Inject
29    DateHelper dateHelper;
30  
31    @Inject
32    PkiHelper pkiHelper;
33  
34    /**
35     * Searches the neo4j database for all ApiKeys associated with a given user.
36     *
37     * @param username Identifies the associated user
38     * @return The list of ApiKeys associated with the given user
39     * @throws InvalidPathException if the user of this name does not exist
40     * @throws InvalidAuthException if the username does not match the user making the request
41     */
42    public List<ApiKey> getAllApiKeys(String username) {
43      userService.assertCurrentUserEquals(username);
44      User user = userService.getUser(username);
45      return user.getApiKeys();
46    }
47  
48    /**
49     * Searches the neo4j database for an ApiKey
50     *
51     * @param username of the user owning the api key
52     * @param apiKeyUid Identifies the ApiKey to be searched
53     * @return The ApiKey with the given uid
54     * @throws InvalidPathException if the ApiKey or the user of this name does not exist
55     * @throws InvalidAuthException if the username does not match the user making the request or the ApiKey does not belong to the user
56     */
57    public @Nonnull ApiKey getApiKey(String username, UUID apiKeyUid) {
58      userService.getUser(username);
59      userService.assertCurrentUserEquals(username);
60  
61      ApiKey requestedKey = apiKeyDAO.find(apiKeyUid);
62  
63      if (requestedKey == null) {
64        throw new InvalidPathException("ID ERROR - ApiKey does not exist");
65      }
66      if (!requestedKey.getBelongsTo().getUsername().equals(username)) {
67        throw new InvalidAuthException("You do not have permissions for this ApiKey.");
68      }
69  
70      return requestedKey;
71    }
72  
73    /**
74     * Searches the neo4j database for an ApiKey.
75     *
76     * @param apiKeyUid Identifies the ApiKey to be searched
77     * @return The ApiKey with the given uid
78     * @throws InvalidPathException ApiKey does not exist
79     */
80    public @Nonnull ApiKey getApiKey(UUID apiKeyUid) {
81      ApiKey requestedKey = apiKeyDAO.find(apiKeyUid);
82  
83      if (requestedKey == null) {
84        throw new InvalidPathException("ID ERROR - ApiKey does not exist");
85      }
86  
87      return requestedKey;
88    }
89  
90    /**
91     * Creates an ApiKey and stores it in neo4j
92     *
93     * @param apiKey   The ApiKey to be stored
94     * @param username The user who wants to create an apiKey
95     * @param baseUri  The current Uri
96     * @return The created ApiKey
97     * @throws InvalidPathException if the user of this name does not exist
98     * @throws InvalidAuthException if the username does not match the user making the request
99     */
100   public ApiKey createApiKey(ApiKeyIO apiKey, String username, String baseUri) {
101     var user = userService.getUser(username);
102     userService.assertCurrentUserEquals(username);
103 
104     var toCreate = new ApiKey();
105     toCreate.setBelongsTo(user);
106     toCreate.setCreatedAt(dateHelper.getDate());
107     toCreate.setName(apiKey.getName());
108 
109     var createdApiKey = apiKeyDAO.createOrUpdate(toCreate);
110     createdApiKey.setJws(generateJws(createdApiKey, baseUri));
111     return apiKeyDAO.createOrUpdate(createdApiKey);
112   }
113 
114   /**
115    * Deletes an ApiKey from neo4j
116    *
117    * @param apiKeyUid Identifies the ApiKey to be deleted
118    * @return A boolean to identify whether the ApiKey was successfully removed
119    * @throws InvalidPathException if the ApiKey or the user of this name does not exist
120    * @throws InvalidAuthException if the username does not match the user making the request or the ApiKey does not belong to the user
121    */
122   public boolean deleteApiKey(String username, UUID apiKeyUid) {
123     userService.assertCurrentUserEquals(username);
124     getApiKey(username, apiKeyUid);
125 
126     return apiKeyDAO.delete(apiKeyUid);
127   }
128 
129   /**
130    * Generates and sets a signed JSON Web Token for the given ApiKey object by
131    * using an RSA-Key and the following attributes: username as the JWT claim
132    * "subject", the URL of this backend software as the JWT claim "issuer", the id
133    * of the apiKey as the JWT claim "id" and the current date for the JWT claims
134    * "not before" and "issued at".
135    *
136    * @param apiKey  The apiKey for which the JSON Web Token should be generated.
137    * @param baseUri Contains the context of the request in order to set JWT claim
138    *                "issuer"
139    */
140   private String generateJws(ApiKey apiKey, String baseUri) {
141     pkiHelper.init();
142     var currentDate = dateHelper.getDate();
143     var jws = Jwts.builder()
144       .setSubject(apiKey.getBelongsTo().getUsername())
145       .setIssuer(baseUri)
146       .setNotBefore(currentDate)
147       .setIssuedAt(currentDate)
148       .setId(apiKey.getUid().toString())
149       .signWith(pkiHelper.getPrivateKey())
150       .compact();
151     return jws;
152   }
153 }