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