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) 2017, 2021, Oracle and/or its affiliates. All rights reserved. 22 */ 23 package opengrok.auth.plugin; 24 25 import java.lang.reflect.Constructor; 26 import java.lang.reflect.InvocationTargetException; 27 import java.util.Map; 28 import java.util.logging.Level; 29 import java.util.logging.Logger; 30 31 import jakarta.servlet.http.HttpServletRequest; 32 import opengrok.auth.plugin.decoders.IUserDecoder; 33 import opengrok.auth.plugin.entity.User; 34 import org.opengrok.indexer.authorization.IAuthorizationPlugin; 35 import org.opengrok.indexer.configuration.Group; 36 import org.opengrok.indexer.configuration.Project; 37 38 /** 39 * Authorization plug-in to extract user info from HTTP headers. 40 * 41 * @author Krystof Tulinger 42 */ 43 public class UserPlugin implements IAuthorizationPlugin { 44 45 private static final Logger LOGGER = Logger.getLogger(UserPlugin.class.getName()); 46 47 private static final String DECODER_CLASS_PARAM = "decoder"; 48 49 public static final String REQUEST_ATTR = "opengrok-user-plugin-user"; 50 51 private IUserDecoder decoder; 52 UserPlugin()53 public UserPlugin() { 54 } 55 56 // for testing UserPlugin(IUserDecoder decoder)57 protected UserPlugin(IUserDecoder decoder) { 58 this.decoder = decoder; 59 } 60 getDecoder(String name)61 private IUserDecoder getDecoder(String name) throws ClassNotFoundException, NoSuchMethodException, 62 IllegalAccessException, InvocationTargetException, InstantiationException { 63 Class<?> clazz = Class.forName(name); 64 Constructor<?> constructor = clazz.getConstructor(); 65 Object instance = constructor.newInstance(); 66 return (IUserDecoder) instance; 67 } 68 69 @Override load(Map<String, Object> parameters)70 public void load(Map<String, Object> parameters) { 71 String decoderName; 72 if ((decoderName = (String) parameters.get(DECODER_CLASS_PARAM)) == null) { 73 throw new NullPointerException(String.format("missing " + 74 "parameter '%s' in %s configuration", 75 DECODER_CLASS_PARAM, UserPlugin.class.getName())); 76 } 77 78 LOGGER.log(Level.INFO, "loading decoder: {0}", decoderName); 79 try { 80 decoder = getDecoder(decoderName); 81 } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | 82 InvocationTargetException | InstantiationException e) { 83 throw new RuntimeException("cannot load decoder " + decoderName, e); 84 } 85 } 86 87 @Override unload()88 public void unload() { 89 // no state to free 90 } 91 getUser(HttpServletRequest request)92 private User getUser(HttpServletRequest request) { 93 User user; 94 95 if ((user = (User) request.getAttribute(REQUEST_ATTR)) == null) { 96 user = decoder.fromRequest(request); 97 request.setAttribute(REQUEST_ATTR, user); 98 } 99 100 return user; 101 } 102 103 @Override isAllowed(HttpServletRequest request, Project project)104 public boolean isAllowed(HttpServletRequest request, Project project) { 105 return getUser(request) != null; 106 } 107 108 @Override isAllowed(HttpServletRequest request, Group group)109 public boolean isAllowed(HttpServletRequest request, Group group) { 110 return getUser(request) != null; 111 } 112 } 113