xref: /OpenGrok/plugins/src/main/java/opengrok/auth/plugin/UserPlugin.java (revision 9d74bf96c386aa7bedff220480c7da5f7bfead79)
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