File D:\maven-qcr-plugin-testsunitaires\qcr4java\jenkins-master\target\site\qc\core\src\main\java\hudson\security\AuthorizationMatrixProperty.java.html

1 /*
2 * The MIT License
3 *
4 * Copyright (c) 2004-2010, Sun Microsystems, Inc., Kohsuke Kawaguchi, Yahoo! Inc., Peter Hayes, Tom Huybrechts
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
14 * all 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
22 * THE SOFTWARE.
23 */
24 package hudson.security;
25
26 import hudson.diagnosis.OldDataMonitor;
27 import hudson.model.AbstractProject;
28 import hudson.model.Item;
29 import hudson.model.Job;
30 import hudson.model.JobProperty;
31 import hudson.model.JobPropertyDescriptor;
32 import jenkins.model.Jenkins;
33 import hudson.model.Run;
34 import hudson.Extension;
35 import hudson.util.FormValidation;
36 import hudson.util.RobustReflectionConverter;
37
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.HashMap;
41 import java.util.HashSet;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Set;
45 import java.util.Collections;
46 import java.util.Map.Entry;
47 import java.util.logging.Level;
48 import java.util.logging.Logger;
49 import java.io.IOException;
50
51 import net.sf.json.JSONObject;
52
53 import org.acegisecurity.acls.sid.Sid;
54 import org.kohsuke.stapler.StaplerRequest;
55 import org.kohsuke.stapler.QueryParameter;
56 import org.kohsuke.stapler.AncestorInPath;
57
58 import com.thoughtworks.xstream.converters.Converter;
59 import com.thoughtworks.xstream.converters.MarshallingContext;
60 import com.thoughtworks.xstream.converters.UnmarshallingContext;
61 import com.thoughtworks.xstream.io.HierarchicalStreamReader;
62 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
63
64 import javax.servlet.ServletException;
65
66 /**
67 * {@link JobProperty} to associate ACL for each project.
68 *
69 * <p>
70 * Once created (and initialized), this object becomes immutable.
71 */
72 public class AuthorizationMatrixProperty extends JobProperty<Job<?, ?>> {
73
74 private transient SidACL acl = new AclImpl();
75
76 /**
77 * List up all permissions that are granted.
78 *
79 * Strings are either the granted authority or the principal, which is not
80 * distinguished.
81 */
82 private final Map<Permission, Set<String>> grantedPermissions = new HashMap<Permission, Set<String>>();
83
84 private Set<String> sids = new HashSet<String>();
85
86 private AuthorizationMatrixProperty() {
87 }
88
89 public AuthorizationMatrixProperty(Map<Permission, Set<String>> grantedPermissions) {
90 // do a deep copy to be safe
91 for (Entry<Permission,Set<String>> e : grantedPermissions.entrySet())
92 this.grantedPermissions.put(e.getKey(),new HashSet<String>(e.getValue()));
93 }
94
95 public Set<String> getGroups() {
96 return sids;
97 }
98
99 /**
100 * Returns all SIDs configured in this matrix, minus "anonymous"
101 *
102 * @return Always non-null.
103 */
104 public List<String> getAllSIDs() {
105 Set<String> r = new HashSet<String>();
106 for (Set<String> set : grantedPermissions.values())
107 r.addAll(set);
108 r.remove("anonymous");
109
110 String[] data = r.toArray(new String[r.size()]);
111 Arrays.sort(data);
112 return Arrays.asList(data);
113 }
114
115 /**
116 * Returns all the (Permission,sid) pairs that are granted, in the multi-map form.
117 *
118 * @return
119 * read-only. never null.
120 */
121 public Map<Permission,Set<String>> getGrantedPermissions() {
122 return Collections.unmodifiableMap(grantedPermissions);
123 }
124
125 /**
126 * Adds to {@link #grantedPermissions}. Use of this method should be limited
127 * during construction, as this object itself is considered immutable once
128 * populated.
129 */
130 protected void add(Permission p, String sid) {
131 Set<String> set = grantedPermissions.get(p);
132 if (set == null)
133 grantedPermissions.put(p, set = new HashSet<String>());
134 set.add(sid);
135 sids.add(sid);
136 }
137
138 @Extension
139 public static class DescriptorImpl extends JobPropertyDescriptor {
140 @Override
141 public JobProperty<?> newInstance(StaplerRequest req, JSONObject formData) throws FormException {
142 formData = formData.getJSONObject("useProjectSecurity");
143 if (formData.isNullObject())
144 return null;
145
146 AuthorizationMatrixProperty amp = new AuthorizationMatrixProperty();
147 for (Map.Entry<String, Object> r : (Set<Map.Entry<String, Object>>) formData.getJSONObject("data").entrySet()) {
148 String sid = r.getKey();
149 if (r.getValue() instanceof JSONObject) {
150 for (Map.Entry<String, Boolean> e : (Set<Map.Entry<String, Boolean>>) ((JSONObject) r
151 .getValue()).entrySet()) {
152 if (e.getValue()) {
153 Permission p = Permission.fromId(e.getKey());
154 amp.add(p, sid);
155 }
156 }
157 }
158 }
159 return amp;
160 }
161
162 @Override
163 public boolean isApplicable(Class<? extends Job> jobType) {
164 // only applicable when ProjectMatrixAuthorizationStrategy is in charge
165 return Jenkins.getInstance().getAuthorizationStrategy() instanceof ProjectMatrixAuthorizationStrategy;
166 }
167
168 @Override
169 public String getDisplayName() {
170 return "Authorization Matrix";
171 }
172
173 public List<PermissionGroup> getAllGroups() {
174 List<PermissionGroup> r = new ArrayList<PermissionGroup>();
175 for (PermissionGroup pg : PermissionGroup.getAll()) {
176 if (pg.hasPermissionContainedBy(PermissionScope.ITEM))
177 r.add(pg);
178 }
179 return r;
180 }
181
182 public boolean showPermission(Permission p) {
183 return p.getEnabled() && p.isContainedBy(PermissionScope.ITEM);
184 }
185
186 public FormValidation doCheckName(@AncestorInPath Job project, @QueryParameter String value) throws IOException, ServletException {
187 return GlobalMatrixAuthorizationStrategy.DESCRIPTOR.doCheckName_(value, project, AbstractProject.CONFIGURE);
188 }
189 }
190
191 private final class AclImpl extends SidACL {
192 protected Boolean hasPermission(Sid sid, Permission p) {
193 if (AuthorizationMatrixProperty.this.hasPermission(toString(sid),p))
194 return true;
195 return null;
196 }
197 }
198
199 public SidACL getACL() {
200 return acl;
201 }
202
203 /**
204 * Checks if the given SID has the given permission.
205 */
206 public boolean hasPermission(String sid, Permission p) {
207 for (; p != null; p = p.impliedBy) {
208 Set<String> set = grantedPermissions.get(p);
209 if (set != null && set.contains(sid))
210 return true;
211 }
212 return false;
213 }
214
215 /**
216 * Checks if the permission is explicitly given, instead of implied through {@link Permission#impliedBy}.
217 */
218 public boolean hasExplicitPermission(String sid, Permission p) {
219 Set<String> set = grantedPermissions.get(p);
220 return set != null && set.contains(sid);
221 }
222
223 /**
224 * Works like {@link #add(Permission, String)} but takes both parameters
225 * from a single string of the form <tt>PERMISSIONID:sid</tt>
226 */
227 private void add(String shortForm) {
228 int idx = shortForm.indexOf(':');
229 Permission p = Permission.fromId(shortForm.substring(0, idx));
230 if (p==null)
231 throw new IllegalArgumentException("Failed to parse '"+shortForm+"' --- no such permission");
232 add(p, shortForm.substring(idx + 1));
233 }
234
235 /**
236 * Persist {@link ProjectMatrixAuthorizationStrategy} as a list of IDs that
237 * represent {@link ProjectMatrixAuthorizationStrategy#grantedPermissions}.
238 */
239 public static final class ConverterImpl implements Converter {
240 public boolean canConvert(Class type) {
241 return type == AuthorizationMatrixProperty.class;
242 }
243
244 public void marshal(Object source, HierarchicalStreamWriter writer,
245 MarshallingContext context) {
246 AuthorizationMatrixProperty amp = (AuthorizationMatrixProperty) source;
247
248 for (Entry<Permission, Set<String>> e : amp.grantedPermissions
249 .entrySet()) {
250 String p = e.getKey().getId();
251 for (String sid : e.getValue()) {
252 writer.startNode("permission");
253 writer.setValue(p + ':' + sid);
254 writer.endNode();
255 }
256 }
257 }
258
259 public Object unmarshal(HierarchicalStreamReader reader,
260 final UnmarshallingContext context) {
261 AuthorizationMatrixProperty as = new AuthorizationMatrixProperty();
262
263 String prop = reader.peekNextChild();
264 if (prop!=null && prop.equals("useProjectSecurity")) {
265 reader.moveDown();
266 reader.getValue(); // we used to use this but not any more.
267 reader.moveUp();
268 }
269 while (reader.hasMoreChildren()) {
270 reader.moveDown();
271 try {
272 as.add(reader.getValue());
273 } catch (IllegalArgumentException ex) {
274 Logger.getLogger(AuthorizationMatrixProperty.class.getName())
275 .log(Level.WARNING,"Skipping a non-existent permission",ex);
276 RobustReflectionConverter.addErrorInContext(context, ex);
277 }
278 reader.moveUp();
279 }
280
281 if (GlobalMatrixAuthorizationStrategy.migrateHudson2324(as.grantedPermissions))
282 OldDataMonitor.report(context, "1.301");
283
284 return as;
285 }
286 }
287 }
288