use of java.security.Permission in project jspwiki by apache.
the class PermissionTag method checkPermission.
/**
* Checks a single permission.
*
* @param permission
* @return true if granted, false if not
*/
private boolean checkPermission(String permission) {
WikiSession session = m_wikiContext.getWikiSession();
WikiPage page = m_wikiContext.getPage();
AuthorizationManager mgr = m_wikiContext.getEngine().getAuthorizationManager();
boolean gotPermission = false;
if (CREATE_GROUPS.equals(permission) || CREATE_PAGES.equals(permission) || EDIT_PREFERENCES.equals(permission) || EDIT_PROFILE.equals(permission) || LOGIN.equals(permission)) {
gotPermission = mgr.checkPermission(session, new WikiPermission(page.getWiki(), permission));
} else if (VIEW_GROUP.equals(permission) || EDIT_GROUP.equals(permission) || DELETE_GROUP.equals(permission)) {
Command command = m_wikiContext.getCommand();
gotPermission = false;
if (command instanceof GroupCommand && command.getTarget() != null) {
GroupPrincipal group = (GroupPrincipal) command.getTarget();
String groupName = group.getName();
String action = "view";
if (EDIT_GROUP.equals(permission)) {
action = "edit";
} else if (DELETE_GROUP.equals(permission)) {
action = "delete";
}
gotPermission = mgr.checkPermission(session, new GroupPermission(groupName, action));
}
} else if (ALL_PERMISSION.equals(permission)) {
gotPermission = mgr.checkPermission(session, new AllPermission(m_wikiContext.getEngine().getApplicationName()));
} else if (page != null) {
//
if (EDIT.equals(permission)) {
WikiPage latest = m_wikiContext.getEngine().getPage(page.getName());
if (page.getVersion() != WikiProvider.LATEST_VERSION && latest.getVersion() != page.getVersion()) {
return false;
}
}
Permission p = PermissionFactory.getPagePermission(page, permission);
gotPermission = mgr.checkPermission(session, p);
}
return gotPermission;
}
use of java.security.Permission in project jspwiki by apache.
the class AttachmentServlet method doGet.
/**
* Serves a GET with two parameters: 'wikiname' specifying the wikiname
* of the attachment, 'version' specifying the version indicator.
*/
// FIXME: Messages would need to be localized somehow.
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException {
WikiContext context = m_engine.createContext(req, WikiContext.ATTACH);
String version = req.getParameter(HDR_VERSION);
String nextPage = req.getParameter("nextpage");
String msg = "An error occurred. Ouch.";
int ver = WikiProvider.LATEST_VERSION;
AttachmentManager mgr = m_engine.getAttachmentManager();
AuthorizationManager authmgr = m_engine.getAuthorizationManager();
String page = context.getPage().getName();
if (page == null) {
log.info("Invalid attachment name.");
res.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
OutputStream out = null;
InputStream in = null;
try {
log.debug("Attempting to download att " + page + ", version " + version);
if (version != null) {
ver = Integer.parseInt(version);
}
Attachment att = mgr.getAttachmentInfo(page, ver);
if (att != null) {
//
// Check if the user has permission for this attachment
//
Permission permission = PermissionFactory.getPagePermission(att, "view");
if (!authmgr.checkPermission(context.getWikiSession(), permission)) {
log.debug("User does not have permission for this");
res.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
//
if (HttpUtil.checkFor304(req, att.getName(), att.getLastModified())) {
log.debug("Client has latest version already, sending 304...");
res.sendError(HttpServletResponse.SC_NOT_MODIFIED);
return;
}
String mimetype = getMimeType(context, att.getFileName());
res.setContentType(mimetype);
//
// We use 'inline' instead of 'attachment' so that user agents
// can try to automatically open the file.
//
res.addHeader("Content-Disposition", "inline; filename=\"" + att.getFileName() + "\";");
res.addDateHeader("Last-Modified", att.getLastModified().getTime());
if (!att.isCacheable()) {
res.addHeader("Pragma", "no-cache");
res.addHeader("Cache-control", "no-cache");
}
// If a size is provided by the provider, report it.
if (att.getSize() >= 0) {
// log.info("size:"+att.getSize());
res.setContentLength((int) att.getSize());
}
out = res.getOutputStream();
in = mgr.getAttachmentStream(context, att);
int read = 0;
byte[] buffer = new byte[BUFFER_SIZE];
while ((read = in.read(buffer)) > -1) {
out.write(buffer, 0, read);
}
if (log.isDebugEnabled()) {
msg = "Attachment " + att.getFileName() + " sent to " + req.getRemoteUser() + " on " + HttpUtil.getRemoteAddress(req);
log.debug(msg);
}
if (nextPage != null) {
res.sendRedirect(validateNextPage(nextPage, m_engine.getURL(WikiContext.ERROR, "", null, false)));
}
} else {
msg = "Attachment '" + page + "', version " + ver + " does not exist.";
log.info(msg);
res.sendError(HttpServletResponse.SC_NOT_FOUND, msg);
}
} catch (ProviderException pe) {
msg = "Provider error: " + pe.getMessage();
log.debug("Provider failed while reading", pe);
//
try {
res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg);
} catch (IllegalStateException e) {
}
} catch (NumberFormatException nfe) {
log.warn("Invalid version number: " + version);
res.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid version number");
} catch (SocketException se) {
//
// These are very common in download situations due to aggressive
// clients. No need to try and send an error.
//
log.debug("I/O exception during download", se);
} catch (IOException ioe) {
//
// Client dropped the connection or something else happened.
// We don't know where the error came from, so we'll at least
// try to send an error and catch it quietly if it doesn't quite work.
//
msg = "Error: " + ioe.getMessage();
log.debug("I/O exception during download", ioe);
try {
res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg);
} catch (IllegalStateException e) {
}
} finally {
IOUtils.closeQuietly(in);
//
// Quite often, aggressive clients close the connection when they have
// received the last bits. Therefore, we close the output, but ignore
// any exception that might come out of it.
//
IOUtils.closeQuietly(out);
}
}
use of java.security.Permission in project jspwiki by apache.
the class AttachmentServlet method executeUpload.
/**
* @param context the wiki context
* @param data the input stream data
* @param filename the name of the file to upload
* @param errorPage the place to which you want to get a redirection
* @param parentPage the page to which the file should be attached
* @param changenote The change note
* @param contentLength The content length
* @return <code>true</code> if upload results in the creation of a new page;
* <code>false</code> otherwise
* @throws RedirectException If the content needs to be redirected
* @throws IOException If there is a problem in the upload.
* @throws ProviderException If there is a problem in the backend.
*/
protected boolean executeUpload(WikiContext context, InputStream data, String filename, String errorPage, String parentPage, String changenote, long contentLength) throws RedirectException, IOException, ProviderException {
boolean created = false;
try {
filename = AttachmentManager.validateFileName(filename);
} catch (WikiException e) {
// here we have the context available, so we can internationalize it properly :
throw new RedirectException(Preferences.getBundle(context, InternationalizationManager.CORE_BUNDLE).getString(e.getMessage()), errorPage);
}
if (!context.hasAdminPermissions()) {
if (contentLength > m_maxSize) {
// FIXME: Does not delete the received files.
throw new RedirectException("File exceeds maximum size (" + m_maxSize + " bytes)", errorPage);
}
if (!isTypeAllowed(filename)) {
throw new RedirectException("Files of this type may not be uploaded to this wiki", errorPage);
}
}
Principal user = context.getCurrentUser();
AttachmentManager mgr = m_engine.getAttachmentManager();
log.debug("file=" + filename);
if (data == null) {
log.error("File could not be opened.");
throw new RedirectException("File could not be opened.", errorPage);
}
//
// Check whether we already have this kind of a page.
// If the "page" parameter already defines an attachment
// name for an update, then we just use that file.
// Otherwise we create a new attachment, and use the
// filename given. Incidentally, this will also mean
// that if the user uploads a file with the exact
// same name than some other previous attachment,
// then that attachment gains a new version.
//
Attachment att = mgr.getAttachmentInfo(context.getPage().getName());
if (att == null) {
att = new Attachment(m_engine, parentPage, filename);
created = true;
}
att.setSize(contentLength);
//
// Check if we're allowed to do this?
//
Permission permission = PermissionFactory.getPagePermission(att, "upload");
if (m_engine.getAuthorizationManager().checkPermission(context.getWikiSession(), permission)) {
if (user != null) {
att.setAuthor(user.getName());
}
if (changenote != null && changenote.length() > 0) {
att.setAttribute(WikiPage.CHANGENOTE, changenote);
}
try {
m_engine.getAttachmentManager().storeAttachment(att, data);
} catch (ProviderException pe) {
// here we have the context available, so we can internationalize it properly :
throw new ProviderException(Preferences.getBundle(context, InternationalizationManager.CORE_BUNDLE).getString(pe.getMessage()));
}
log.info("User " + user + " uploaded attachment to " + parentPage + " called " + filename + ", size " + att.getSize());
} else {
throw new RedirectException("No permission to upload a file", errorPage);
}
return created;
}
use of java.security.Permission in project jspwiki by apache.
the class AuthorizationManager method checkPermission.
/**
* Returns <code>true</code> or <code>false</code>, depending on
* whether a Permission is allowed for the Subject associated with
* a supplied WikiSession. The access control algorithm works this way:
* <ol>
* <li>The {@link org.apache.wiki.auth.acl.Acl} for the page is obtained</li>
* <li>The Subject associated with the current
* {@link org.apache.wiki.WikiSession} is obtained</li>
* <li>If the Subject's Principal set includes the Role Principal that is
* the administrator group, always allow the Permission</li>
* <li>For all permissions, check to see if the Permission is allowed according
* to the default security policy. If it isn't, deny the permission and halt
* further processing.</li>
* <li>If there is an Acl, get the list of Principals assigned this
* Permission in the Acl: these will be role, group or user Principals, or
* {@link org.apache.wiki.auth.acl.UnresolvedPrincipal}s (see below).
* Then iterate through the Subject's Principal set and determine whether
* the user (Subject) possesses any one of these specified Roles or
* Principals. The matching process delegates to
* {@link #hasRoleOrPrincipal(WikiSession, Principal)}.
* </ol>
* <p>
* Note that when iterating through the Acl's list of authorized Principals,
* it is possible that one or more of the Acl's Principal entries are of
* type <code>UnresolvedPrincipal</code>. This means that the last time
* the ACL was read, the Principal (user, built-in Role, authorizer Role, or
* wiki Group) could not be resolved: the Role was not valid, the user
* wasn't found in the UserDatabase, or the Group wasn't known to (e.g.,
* cached) in the GroupManager. If an <code>UnresolvedPrincipal</code> is
* encountered, this method will attempt to resolve it first <em>before</em>
* checking to see if the Subject possesses this principal, by calling
* {@link #resolvePrincipal(String)}. If the (re-)resolution does not
* succeed, the access check for the principal will fail by definition (the
* Subject should never contain UnresolvedPrincipals).
* </p>
* <p>
* If security not set to JAAS, will return true.
* </p>
* @param session the current wiki session
* @param permission the Permission being checked
* @see #hasRoleOrPrincipal(WikiSession, Principal)
* @return the result of the Permission check
*/
public boolean checkPermission(WikiSession session, Permission permission) {
//
if (session == null || permission == null) {
fireEvent(WikiSecurityEvent.ACCESS_DENIED, null, permission);
return false;
}
Principal user = session.getLoginPrincipal();
// Always allow the action if user has AllPermission
Permission allPermission = new AllPermission(m_engine.getApplicationName());
boolean hasAllPermission = checkStaticPermission(session, allPermission);
if (hasAllPermission) {
fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user, permission);
return true;
}
// If the user doesn't have *at least* the permission
// granted by policy, return false.
boolean hasPolicyPermission = checkStaticPermission(session, permission);
if (!hasPolicyPermission) {
fireEvent(WikiSecurityEvent.ACCESS_DENIED, user, permission);
return false;
}
// If this isn't a PagePermission, it's allowed
if (!(permission instanceof PagePermission)) {
fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user, permission);
return true;
}
//
// If the page or ACL is null, it's allowed.
//
String pageName = ((PagePermission) permission).getPage();
WikiPage page = m_engine.getPage(pageName);
Acl acl = (page == null) ? null : m_engine.getAclManager().getPermissions(page);
if (page == null || acl == null || acl.isEmpty()) {
fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user, permission);
return true;
}
//
// Next, iterate through the Principal objects assigned
// this permission. If the context's subject possesses
// any of these, the action is allowed.
Principal[] aclPrincipals = acl.findPrincipals(permission);
log.debug("Checking ACL entries...");
log.debug("Acl for this page is: " + acl);
log.debug("Checking for principal: " + Arrays.toString(aclPrincipals));
log.debug("Permission: " + permission);
for (Principal aclPrincipal : aclPrincipals) {
// try to resolve it here & correct the Acl
if (aclPrincipal instanceof UnresolvedPrincipal) {
AclEntry aclEntry = acl.getEntry(aclPrincipal);
aclPrincipal = resolvePrincipal(aclPrincipal.getName());
if (aclEntry != null && !(aclPrincipal instanceof UnresolvedPrincipal)) {
aclEntry.setPrincipal(aclPrincipal);
}
}
if (hasRoleOrPrincipal(session, aclPrincipal)) {
fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user, permission);
return true;
}
}
fireEvent(WikiSecurityEvent.ACCESS_DENIED, user, permission);
return false;
}
use of java.security.Permission in project jspwiki by apache.
the class DefaultAclManager method printAcl.
/**
* Generates an ACL string for inclusion in a wiki page, based on a supplied Acl object.
* All of the permissions in this Acl are assumed to apply to the same page scope.
* The names of the pages are ignored; only the actions and principals matter.
*
* @param acl the ACL
* @return the ACL string
*/
protected static String printAcl(Acl acl) {
// Extract the ACL entries into a Map with keys == permissions, values == principals
Map<String, List<Principal>> permissionPrincipals = new TreeMap<String, List<Principal>>();
Enumeration<AclEntry> entries = acl.entries();
while (entries.hasMoreElements()) {
AclEntry entry = entries.nextElement();
Principal principal = entry.getPrincipal();
Enumeration<Permission> permissions = entry.permissions();
while (permissions.hasMoreElements()) {
Permission permission = permissions.nextElement();
List<Principal> principals = permissionPrincipals.get(permission.getActions());
if (principals == null) {
principals = new ArrayList<Principal>();
String action = permission.getActions();
if (action.indexOf(',') != -1) {
throw new IllegalStateException("AclEntry permission cannot have multiple targets.");
}
permissionPrincipals.put(action, principals);
}
principals.add(principal);
}
}
// Now, iterate through each permission in the map and generate an ACL string
StringBuilder s = new StringBuilder();
for (Map.Entry<String, List<Principal>> entry : permissionPrincipals.entrySet()) {
String action = entry.getKey();
List<Principal> principals = entry.getValue();
Collections.sort(principals, new PrincipalComparator());
s.append("[{ALLOW ");
s.append(action);
s.append(" ");
for (int i = 0; i < principals.size(); i++) {
Principal principal = principals.get(i);
s.append(principal.getName());
if (i < (principals.size() - 1)) {
s.append(",");
}
}
s.append("}]\n");
}
return s.toString();
}
Aggregations