xref: /OpenGrok/plugins/src/main/java/opengrok/auth/plugin/decoders/OSSOHeaderDecoder.java (revision 0e4c55544f8ea0a68e8bae37b0e502097e008ec1)
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 /*
21b28a5538SAdam Hornacek  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
2220463cfeSChris Fraire  * Portions Copyright (c) 2020, Chris Fraire <cfraire@me.com>.
23b28a5538SAdam Hornacek  */
24b28a5538SAdam Hornacek package opengrok.auth.plugin.decoders;
25b28a5538SAdam Hornacek 
26b28a5538SAdam Hornacek import java.util.Collections;
27b28a5538SAdam Hornacek import java.util.Date;
28b28a5538SAdam Hornacek import java.util.logging.Level;
29b28a5538SAdam Hornacek import java.util.logging.Logger;
30*aa6abf42SAdam Hornacek 
31*aa6abf42SAdam Hornacek import jakarta.servlet.http.HttpServletRequest;
32b28a5538SAdam Hornacek import opengrok.auth.plugin.entity.User;
33b28a5538SAdam Hornacek import opengrok.auth.plugin.util.Timestamp;
34d26fc5a1SChris Fraire import org.opengrok.indexer.web.Laundromat;
35b28a5538SAdam Hornacek 
36b28a5538SAdam Hornacek /**
37b28a5538SAdam Hornacek  * Decode Oracle SSO specific headers.
38b28a5538SAdam Hornacek  *
39b28a5538SAdam Hornacek  * @author Krystof Tulinger
40b28a5538SAdam Hornacek  */
41b28a5538SAdam Hornacek public class OSSOHeaderDecoder implements IUserDecoder {
42b28a5538SAdam Hornacek 
43b28a5538SAdam Hornacek     private static final Logger LOGGER = Logger.getLogger(OSSOHeaderDecoder.class.getName());
44b28a5538SAdam Hornacek 
45b28a5538SAdam Hornacek     protected static String OSSO_COOKIE_TIMESTAMP_HEADER = "osso-cookie-timestamp";
46b28a5538SAdam Hornacek     protected static String OSSO_TIMEOUT_EXCEEDED_HEADER = "osso-idle-timeout-exceeded";
47b28a5538SAdam Hornacek     protected static String OSSO_SUBSCRIBER_DN_HEADER = "osso-subscriber-dn";
48b28a5538SAdam Hornacek     protected static String OSSO_SUBSCRIBER_HEADER = "osso-subscriber";
49b28a5538SAdam Hornacek     protected static String OSSO_USER_DN_HEADER = "osso-user-dn";
50b28a5538SAdam Hornacek     protected static String OSSO_USER_GUID_HEADER = "osso-user-guid";
51b28a5538SAdam Hornacek 
52b28a5538SAdam Hornacek     @Override
fromRequest(HttpServletRequest request)53b28a5538SAdam Hornacek     public User fromRequest(HttpServletRequest request) {
54b28a5538SAdam Hornacek         String username, userguid, timeouted, timestamp;
55b28a5538SAdam Hornacek         Date cookieTimestamp = null;
56b28a5538SAdam Hornacek 
5720463cfeSChris Fraire         // Avoid classification as a taint bug.
58d26fc5a1SChris Fraire         username = Laundromat.launderInput(request.getHeader(OSSO_USER_DN_HEADER));
59d26fc5a1SChris Fraire         timeouted = Laundromat.launderInput(request.getHeader(OSSO_TIMEOUT_EXCEEDED_HEADER));
60d26fc5a1SChris Fraire         timestamp = Laundromat.launderInput(request.getHeader(OSSO_COOKIE_TIMESTAMP_HEADER));
61d26fc5a1SChris Fraire         userguid = Laundromat.launderInput(request.getHeader(OSSO_USER_GUID_HEADER));
62b28a5538SAdam Hornacek 
63b28a5538SAdam Hornacek         if (username == null || username.isEmpty()) {
64b28a5538SAdam Hornacek             LOGGER.log(Level.WARNING,
65b28a5538SAdam Hornacek                     "Can not construct an user: username could not be extracted from headers: {0}",
66b28a5538SAdam Hornacek                     String.join(",", Collections.list(request.getHeaderNames())));
67b28a5538SAdam Hornacek             return null;
68b28a5538SAdam Hornacek         }
69b28a5538SAdam Hornacek 
70b28a5538SAdam Hornacek         if (userguid == null || userguid.isEmpty()) {
71b28a5538SAdam Hornacek             LOGGER.log(Level.WARNING,
72b28a5538SAdam Hornacek                     "Can not construct an user: userguid could not be extracted from headers: {0}",
73b28a5538SAdam Hornacek                     String.join(",", Collections.list(request.getHeaderNames())));
74b28a5538SAdam Hornacek             return null;
75b28a5538SAdam Hornacek         }
76b28a5538SAdam Hornacek 
77b28a5538SAdam Hornacek         /**
78b28a5538SAdam Hornacek          * The timestamp cookie can be corrupted.
79b28a5538SAdam Hornacek          */
80b28a5538SAdam Hornacek         try {
81b28a5538SAdam Hornacek             cookieTimestamp = Timestamp.decodeTimeCookie(timestamp);
82b28a5538SAdam Hornacek         } catch (NumberFormatException ex) {
83b28a5538SAdam Hornacek             LOGGER.log(Level.WARNING,
84b28a5538SAdam Hornacek                     String.format("Unparseable timestamp cookie \"%s\" for user \"%s\"",
85b28a5538SAdam Hornacek                             timestamp, username), ex);
86b28a5538SAdam Hornacek         }
87b28a5538SAdam Hornacek 
88b28a5538SAdam Hornacek         /**
89b28a5538SAdam Hornacek          * Creating new user entity with provided information. The entity can be
90b28a5538SAdam Hornacek          * checked if the timeout expired via {@link User#isTimeouted()}.
91b28a5538SAdam Hornacek          */
92b28a5538SAdam Hornacek         User user = new User(username, userguid, cookieTimestamp,
93b28a5538SAdam Hornacek                 "true".equalsIgnoreCase(timeouted));
94b28a5538SAdam Hornacek 
95b28a5538SAdam Hornacek         user.setAttribute("subscriber-dn", request.getHeader(OSSO_SUBSCRIBER_DN_HEADER));
96b28a5538SAdam Hornacek         user.setAttribute("subscriber", request.getHeader(OSSO_SUBSCRIBER_HEADER));
97b28a5538SAdam Hornacek 
98b28a5538SAdam Hornacek         if (user.isTimeouted()) {
99b28a5538SAdam Hornacek             LOGGER.log(Level.WARNING, "Can not construct an user \"{0}\": header is timeouted",
100b28a5538SAdam Hornacek                     username);
101b28a5538SAdam Hornacek             return null;
102b28a5538SAdam Hornacek         }
103b28a5538SAdam Hornacek 
104b28a5538SAdam Hornacek         return user;
105b28a5538SAdam Hornacek     }
106b28a5538SAdam Hornacek }
107