View Javadoc
1   /**
2    * Waffle (https://github.com/dblock/waffle)
3    *
4    * Copyright (c) 2010 - 2015 Application Security, Inc.
5    *
6    * All rights reserved. This program and the accompanying materials
7    * are made available under the terms of the Eclipse Public License v1.0
8    * which accompanies this distribution, and is available at
9    * http://www.eclipse.org/legal/epl-v10.html
10   *
11   * Contributors:
12   *     Application Security, Inc.
13   */
14  package waffle.apache;
15  
16  import java.util.ArrayList;
17  import java.util.HashMap;
18  import java.util.List;
19  import java.util.Map;
20  
21  import org.apache.catalina.Realm;
22  import org.apache.catalina.realm.GenericPrincipal;
23  
24  import com.google.common.base.Joiner;
25  
26  import waffle.windows.auth.IWindowsAccount;
27  import waffle.windows.auth.IWindowsIdentity;
28  import waffle.windows.auth.PrincipalFormat;
29  import waffle.windows.auth.WindowsAccount;
30  
31  /**
32   * A Windows Principal.
33   * 
34   * @author dblock[at]dblock[dot]org
35   */
36  public class GenericWindowsPrincipal extends GenericPrincipal {
37  
38      /** The sid. */
39      private final byte[]                      sid;
40      
41      /** The sid string. */
42      private final String                      sidString;
43      
44      /** The groups. */
45      private final Map<String, WindowsAccount> groups;
46  
47      /**
48       * A windows principal.
49       * 
50       * @param newWindowsIdentity
51       *            Windows identity.
52       * @param newRealm
53       *            Authentication realm.
54       * @param newPrincipalFormat
55       *            Principal format.
56       * @param newRoleFormat
57       *            Role format.
58       */
59      public GenericWindowsPrincipal(final IWindowsIdentity newWindowsIdentity, final Realm newRealm,
60              final PrincipalFormat newPrincipalFormat, final PrincipalFormat newRoleFormat) {
61          super(newRealm, newWindowsIdentity.getFqn(), "",
62                  GenericWindowsPrincipal.getRoles(newWindowsIdentity, newPrincipalFormat, newRoleFormat));
63          this.sid = newWindowsIdentity.getSid();
64          this.sidString = newWindowsIdentity.getSidString();
65          this.groups = GenericWindowsPrincipal.getGroups(newWindowsIdentity.getGroups());
66      }
67  
68      /**
69       * Gets the roles.
70       *
71       * @param windowsIdentity
72       *            the windows identity
73       * @param principalFormat
74       *            the principal format
75       * @param roleFormat
76       *            the role format
77       * @return the roles
78       */
79      private static List<String> getRoles(final IWindowsIdentity windowsIdentity, final PrincipalFormat principalFormat,
80              final PrincipalFormat roleFormat) {
81          final List<String> roles = new ArrayList<String>();
82          roles.addAll(GenericWindowsPrincipal.getPrincipalNames(windowsIdentity, principalFormat));
83          for (final IWindowsAccount group : windowsIdentity.getGroups()) {
84              roles.addAll(GenericWindowsPrincipal.getRoleNames(group, roleFormat));
85          }
86          return roles;
87      }
88  
89      /**
90       * Gets the groups.
91       *
92       * @param groups
93       *            the groups
94       * @return the groups
95       */
96      private static Map<String, WindowsAccount> getGroups(final IWindowsAccount[] groups) {
97          final Map<String, WindowsAccount> groupMap = new HashMap<String, WindowsAccount>();
98          for (final IWindowsAccount group : groups) {
99              groupMap.put(group.getFqn(), new WindowsAccount(group));
100         }
101         return groupMap;
102     }
103 
104     /**
105      * Byte representation of the SID.
106      * 
107      * @return Array of bytes.
108      */
109     public byte[] getSid() {
110         return this.sid.clone();
111     }
112 
113     /**
114      * String representation of the SID.
115      * 
116      * @return String.
117      */
118     public String getSidString() {
119         return this.sidString;
120     }
121 
122     /**
123      * Windows groups that the user is a member of.
124      * 
125      * @return A map of group names to groups.
126      */
127     public Map<String, WindowsAccount> getGroups() {
128         return this.groups;
129     }
130 
131     /**
132      * Returns a list of role principal objects.
133      * 
134      * @param group
135      *            Windows group.
136      * @param principalFormat
137      *            Principal format.
138      * @return List of role principal objects.
139      */
140     private static List<String> getRoleNames(final IWindowsAccount group, final PrincipalFormat principalFormat) {
141         final List<String> principals = new ArrayList<String>();
142         switch (principalFormat) {
143             case FQN:
144                 principals.add(group.getFqn());
145                 break;
146             case SID:
147                 principals.add(group.getSidString());
148                 break;
149             case BOTH:
150                 principals.add(group.getFqn());
151                 principals.add(group.getSidString());
152                 break;
153             case NONE:
154                 break;
155             default:
156                 break;
157         }
158         return principals;
159     }
160 
161     /**
162      * Returns a list of user principal objects.
163      * 
164      * @param windowsIdentity
165      *            Windows identity.
166      * @param principalFormat
167      *            Principal format.
168      * @return A list of user principal objects.
169      */
170     private static List<String> getPrincipalNames(final IWindowsIdentity windowsIdentity,
171             final PrincipalFormat principalFormat) {
172         final List<String> principals = new ArrayList<String>();
173         switch (principalFormat) {
174             case FQN:
175                 principals.add(windowsIdentity.getFqn());
176                 break;
177             case SID:
178                 principals.add(windowsIdentity.getSidString());
179                 break;
180             case BOTH:
181                 principals.add(windowsIdentity.getFqn());
182                 principals.add(windowsIdentity.getSidString());
183                 break;
184             case NONE:
185                 break;
186             default:
187                 break;
188         }
189         return principals;
190     }
191 
192     /**
193      * Get an array of roles as a string.
194      * 
195      * @return Role1, Role2, ...
196      */
197     public String getRolesString() {
198         return Joiner.on(", ").join(this.getRoles());
199     }
200 }