1 /*
2 * MIT License
3 *
4 * Copyright (c) 2010-2024 The Waffle Project Contributors: https://github.com/Waffle/waffle/graphs/contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24 package waffle.apache;
25
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30
31 import org.apache.catalina.realm.GenericPrincipal;
32
33 import waffle.windows.auth.IWindowsAccount;
34 import waffle.windows.auth.IWindowsIdentity;
35 import waffle.windows.auth.PrincipalFormat;
36 import waffle.windows.auth.WindowsAccount;
37
38 /**
39 * A Windows Principal.
40 */
41 public class GenericWindowsPrincipal extends GenericPrincipal {
42
43 /** The Constant serialVersionUID. */
44 private static final long serialVersionUID = 1L;
45
46 /** The sid. */
47 private final byte[] sid;
48
49 /** The sid string. */
50 private final String sidString;
51
52 /** The groups. */
53 private final Map<String, WindowsAccount> groups;
54
55 /**
56 * A windows principal.
57 *
58 * @param windowsIdentity
59 * Windows identity.
60 * @param principalFormat
61 * Principal format.
62 * @param roleFormat
63 * Role format.
64 */
65 public GenericWindowsPrincipal(final IWindowsIdentity windowsIdentity, final PrincipalFormat principalFormat,
66 final PrincipalFormat roleFormat) {
67 super(windowsIdentity.getFqn(), GenericWindowsPrincipal.getRoles(windowsIdentity, principalFormat, roleFormat));
68 this.sid = windowsIdentity.getSid();
69 this.sidString = windowsIdentity.getSidString();
70 this.groups = GenericWindowsPrincipal.getGroups(windowsIdentity.getGroups());
71 }
72
73 /**
74 * Gets the roles.
75 *
76 * @param windowsIdentity
77 * the windows identity
78 * @param principalFormat
79 * the principal format
80 * @param roleFormat
81 * the role format
82 *
83 * @return the roles
84 */
85 private static List<String> getRoles(final IWindowsIdentity windowsIdentity, final PrincipalFormat principalFormat,
86 final PrincipalFormat roleFormat) {
87 final List<String> roles = new ArrayList<>();
88 roles.addAll(GenericWindowsPrincipal.getPrincipalNames(windowsIdentity, principalFormat));
89 for (final IWindowsAccount group : windowsIdentity.getGroups()) {
90 roles.addAll(GenericWindowsPrincipal.getRoleNames(group, roleFormat));
91 }
92 return roles;
93 }
94
95 /**
96 * Gets the groups.
97 *
98 * @param groups
99 * the groups
100 *
101 * @return the groups
102 */
103 private static Map<String, WindowsAccount> getGroups(final IWindowsAccount[] groups) {
104 final Map<String, WindowsAccount> groupMap = new HashMap<>();
105 for (final IWindowsAccount group : groups) {
106 groupMap.put(group.getFqn(), new WindowsAccount(group));
107 }
108 return groupMap;
109 }
110
111 /**
112 * Byte representation of the SID.
113 *
114 * @return Array of bytes.
115 */
116 public byte[] getSid() {
117 return this.sid.clone();
118 }
119
120 /**
121 * String representation of the SID.
122 *
123 * @return String.
124 */
125 public String getSidString() {
126 return this.sidString;
127 }
128
129 /**
130 * Windows groups that the user is a member of.
131 *
132 * @return A map of group names to groups.
133 */
134 public Map<String, WindowsAccount> getGroups() {
135 return this.groups;
136 }
137
138 /**
139 * Returns a list of role principal objects.
140 *
141 * @param group
142 * Windows group.
143 * @param principalFormat
144 * Principal format.
145 *
146 * @return List of role principal objects.
147 */
148 private static List<String> getRoleNames(final IWindowsAccount group, final PrincipalFormat principalFormat) {
149 final List<String> principals = new ArrayList<>();
150 switch (principalFormat) {
151 case FQN:
152 principals.add(group.getFqn());
153 break;
154 case SID:
155 principals.add(group.getSidString());
156 break;
157 case BOTH:
158 principals.add(group.getFqn());
159 principals.add(group.getSidString());
160 break;
161 case NONE:
162 default:
163 break;
164 }
165 return principals;
166 }
167
168 /**
169 * Returns a list of user principal objects.
170 *
171 * @param windowsIdentity
172 * Windows identity.
173 * @param principalFormat
174 * Principal format.
175 *
176 * @return A list of user principal objects.
177 */
178 private static List<String> getPrincipalNames(final IWindowsIdentity windowsIdentity,
179 final PrincipalFormat principalFormat) {
180 final List<String> principals = new ArrayList<>();
181 switch (principalFormat) {
182 case FQN:
183 principals.add(windowsIdentity.getFqn());
184 break;
185 case SID:
186 principals.add(windowsIdentity.getSidString());
187 break;
188 case BOTH:
189 principals.add(windowsIdentity.getFqn());
190 principals.add(windowsIdentity.getSidString());
191 break;
192 case NONE:
193 default:
194 break;
195 }
196 return principals;
197 }
198
199 /**
200 * Get an array of roles as a string.
201 *
202 * @return Role1, Role2, ...
203 */
204 public String getRolesString() {
205 return String.join(", ", this.getRoles());
206 }
207
208 }