1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.opencastproject.security.util;
23
24 import static org.apache.commons.lang3.StringUtils.isBlank;
25 import static org.opencastproject.security.api.SecurityConstants.EPISODE_ROLE_ID_PREFIX;
26 import static org.opencastproject.security.api.SecurityConstants.GLOBAL_ADMIN_ROLE;
27 import static org.opencastproject.security.api.SecurityConstants.GLOBAL_ANONYMOUS_USERNAME;
28 import static org.opencastproject.security.api.SecurityConstants.GLOBAL_CAPTURE_AGENT_ROLE;
29 import static org.opencastproject.util.data.Tuple.tuple;
30
31 import org.opencastproject.security.api.JaxbOrganization;
32 import org.opencastproject.security.api.JaxbRole;
33 import org.opencastproject.security.api.JaxbUser;
34 import org.opencastproject.security.api.Organization;
35 import org.opencastproject.security.api.OrganizationDirectoryService;
36 import org.opencastproject.security.api.SecurityConstants;
37 import org.opencastproject.security.api.SecurityService;
38 import org.opencastproject.security.api.UnauthorizedException;
39 import org.opencastproject.security.api.User;
40 import org.opencastproject.security.api.UserDirectoryService;
41 import org.opencastproject.util.ConfigurationException;
42 import org.opencastproject.util.NotFoundException;
43 import org.opencastproject.util.data.Tuple;
44
45 import org.apache.commons.lang3.StringUtils;
46 import org.osgi.service.component.ComponentContext;
47
48 import java.net.URL;
49 import java.util.Optional;
50 import java.util.regex.Pattern;
51
52
53 public final class SecurityUtil {
54 private static final Pattern SANITIZING_PATTERN = Pattern.compile("[^a-zA-Z0-9_]");
55
56 private SecurityUtil() {
57 }
58
59
60 public static final String PROPERTY_KEY_SYS_USER = "org.opencastproject.security.digest.user";
61
62
63
64
65
66
67
68
69
70
71
72
73
74 public static void runAs(SecurityService sec, Organization org, User user, Runnable fn) {
75 final Organization prevOrg = sec.getOrganization();
76 final User prevUser = prevOrg != null ? sec.getUser() : null;
77 sec.setOrganization(org);
78 sec.setUser(user);
79 try {
80 fn.run();
81 } finally {
82 sec.setOrganization(prevOrg);
83 sec.setUser(prevUser);
84 }
85 }
86
87
88
89
90
91
92
93
94
95 public static User createSystemUser(String systemUserName, Organization org) {
96 JaxbOrganization jaxbOrganization = JaxbOrganization.fromOrganization(org);
97 return new JaxbUser(systemUserName, null, jaxbOrganization, new JaxbRole(GLOBAL_ADMIN_ROLE, jaxbOrganization),
98 new JaxbRole(org.getAdminRole(), jaxbOrganization));
99 }
100
101
102
103
104
105
106
107
108 public static User createAnonymousUser(Organization org) {
109 JaxbOrganization jaxbOrganization = JaxbOrganization.fromOrganization(org);
110 return new JaxbUser(GLOBAL_ANONYMOUS_USERNAME, null, jaxbOrganization, new JaxbRole(
111 jaxbOrganization.getAnonymousRole(), jaxbOrganization));
112 }
113
114
115
116
117
118
119
120 public static User createSystemUser(ComponentContext cc, Organization org) {
121 final String systemUserName = cc.getBundleContext().getProperty(PROPERTY_KEY_SYS_USER);
122 return createSystemUser(systemUserName, org);
123 }
124
125
126
127
128
129
130 public static String getSystemUserName(ComponentContext cc) {
131 final String systemUserName = cc.getBundleContext().getProperty(PROPERTY_KEY_SYS_USER);
132 if (systemUserName != null) {
133 return systemUserName;
134 } else {
135 throw new ConfigurationException(
136 "An Opencast installation always needs a system user name. Please configure one under the key "
137 + PROPERTY_KEY_SYS_USER);
138 }
139 }
140
141
142
143
144 public static Optional<Tuple<User, Organization>> getUserAndOrganization(SecurityService sec,
145 OrganizationDirectoryService orgDir, String orgId, UserDirectoryService userDir, String userId) {
146 final Organization prevOrg = sec.getOrganization();
147 try {
148 final Organization org = orgDir.getOrganization(orgId);
149 sec.setOrganization(org);
150 return Optional.ofNullable(userDir.loadUser(userId))
151 .map(user -> tuple(user, org));
152 } catch (NotFoundException e) {
153 return Optional.empty();
154 } finally {
155 sec.setOrganization(prevOrg);
156 }
157 }
158
159
160 public static Tuple<String, Integer> hostAndPort(URL url) {
161 int port = url.getPort();
162 if (port < 0) {
163 port = url.getDefaultPort();
164 }
165 return tuple(StringUtils.strip(url.getHost(), "/"), port);
166 }
167
168
169
170
171
172
173
174
175 public static void checkAgentAccess(final SecurityService securityService, final String agentId)
176 throws UnauthorizedException {
177 if (isBlank(agentId)) {
178 return;
179 }
180 final User user = securityService.getUser();
181 if (user.hasRole(SecurityConstants.GLOBAL_ADMIN_ROLE) || user.hasRole(user.getOrganization().getAdminRole())) {
182 return;
183 }
184 if (!user.hasRole(SecurityUtil.getCaptureAgentRole(agentId))) {
185 throw new UnauthorizedException(user, "schedule");
186 }
187 }
188
189 private static String sanitizeCaName(final String ca) {
190 return SANITIZING_PATTERN.matcher(ca).replaceAll("").toUpperCase();
191 }
192
193
194
195
196
197
198
199
200
201 public static String getCaptureAgentRole(final String agentId) {
202 return GLOBAL_CAPTURE_AGENT_ROLE + "_" + sanitizeCaName(agentId);
203 }
204
205
206
207
208
209
210
211
212 public static String getEpisodeRoleId(final String mediaPackageId, final String action) {
213 return EPISODE_ROLE_ID_PREFIX + "_" + mediaPackageId + "_" + action.toUpperCase();
214 }
215 }