View Javadoc
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 }