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