View Javadoc
1   /*
2    * Copyright 2012-2021 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.ArrayList;
22  import java.util.Arrays;
23  import java.util.HashSet;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Set;
27  
28  import org.codelibs.core.lang.StringUtil;
29  import org.codelibs.fess.entity.FessUser;
30  import org.codelibs.fess.helper.SystemHelper;
31  import org.codelibs.fess.mylasta.direction.FessConfig;
32  import org.codelibs.fess.util.ComponentUtil;
33  import org.lastaflute.web.login.credential.LoginCredential;
34  
35  import com.onelogin.saml2.Auth;
36  
37  public class SamlCredential implements LoginCredential, FessCredential {
38  
39      private final Map<String, List<String>> attributes;
40  
41      private final String nameId;
42  
43      private final String nameIdFormat;
44  
45      private final String sessionIndex;
46  
47      private final String nameidNameQualifier;
48  
49      private final String nameidSPNameQualifier;
50  
51      public SamlCredential(final Auth auth) {
52          attributes = auth.getAttributes();
53          nameId = auth.getNameId();
54          nameIdFormat = auth.getNameIdFormat();
55          sessionIndex = auth.getSessionIndex();
56          nameidNameQualifier = auth.getNameIdNameQualifier();
57          nameidSPNameQualifier = auth.getNameIdSPNameQualifier();
58      }
59  
60      @Override
61      public String toString() {
62          return "{" + getUserId() + "}";
63      }
64  
65      @Override
66      public String getUserId() {
67          return nameId;
68      }
69  
70      public SamlUser getUser() {
71          return new SamlUser(nameId, sessionIndex, nameIdFormat, nameidNameQualifier, nameidSPNameQualifier, getDefaultGroupsAsArray(),
72                  getDefaultRolesAsArray());
73      }
74  
75      protected String[] getDefaultGroupsAsArray() {
76          final List<String> list = new ArrayList<>();
77          final FessConfig fessConfig = ComponentUtil.getFessConfig();
78          final String key = fessConfig.getSystemProperty("saml.attribute.group.name", "memberOf");
79          if (StringUtil.isNotBlank(key)) {
80              final List<String> nameList = attributes.get(key);
81              if (nameList != null) {
82                  list.addAll(nameList);
83              }
84          }
85          final String value = fessConfig.getSystemProperty("saml.default.groups");
86          if (StringUtil.isNotBlank(value)) {
87              split(value, ",").of(stream -> stream.forEach(list::add));
88          }
89          return list.stream().filter(StringUtil::isNotBlank).map(String::trim).toArray(n -> new String[n]);
90      }
91  
92      protected String[] getDefaultRolesAsArray() {
93          final List<String> list = new ArrayList<>();
94          final FessConfig fessConfig = ComponentUtil.getFessConfig();
95          final String key = fessConfig.getSystemProperty("saml.attribute.role.name");
96          if (StringUtil.isNotBlank(key)) {
97              final List<String> nameList = attributes.get(key);
98              if (nameList != null) {
99                  list.addAll(nameList);
100             }
101         }
102         final String value = fessConfig.getSystemProperty("saml.default.roles");
103         if (StringUtil.isNotBlank(value)) {
104             split(value, ",").of(stream -> stream.forEach(list::add));
105         }
106         return list.stream().filter(StringUtil::isNotBlank).map(String::trim).toArray(n -> new String[n]);
107     }
108 
109     public static class SamlUser implements FessUser {
110 
111         private static final long serialVersionUID = 1L;
112 
113         protected String[] groups;
114 
115         protected String[] roles;
116 
117         protected String[] permissions;
118 
119         protected String nameId;
120 
121         protected String sessionIndex;
122 
123         protected String nameIdFormat;
124 
125         protected String nameidNameQualifier;
126 
127         protected String nameidSPNameQualifier;
128 
129         public SamlUser(final String nameId, final String sessionIndex, final String nameIdFormat, final String nameidNameQualifier,
130                 final String nameidSPNameQualifier, final String[] groups, final String[] roles) {
131             this.nameId = nameId;
132             this.sessionIndex = sessionIndex;
133             this.nameIdFormat = nameIdFormat;
134             this.nameidNameQualifier = nameidNameQualifier;
135             this.nameidSPNameQualifier = nameidSPNameQualifier;
136             this.groups = groups;
137             this.roles = roles;
138         }
139 
140         @Override
141         public String getName() {
142             return nameId;
143         }
144 
145         @Override
146         public String[] getRoleNames() {
147             return roles;
148         }
149 
150         @Override
151         public String[] getGroupNames() {
152             return groups;
153         }
154 
155         @Override
156         public String[] getPermissions() {
157             if (permissions == null) {
158                 final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
159                 final Set<String> permissionSet = new HashSet<>();
160                 permissionSet.add(systemHelper.getSearchRoleByUser(nameId));
161                 stream(groups).of(stream -> stream.forEach(s -> permissionSet.add(systemHelper.getSearchRoleByGroup(s))));
162                 stream(roles).of(stream -> stream.forEach(s -> permissionSet.add(systemHelper.getSearchRoleByRole(s))));
163                 permissions = permissionSet.toArray(new String[permissionSet.size()]);
164             }
165             return permissions;
166         }
167 
168         public String getSessionIndex() {
169             return sessionIndex;
170         }
171 
172         public String getNameIdFormat() {
173             return nameIdFormat;
174         }
175 
176         public String getNameidNameQualifier() {
177             return nameidNameQualifier;
178         }
179 
180         public String getNameidSPNameQualifier() {
181             return nameidSPNameQualifier;
182         }
183 
184         @Override
185         public String toString() {
186             return "SamlUser [groups=" + Arrays.toString(groups) + ", roles=" + Arrays.toString(roles) + ", permissions="
187                     + Arrays.toString(permissions) + ", nameId=" + nameId + ", sessionIndex=" + sessionIndex + ", nameIdFormat="
188                     + nameIdFormat + ", nameidNameQualifier=" + nameidNameQualifier + ", nameidSPNameQualifier=" + nameidSPNameQualifier
189                     + "]";
190         }
191 
192     }
193 }