blob: edbb6720a2ce4e8ff950971e9165b17a54db392d [file] [log] [blame]
Shuyi Chend7955ce2013-05-22 14:51:55 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package org.apache.harmony.javax.security.auth;
19
20import java.security.DomainCombiner;
21import java.security.Principal;
22import java.security.ProtectionDomain;
23import java.util.Set;
24
25/**
26 * Merges permissions based on code source and code signers with permissions
27 * granted to the specified {@link Subject}.
28 */
29public class SubjectDomainCombiner implements DomainCombiner {
30
31 // subject to be associated
32 private Subject subject;
33
34 // permission required to get a subject object
35 private static final AuthPermission _GET = new AuthPermission(
36 "getSubjectFromDomainCombiner"); //$NON-NLS-1$
37
38 /**
39 * Creates a domain combiner for the entity provided in {@code subject}.
40 *
41 * @param subject
42 * the entity to which this domain combiner is associated.
43 */
44 public SubjectDomainCombiner(Subject subject) {
45 super();
46 if (subject == null) {
47 throw new NullPointerException();
48 }
49 this.subject = subject;
50 }
51
52 /**
53 * Returns the entity to which this domain combiner is associated.
54 *
55 * @return the entity to which this domain combiner is associated.
56 */
57 public Subject getSubject() {
58 SecurityManager sm = System.getSecurityManager();
59 if (sm != null) {
60 sm.checkPermission(_GET);
61 }
62
63 return subject;
64 }
65
66 /**
67 * Merges the {@code ProtectionDomain} with the {@code Principal}s
68 * associated with the subject of this {@code SubjectDomainCombiner}.
69 *
70 * @param currentDomains
71 * the {@code ProtectionDomain}s associated with the context of
72 * the current thread. The domains must be sorted according to
73 * the execution order, the most recent residing at the
74 * beginning.
75 * @param assignedDomains
76 * the {@code ProtectionDomain}s from the parent thread based on
77 * code source and signers.
78 * @return a single {@code ProtectionDomain} array computed from the two
79 * provided arrays, or {@code null}.
80 * @see ProtectionDomain
81 */
82 public ProtectionDomain[] combine(ProtectionDomain[] currentDomains,
83 ProtectionDomain[] assignedDomains) {
84 // get array length for combining protection domains
85 int len = 0;
86 if (currentDomains != null) {
87 len += currentDomains.length;
88 }
89 if (assignedDomains != null) {
90 len += assignedDomains.length;
91 }
92 if (len == 0) {
93 return null;
94 }
95
96 ProtectionDomain[] pd = new ProtectionDomain[len];
97
98 // for each current domain substitute set of principal with subject's
99 int cur = 0;
100 if (currentDomains != null) {
101
102 Set<Principal> s = subject.getPrincipals();
103 Principal[] p = s.toArray(new Principal[s.size()]);
104
105 for (cur = 0; cur < currentDomains.length; cur++) {
106 if (currentDomains[cur] != null) {
107 ProtectionDomain newPD;
108 newPD = new ProtectionDomain(currentDomains[cur].getCodeSource(),
109 currentDomains[cur].getPermissions(), currentDomains[cur]
110 .getClassLoader(), p);
111 pd[cur] = newPD;
112 }
113 }
114 }
115
116 // copy assigned domains
117 if (assignedDomains != null) {
118 System.arraycopy(assignedDomains, 0, pd, cur, assignedDomains.length);
119 }
120
121 return pd;
122 }
123}