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.GenericPrincipal;
22  
23  import com.google.common.base.Joiner;
24  
25  import waffle.windows.auth.IWindowsAccount;
26  import waffle.windows.auth.IWindowsIdentity;
27  import waffle.windows.auth.PrincipalFormat;
28  import waffle.windows.auth.WindowsAccount;
29  
30  /**
31   * A Windows Principal.
32   * 
33   * @author dblock[at]dblock[dot]org
34   */
35  public class GenericWindowsPrincipal extends GenericPrincipal {
36  
37      /** The sid. */
38      private final byte[]                      sid;
39      
40      /** The sid string. */
41      private final String                      sidString;
42      
43      /** The groups. */
44      private final Map<String, WindowsAccount> groups;
45  
46      /**
47       * A windows principal.
48       * 
49       * @param windowsIdentity
50       *            Windows identity.
51       * @param principalFormat
52       *            Principal format.
53       * @param roleFormat
54       *            Role format.
55       */
56      public GenericWindowsPrincipal(final IWindowsIdentity windowsIdentity, final PrincipalFormat principalFormat,
57              final PrincipalFormat roleFormat) {
58          super(windowsIdentity.getFqn(), "", GenericWindowsPrincipal.getRoles(windowsIdentity, principalFormat, roleFormat));
59          this.sid = windowsIdentity.getSid();
60          this.sidString = windowsIdentity.getSidString();
61          this.groups = GenericWindowsPrincipal.getGroups(windowsIdentity.getGroups());
62      }
63  
64      /**
65       * Gets the roles.
66       *
67       * @param windowsIdentity
68       *            the windows identity
69       * @param principalFormat
70       *            the principal format
71       * @param roleFormat
72       *            the role format
73       * @return the roles
74       */
75      private static List<String> getRoles(final IWindowsIdentity windowsIdentity, final PrincipalFormat principalFormat,
76              final PrincipalFormat roleFormat) {
77          final List<String> roles = new ArrayList<String>();
78          roles.addAll(GenericWindowsPrincipal.getPrincipalNames(windowsIdentity, principalFormat));
79          for (final IWindowsAccount group : windowsIdentity.getGroups()) {
80              roles.addAll(GenericWindowsPrincipal.getRoleNames(group, roleFormat));
81          }
82          return roles;
83      }
84  
85      /**
86       * Gets the groups.
87       *
88       * @param groups
89       *            the groups
90       * @return the groups
91       */
92      private static Map<String, WindowsAccount> getGroups(final IWindowsAccount[] groups) {
93          final Map<String, WindowsAccount> groupMap = new HashMap<String, WindowsAccount>();
94          for (final IWindowsAccount group : groups) {
95              groupMap.put(group.getFqn(), new WindowsAccount(group));
96          }
97          return groupMap;
98      }
99  
100     /**
101      * Byte representation of the SID.
102      * 
103      * @return Array of bytes.
104      */
105     public byte[] getSid() {
106         return this.sid.clone();
107     }
108 
109     /**
110      * String representation of the SID.
111      * 
112      * @return String.
113      */
114     public String getSidString() {
115         return this.sidString;
116     }
117 
118     /**
119      * Windows groups that the user is a member of.
120      * 
121      * @return A map of group names to groups.
122      */
123     public Map<String, WindowsAccount> getGroups() {
124         return this.groups;
125     }
126 
127     /**
128      * Returns a list of role principal objects.
129      * 
130      * @param group
131      *            Windows group.
132      * @param principalFormat
133      *            Principal format.
134      * @return List of role principal objects.
135      */
136     private static List<String> getRoleNames(final IWindowsAccount group, final PrincipalFormat principalFormat) {
137         final List<String> principals = new ArrayList<String>();
138         switch (principalFormat) {
139             case FQN:
140                 principals.add(group.getFqn());
141                 break;
142             case SID:
143                 principals.add(group.getSidString());
144                 break;
145             case BOTH:
146                 principals.add(group.getFqn());
147                 principals.add(group.getSidString());
148                 break;
149             case NONE:
150                 break;
151             default:
152                 break;
153         }
154         return principals;
155     }
156 
157     /**
158      * Returns a list of user principal objects.
159      * 
160      * @param windowsIdentity
161      *            Windows identity.
162      * @param principalFormat
163      *            Principal format.
164      * @return A list of user principal objects.
165      */
166     private static List<String> getPrincipalNames(final IWindowsIdentity windowsIdentity,
167             final PrincipalFormat principalFormat) {
168         final List<String> principals = new ArrayList<String>();
169         switch (principalFormat) {
170             case FQN:
171                 principals.add(windowsIdentity.getFqn());
172                 break;
173             case SID:
174                 principals.add(windowsIdentity.getSidString());
175                 break;
176             case BOTH:
177                 principals.add(windowsIdentity.getFqn());
178                 principals.add(windowsIdentity.getSidString());
179                 break;
180             case NONE:
181                 break;
182             default:
183                 break;
184         }
185         return principals;
186     }
187 
188     /**
189      * Get an array of roles as a string.
190      * 
191      * @return Role1, Role2, ...
192      */
193     public String getRolesString() {
194         return Joiner.on(", ").join(this.getRoles());
195     }
196 }