View Javadoc
1   /*
2    * Copyright 2012-2025 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.app.web.base.login;
17  
18  import static org.codelibs.core.stream.StreamUtil.split;
19  import static org.codelibs.core.stream.StreamUtil.stream;
20  
21  import java.util.HashSet;
22  import java.util.Map;
23  import java.util.Set;
24  
25  import org.codelibs.core.lang.StringUtil;
26  import org.codelibs.fess.entity.FessUser;
27  import org.codelibs.fess.helper.SystemHelper;
28  import org.codelibs.fess.util.ComponentUtil;
29  import org.codelibs.fess.util.DocumentUtil;
30  import org.lastaflute.web.login.credential.LoginCredential;
31  
32  /**
33   * OpenID Connect credential implementation.
34   */
35  public class OpenIdConnectCredential implements LoginCredential, FessCredential {
36  
37      private final Map<String, Object> attributes;
38  
39      /**
40       * Creates a new OpenID Connect credential.
41       *
42       * @param attributes the attributes from OpenID Connect provider
43       */
44      public OpenIdConnectCredential(final Map<String, Object> attributes) {
45          this.attributes = attributes;
46      }
47  
48      @Override
49      public String toString() {
50          return "{" + getUserId() + "}";
51      }
52  
53      @Override
54      public String getUserId() {
55          return DocumentUtil.getValue(attributes, "email", String.class);
56      }
57  
58      /**
59       * Gets the user groups.
60       *
61       * @return the user groups
62       */
63      public String[] getUserGroups() {
64          String[] userGroups = DocumentUtil.getValue(attributes, "groups", String[].class);
65          if (userGroups == null) {
66              userGroups = getDefaultGroupsAsArray();
67          }
68          return userGroups;
69      }
70  
71      /**
72       * Gets the OpenID Connect user.
73       *
74       * @return the OpenID Connect user
75       */
76      public OpenIdUser getUser() {
77          return new OpenIdUser(getUserId(), getUserGroups(), getDefaultRolesAsArray());
78      }
79  
80      /**
81       * Gets the default groups as an array.
82       *
83       * @return the default groups
84       */
85      protected static String[] getDefaultGroupsAsArray() {
86          final String value = ComponentUtil.getFessConfig().getSystemProperty("oic.default.groups");
87          if (StringUtil.isBlank(value)) {
88              return StringUtil.EMPTY_STRINGS;
89          }
90          return split(value, ",").get(stream -> stream.filter(StringUtil::isNotBlank).map(String::trim).toArray(n -> new String[n]));
91      }
92  
93      /**
94       * Gets the default roles as an array.
95       *
96       * @return the default roles
97       */
98      protected static String[] getDefaultRolesAsArray() {
99          final String value = ComponentUtil.getFessConfig().getSystemProperty("oic.default.roles");
100         if (StringUtil.isBlank(value)) {
101             return StringUtil.EMPTY_STRINGS;
102         }
103         return split(value, ",").get(stream -> stream.filter(StringUtil::isNotBlank).map(String::trim).toArray(n -> new String[n]));
104     }
105 
106     /**
107      * OpenID Connect user implementation.
108      */
109     public static class OpenIdUser implements FessUser {
110 
111         private static final long serialVersionUID = 1L;
112 
113         /** The user name. */
114         protected final String name;
115 
116         /** The user groups. */
117         protected String[] groups;
118 
119         /** The user roles. */
120         protected String[] roles;
121 
122         /** The user permissions. */
123         protected String[] permissions;
124 
125         /**
126          * Creates a new OpenID Connect user.
127          *
128          * @param name the user name
129          * @param groups the user groups
130          * @param roles the user roles
131          */
132         protected OpenIdUser(final String name, final String[] groups, final String[] roles) {
133             this.name = name;
134             this.groups = groups;
135             this.roles = roles;
136         }
137 
138         @Override
139         public String getName() {
140             return name;
141         }
142 
143         @Override
144         public String[] getRoleNames() {
145             return roles;
146         }
147 
148         @Override
149         public String[] getGroupNames() {
150             return groups;
151         }
152 
153         @Override
154         public String[] getPermissions() {
155             if (permissions == null) {
156                 final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
157                 final Set<String> permissionSet = new HashSet<>();
158                 permissionSet.add(systemHelper.getSearchRoleByUser(name));
159                 stream(groups).of(stream -> stream.forEach(s -> permissionSet.add(systemHelper.getSearchRoleByGroup(s))));
160                 stream(roles).of(stream -> stream.forEach(s -> permissionSet.add(systemHelper.getSearchRoleByRole(s))));
161                 permissions = permissionSet.toArray(new String[permissionSet.size()]);
162             }
163             return permissions;
164         }
165 
166     }
167 }