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(), "",
68                  GenericWindowsPrincipal.getRoles(windowsIdentity, principalFormat, roleFormat));
69          this.sid = windowsIdentity.getSid();
70          this.sidString = windowsIdentity.getSidString();
71          this.groups = GenericWindowsPrincipal.getGroups(windowsIdentity.getGroups());
72      }
73  
74      /**
75       * Gets the roles.
76       *
77       * @param windowsIdentity
78       *            the windows identity
79       * @param principalFormat
80       *            the principal format
81       * @param roleFormat
82       *            the role format
83       *
84       * @return the roles
85       */
86      private static List<String> getRoles(final IWindowsIdentity windowsIdentity, final PrincipalFormat principalFormat,
87              final PrincipalFormat roleFormat) {
88          final List<String> roles = new ArrayList<>();
89          roles.addAll(GenericWindowsPrincipal.getPrincipalNames(windowsIdentity, principalFormat));
90          for (final IWindowsAccount group : windowsIdentity.getGroups()) {
91              roles.addAll(GenericWindowsPrincipal.getRoleNames(group, roleFormat));
92          }
93          return roles;
94      }
95  
96      /**
97       * Gets the groups.
98       *
99       * @param groups
100      *            the groups
101      *
102      * @return the groups
103      */
104     private static Map<String, WindowsAccount> getGroups(final IWindowsAccount[] groups) {
105         final Map<String, WindowsAccount> groupMap = new HashMap<>();
106         for (final IWindowsAccount group : groups) {
107             groupMap.put(group.getFqn(), new WindowsAccount(group));
108         }
109         return groupMap;
110     }
111 
112     /**
113      * Byte representation of the SID.
114      *
115      * @return Array of bytes.
116      */
117     public byte[] getSid() {
118         return this.sid.clone();
119     }
120 
121     /**
122      * String representation of the SID.
123      *
124      * @return String.
125      */
126     public String getSidString() {
127         return this.sidString;
128     }
129 
130     /**
131      * Windows groups that the user is a member of.
132      *
133      * @return A map of group names to groups.
134      */
135     public Map<String, WindowsAccount> getGroups() {
136         return this.groups;
137     }
138 
139     /**
140      * Returns a list of role principal objects.
141      *
142      * @param group
143      *            Windows group.
144      * @param principalFormat
145      *            Principal format.
146      *
147      * @return List of role principal objects.
148      */
149     private static List<String> getRoleNames(final IWindowsAccount group, final PrincipalFormat principalFormat) {
150         final List<String> principals = new ArrayList<>();
151         switch (principalFormat) {
152             case FQN:
153                 principals.add(group.getFqn());
154                 break;
155             case SID:
156                 principals.add(group.getSidString());
157                 break;
158             case BOTH:
159                 principals.add(group.getFqn());
160                 principals.add(group.getSidString());
161                 break;
162             case NONE:
163             default:
164                 break;
165         }
166         return principals;
167     }
168 
169     /**
170      * Returns a list of user principal objects.
171      *
172      * @param windowsIdentity
173      *            Windows identity.
174      * @param principalFormat
175      *            Principal format.
176      *
177      * @return A list of user principal objects.
178      */
179     private static List<String> getPrincipalNames(final IWindowsIdentity windowsIdentity,
180             final PrincipalFormat principalFormat) {
181         final List<String> principals = new ArrayList<>();
182         switch (principalFormat) {
183             case FQN:
184                 principals.add(windowsIdentity.getFqn());
185                 break;
186             case SID:
187                 principals.add(windowsIdentity.getSidString());
188                 break;
189             case BOTH:
190                 principals.add(windowsIdentity.getFqn());
191                 principals.add(windowsIdentity.getSidString());
192                 break;
193             case NONE:
194             default:
195                 break;
196         }
197         return principals;
198     }
199 
200     /**
201      * Get an array of roles as a string.
202      *
203      * @return Role1, Role2, ...
204      */
205     public String getRolesString() {
206         return String.join(", ", this.getRoles());
207     }
208 
209 }