xref: /OpenGrok/plugins/src/main/java/opengrok/auth/plugin/UserWhiteListPlugin.java (revision 4ceb1b98c17b7b580c0718bb27573b95081b34a5)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * See LICENSE.txt included in this distribution for the specific
9  * language governing permissions and limitations under the License.
10  *
11  * When distributing Covered Code, include this CDDL HEADER in each
12  * file and include the License file at LICENSE.txt.
13  * If applicable, add the following below this CDDL HEADER, with the
14  * fields enclosed by brackets "[]" replaced with your own identifying
15  * information: Portions Copyright [yyyy] [name of copyright owner]
16  *
17  * CDDL HEADER END
18  */
19 
20 /*
21  * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
22  * Portions Copyright (c) 2020, Chris Fraire <cfraire@me.com>.
23  */
24 package opengrok.auth.plugin;
25 
26 import jakarta.servlet.http.HttpServletRequest;
27 import opengrok.auth.plugin.entity.User;
28 import org.jetbrains.annotations.TestOnly;
29 import org.opengrok.indexer.authorization.IAuthorizationPlugin;
30 import org.opengrok.indexer.configuration.Group;
31 import org.opengrok.indexer.configuration.Project;
32 
33 import java.io.IOException;
34 import java.nio.file.Files;
35 import java.nio.file.Paths;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.TreeSet;
39 import java.util.logging.Level;
40 import java.util.logging.Logger;
41 import java.util.stream.Stream;
42 
43 public class UserWhiteListPlugin implements IAuthorizationPlugin {
44     private static final String CLASS_NAME = UserWhiteListPlugin.class.getName();
45     private static final Logger LOGGER = Logger.getLogger(CLASS_NAME);
46 
47     // configuration parameters
48     static final String FILE_PARAM = "file";
49     static final String FIELD_PARAM = "fieldName";
50 
51     // valid values for the FIELD_NAME parameter
52     static final String USERNAME_FIELD = "username";
53     static final String ID_FIELD = "id";
54 
55     private final Set<String> whitelist = new TreeSet<>();
56     private String fieldName;
57 
58     @Override
load(Map<String, Object> parameters)59     public void load(Map<String, Object> parameters) {
60         if (parameters == null) {
61             throw new IllegalArgumentException("Null parameter");
62         }
63 
64         String filePath;
65         if ((filePath = (String) parameters.get(FILE_PARAM)) == null) {
66             throw new IllegalArgumentException("Missing parameter [" + FILE_PARAM + "] in the configuration");
67         }
68 
69         if ((fieldName = (String) parameters.get(FIELD_PARAM)) == null) {
70             fieldName = USERNAME_FIELD;
71         } else if (!fieldName.equals(USERNAME_FIELD) && !fieldName.equals(ID_FIELD)) {
72             throw new IllegalArgumentException("Invalid value of parameter [" + FIELD_PARAM +
73                     "] in the configuration: only " + USERNAME_FIELD + " or " + ID_FIELD + " are supported");
74         }
75 
76         // Load whitelist from file to memory.
77         try (Stream<String> stream = Files.lines(Paths.get(filePath))) {
78             stream.map(String::strip).forEach(whitelist::add);
79         } catch (IOException e) {
80             throw new IllegalArgumentException(String.format("Unable to read the file \"%s\"", filePath), e);
81         }
82 
83         LOGGER.log(Level.FINE, "UserWhiteList plugin loaded with filePath={0} ({1} entries), fieldName={2}",
84                 new Object[]{filePath, whitelist.size(), fieldName});
85     }
86 
87     @TestOnly
getWhitelist()88     Set<String> getWhitelist() {
89         return whitelist;
90     }
91 
92     @Override
unload()93     public void unload() {
94         whitelist.clear();
95     }
96 
checkWhitelist(HttpServletRequest request)97     private boolean checkWhitelist(HttpServletRequest request) {
98         User user;
99         String attrName = UserPlugin.REQUEST_ATTR;
100         if ((user = (User) request.getAttribute(attrName)) == null) {
101             LOGGER.log(Level.WARNING, "cannot get {0} attribute", attrName);
102             return false;
103         }
104 
105         if (fieldName.equals(USERNAME_FIELD)) {
106             return user.getUsername() != null && whitelist.contains(user.getUsername());
107         } else if (fieldName.equals(ID_FIELD)) {
108             return user.getId() != null && whitelist.contains(user.getId());
109         }
110 
111         return false;
112     }
113 
114     @Override
isAllowed(HttpServletRequest request, Project project)115     public boolean isAllowed(HttpServletRequest request, Project project) {
116         return checkWhitelist(request);
117     }
118 
119     @Override
isAllowed(HttpServletRequest request, Group group)120     public boolean isAllowed(HttpServletRequest request, Group group) {
121         return checkWhitelist(request);
122     }
123 }
124