1b28a5538SAdam Hornacek /* 2b28a5538SAdam Hornacek * CDDL HEADER START 3b28a5538SAdam Hornacek * 4b28a5538SAdam Hornacek * The contents of this file are subject to the terms of the 5b28a5538SAdam Hornacek * Common Development and Distribution License (the "License"). 6b28a5538SAdam Hornacek * You may not use this file except in compliance with the License. 7b28a5538SAdam Hornacek * 8b28a5538SAdam Hornacek * See LICENSE.txt included in this distribution for the specific 9b28a5538SAdam Hornacek * language governing permissions and limitations under the License. 10b28a5538SAdam Hornacek * 11b28a5538SAdam Hornacek * When distributing Covered Code, include this CDDL HEADER in each 12b28a5538SAdam Hornacek * file and include the License file at LICENSE.txt. 13b28a5538SAdam Hornacek * If applicable, add the following below this CDDL HEADER, with the 14b28a5538SAdam Hornacek * fields enclosed by brackets "[]" replaced with your own identifying 15b28a5538SAdam Hornacek * information: Portions Copyright [yyyy] [name of copyright owner] 16b28a5538SAdam Hornacek * 17b28a5538SAdam Hornacek * CDDL HEADER END 18b28a5538SAdam Hornacek */ 19b28a5538SAdam Hornacek 20b28a5538SAdam Hornacek /* 21*9d74bf96SVladimir Kotal * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. 22b28a5538SAdam Hornacek */ 23b28a5538SAdam Hornacek package opengrok.auth.plugin; 24b28a5538SAdam Hornacek 25b28a5538SAdam Hornacek import java.lang.reflect.Constructor; 26b28a5538SAdam Hornacek import java.lang.reflect.InvocationTargetException; 27b28a5538SAdam Hornacek import java.util.Map; 28b28a5538SAdam Hornacek import java.util.logging.Level; 29b28a5538SAdam Hornacek import java.util.logging.Logger; 30aa6abf42SAdam Hornacek 31aa6abf42SAdam Hornacek import jakarta.servlet.http.HttpServletRequest; 32b28a5538SAdam Hornacek import opengrok.auth.plugin.decoders.IUserDecoder; 33b28a5538SAdam Hornacek import opengrok.auth.plugin.entity.User; 34b28a5538SAdam Hornacek import org.opengrok.indexer.authorization.IAuthorizationPlugin; 35b28a5538SAdam Hornacek import org.opengrok.indexer.configuration.Group; 36b28a5538SAdam Hornacek import org.opengrok.indexer.configuration.Project; 37b28a5538SAdam Hornacek 38b28a5538SAdam Hornacek /** 39b28a5538SAdam Hornacek * Authorization plug-in to extract user info from HTTP headers. 40b28a5538SAdam Hornacek * 41b28a5538SAdam Hornacek * @author Krystof Tulinger 42b28a5538SAdam Hornacek */ 43b28a5538SAdam Hornacek public class UserPlugin implements IAuthorizationPlugin { 44b28a5538SAdam Hornacek 45b28a5538SAdam Hornacek private static final Logger LOGGER = Logger.getLogger(UserPlugin.class.getName()); 46b28a5538SAdam Hornacek 47b28a5538SAdam Hornacek private static final String DECODER_CLASS_PARAM = "decoder"; 48b28a5538SAdam Hornacek 49b28a5538SAdam Hornacek public static final String REQUEST_ATTR = "opengrok-user-plugin-user"; 50b28a5538SAdam Hornacek 51b28a5538SAdam Hornacek private IUserDecoder decoder; 52b28a5538SAdam Hornacek UserPlugin()53b28a5538SAdam Hornacek public UserPlugin() { 54b28a5538SAdam Hornacek } 55b28a5538SAdam Hornacek 56b28a5538SAdam Hornacek // for testing UserPlugin(IUserDecoder decoder)57b28a5538SAdam Hornacek protected UserPlugin(IUserDecoder decoder) { 58b28a5538SAdam Hornacek this.decoder = decoder; 59b28a5538SAdam Hornacek } 60b28a5538SAdam Hornacek getDecoder(String name)61b28a5538SAdam Hornacek private IUserDecoder getDecoder(String name) throws ClassNotFoundException, NoSuchMethodException, 62b28a5538SAdam Hornacek IllegalAccessException, InvocationTargetException, InstantiationException { 63b28a5538SAdam Hornacek Class<?> clazz = Class.forName(name); 64b28a5538SAdam Hornacek Constructor<?> constructor = clazz.getConstructor(); 65b28a5538SAdam Hornacek Object instance = constructor.newInstance(); 66b28a5538SAdam Hornacek return (IUserDecoder) instance; 67b28a5538SAdam Hornacek } 68b28a5538SAdam Hornacek 69b28a5538SAdam Hornacek @Override load(Map<String, Object> parameters)70b28a5538SAdam Hornacek public void load(Map<String, Object> parameters) { 71*9d74bf96SVladimir Kotal String decoderName; 72*9d74bf96SVladimir Kotal if ((decoderName = (String) parameters.get(DECODER_CLASS_PARAM)) == null) { 73b28a5538SAdam Hornacek throw new NullPointerException(String.format("missing " + 74b28a5538SAdam Hornacek "parameter '%s' in %s configuration", 75b28a5538SAdam Hornacek DECODER_CLASS_PARAM, UserPlugin.class.getName())); 76b28a5538SAdam Hornacek } 77b28a5538SAdam Hornacek 78*9d74bf96SVladimir Kotal LOGGER.log(Level.INFO, "loading decoder: {0}", decoderName); 79b28a5538SAdam Hornacek try { 80*9d74bf96SVladimir Kotal decoder = getDecoder(decoderName); 81b28a5538SAdam Hornacek } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | 82b28a5538SAdam Hornacek InvocationTargetException | InstantiationException e) { 83*9d74bf96SVladimir Kotal throw new RuntimeException("cannot load decoder " + decoderName, e); 84b28a5538SAdam Hornacek } 85b28a5538SAdam Hornacek } 86b28a5538SAdam Hornacek 87b28a5538SAdam Hornacek @Override unload()88b28a5538SAdam Hornacek public void unload() { 89*9d74bf96SVladimir Kotal // no state to free 90b28a5538SAdam Hornacek } 91b28a5538SAdam Hornacek getUser(HttpServletRequest request)92b28a5538SAdam Hornacek private User getUser(HttpServletRequest request) { 93b28a5538SAdam Hornacek User user; 94b28a5538SAdam Hornacek 95b28a5538SAdam Hornacek if ((user = (User) request.getAttribute(REQUEST_ATTR)) == null) { 96b28a5538SAdam Hornacek user = decoder.fromRequest(request); 97b28a5538SAdam Hornacek request.setAttribute(REQUEST_ATTR, user); 98b28a5538SAdam Hornacek } 99b28a5538SAdam Hornacek 100b28a5538SAdam Hornacek return user; 101b28a5538SAdam Hornacek } 102b28a5538SAdam Hornacek 103b28a5538SAdam Hornacek @Override isAllowed(HttpServletRequest request, Project project)104b28a5538SAdam Hornacek public boolean isAllowed(HttpServletRequest request, Project project) { 105b28a5538SAdam Hornacek return getUser(request) != null; 106b28a5538SAdam Hornacek } 107b28a5538SAdam Hornacek 108b28a5538SAdam Hornacek @Override isAllowed(HttpServletRequest request, Group group)109b28a5538SAdam Hornacek public boolean isAllowed(HttpServletRequest request, Group group) { 110b28a5538SAdam Hornacek return getUser(request) != null; 111b28a5538SAdam Hornacek } 112b28a5538SAdam Hornacek } 113