use of org.structr.core.auth.exception.AuthenticationException in project structr by structr.
the class StructrCMISServicesFactory method checkAuthentication.
// ----- private methods -----
private SecurityContext checkAuthentication(final CallContext callContext) {
final App app = StructrApp.getInstance();
try (final Tx tx = app.tx()) {
final String username = callContext.getUsername();
final String password = callContext.getPassword();
final Principal principal = AuthHelper.getPrincipalForPassword(Principal.name, username, password);
SecurityContext securityContext = null;
if (principal != null) {
if (principal instanceof SuperUser) {
securityContext = SecurityContext.getSuperUserInstance();
} else {
securityContext = SecurityContext.getInstance(principal, AccessMode.Backend);
}
}
tx.success();
if (securityContext != null) {
return securityContext;
}
} catch (AuthenticationException aex) {
throw new CmisUnauthorizedException(aex.getMessage());
} catch (FrameworkException fex) {
logger.warn("", fex);
}
throw new CmisUnauthorizedException();
}
use of org.structr.core.auth.exception.AuthenticationException in project structr by structr.
the class UiAuthenticator method doLogin.
@Override
public Principal doLogin(final HttpServletRequest request, final String emailOrUsername, final String password) throws AuthenticationException, FrameworkException {
final PropertyKey<String> confKey = StructrApp.key(User.class, "confirmationKey");
final PropertyKey<String> eMailKey = StructrApp.key(User.class, "eMail");
final Principal user = AuthHelper.getPrincipalForPassword(eMailKey, emailOrUsername, password);
if (user != null) {
final boolean allowLoginBeforeConfirmation = Settings.RegistrationAllowLoginBeforeConfirmation.getValue();
if (user.getProperty(confKey) != null && !allowLoginBeforeConfirmation) {
logger.warn("Login as {} not allowed before confirmation.", user);
throw new AuthenticationException(AuthHelper.STANDARD_ERROR_MSG);
}
AuthHelper.doLogin(request, user);
}
return user;
}
use of org.structr.core.auth.exception.AuthenticationException in project structr by structr.
the class AuthHelper method getPrincipalForPassword.
/**
* Find a {@link Principal} with matching password and given key or name
*
* @param key
* @param value
* @param password
* @return principal
* @throws AuthenticationException
*/
public static Principal getPrincipalForPassword(final PropertyKey<String> key, final String value, final String password) throws AuthenticationException {
String errorMsg = null;
Principal principal = null;
final String superuserName = Settings.SuperUserName.getValue();
final String superUserPwd = Settings.SuperUserPassword.getValue();
if (StringUtils.isEmpty(value)) {
logger.info("Empty value for key {}", key);
errorMsg = STANDARD_ERROR_MSG;
}
if (StringUtils.isEmpty(password)) {
logger.info("Empty password");
errorMsg = STANDARD_ERROR_MSG;
}
if (superuserName.equals(value) && superUserPwd.equals(password)) {
// logger.info("############# Authenticated as superadmin! ############");
principal = new SuperUser();
} else if (errorMsg == null) {
try {
principal = StructrApp.getInstance().nodeQuery(Principal.class).and().or(key, value).or(AbstractNode.name, value).disableSorting().getFirst();
if (principal == null) {
logger.info("No principal found for {} {}", new Object[] { key.dbName(), value });
errorMsg = STANDARD_ERROR_MSG;
} else {
if (principal.isBlocked()) {
logger.info("Principal {} is blocked", principal);
errorMsg = STANDARD_ERROR_MSG;
}
if (StringUtils.isEmpty(password)) {
logger.info("Empty password for principal {}", principal);
errorMsg = "Empty password, should never happen here!";
} else {
// let Principal decide how to check password
if (!principal.isValidPassword(password)) {
errorMsg = STANDARD_ERROR_MSG;
}
}
}
} catch (FrameworkException fex) {
logger.warn("", fex);
}
}
if (errorMsg != null) {
throw new AuthenticationException(errorMsg);
}
return principal;
}
use of org.structr.core.auth.exception.AuthenticationException in project structr by structr.
the class DeploymentServlet method doPost.
@Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException {
try (final Tx tx = StructrApp.getInstance().tx()) {
if (!ServletFileUpload.isMultipartContent(request)) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
response.getOutputStream().write("ERROR (400): Request does not contain multipart content.\n".getBytes("UTF-8"));
return;
}
final SecurityContext securityContext;
try {
securityContext = getConfig().getAuthenticator().initializeAndExamineRequest(request, response);
} catch (AuthenticationException ae) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getOutputStream().write("ERROR (401): Invalid user or password.\n".getBytes("UTF-8"));
return;
}
if (securityContext.getUser(false) == null && !Settings.DeploymentAllowAnonymousUploads.getValue()) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getOutputStream().write("ERROR (401): Anonymous uploads forbidden.\n".getBytes("UTF-8"));
return;
}
// Ensure access mode is frontend
securityContext.setAccessMode(AccessMode.Frontend);
request.setCharacterEncoding("UTF-8");
// Important: Set character encoding before calling response.getWriter() !!, see Servlet Spec 5.4
response.setCharacterEncoding("UTF-8");
// don't continue on redirects
if (response.getStatus() == 302) {
return;
}
final String pathInfo = request.getPathInfo();
String type = null;
if (StringUtils.isNotBlank(pathInfo)) {
type = SchemaHelper.normalizeEntityName(StringUtils.stripStart(pathInfo.trim(), "/"));
}
uploader.setFileSizeMax(MEGABYTE * Settings.DeploymentMaxFileSize.getValue());
uploader.setSizeMax(MEGABYTE * Settings.DeploymentMaxRequestSize.getValue());
response.setContentType("text/html");
final List<FileItem> fileItemsList = uploader.parseRequest(request);
final Iterator<FileItem> fileItemsIterator = fileItemsList.iterator();
final Map<String, Object> params = new HashMap<>();
while (fileItemsIterator.hasNext()) {
final FileItem item = fileItemsIterator.next();
try {
final String directoryPath = "/tmp/" + UUID.randomUUID();
final String filePath = directoryPath + ".zip";
File file = new File(filePath);
Files.write(IOUtils.toByteArray(item.getInputStream()), file);
unzip(file, directoryPath);
DeployCommand deployCommand = StructrApp.getInstance(securityContext).command(DeployCommand.class);
final Map<String, Object> attributes = new HashMap<>();
attributes.put("source", directoryPath + "/" + StringUtils.substringBeforeLast(item.getName(), "."));
deployCommand.execute(attributes);
file.deleteOnExit();
File dir = new File(directoryPath);
dir.deleteOnExit();
} catch (IOException ex) {
logger.warn("Could not upload file", ex);
}
}
tx.success();
} catch (FrameworkException | IOException | FileUploadException t) {
logger.error("Exception while processing request", t);
UiAuthenticator.writeInternalServerError(response);
}
}
use of org.structr.core.auth.exception.AuthenticationException in project structr by structr.
the class HtmlServlet method doGet.
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response) {
final Authenticator auth = getConfig().getAuthenticator();
List<Page> pages = null;
boolean requestUriContainsUuids = false;
SecurityContext securityContext;
final App app;
try {
assertInitialized();
final String path = request.getPathInfo() != null ? request.getPathInfo() : "/";
// check for registration (has its own tx because of write access
if (checkRegistration(auth, request, response, path)) {
return;
}
// check for registration (has its own tx because of write access
if (checkResetPassword(auth, request, response, path)) {
return;
}
// isolate request authentication in a transaction
try (final Tx tx = StructrApp.getInstance().tx()) {
securityContext = auth.initializeAndExamineRequest(request, response);
tx.success();
} catch (AuthenticationException aex) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
app = StructrApp.getInstance(securityContext);
try (final Tx tx = app.tx()) {
// Ensure access mode is frontend
securityContext.setAccessMode(AccessMode.Frontend);
request.setCharacterEncoding("UTF-8");
// Important: Set character encoding before calling response.getWriter() !!, see Servlet Spec 5.4
response.setCharacterEncoding("UTF-8");
boolean dontCache = false;
logger.debug("Path info {}", path);
// don't continue on redirects
if (response.getStatus() == 302) {
tx.success();
return;
}
final Principal user = securityContext.getUser(false);
if (user != null) {
// Don't cache if a user is logged in
dontCache = true;
}
final RenderContext renderContext = RenderContext.getInstance(securityContext, request, response);
renderContext.setResourceProvider(config.getResourceProvider());
final EditMode edit = renderContext.getEditMode(user);
DOMNode rootElement = null;
AbstractNode dataNode = null;
final String[] uriParts = PathHelper.getParts(path);
if ((uriParts == null) || (uriParts.length == 0)) {
// find a visible page
rootElement = findIndexPage(securityContext, pages, edit);
logger.debug("No path supplied, trying to find index page");
} else {
if (rootElement == null) {
rootElement = findPage(securityContext, pages, path, edit);
} else {
dontCache = true;
}
}
if (rootElement == null) {
// No page found
// In case of a file, try to find a file with the query string in the filename
final String queryString = request.getQueryString();
// Look for a file, first include the query string
File file = findFile(securityContext, request, path + (queryString != null ? "?" + queryString : ""));
// If no file with query string in the file name found, try without query string
if (file == null) {
file = findFile(securityContext, request, path);
}
if (file != null) {
streamFile(securityContext, file, request, response, edit);
tx.success();
return;
}
if (uriParts != null) {
// store remaining path parts in request
final Matcher matcher = threadLocalUUIDMatcher.get();
for (int i = 0; i < uriParts.length; i++) {
request.setAttribute(uriParts[i], i);
matcher.reset(uriParts[i]);
// set to "true" if part matches UUID pattern
requestUriContainsUuids |= matcher.matches();
}
}
if (!requestUriContainsUuids) {
// Try to find a data node by name
dataNode = findFirstNodeByName(securityContext, request, path);
} else {
dataNode = findNodeByUuid(securityContext, PathHelper.getName(path));
}
// if (dataNode != null && !(dataNode instanceof Linkable)) {
if (dataNode != null) {
// Last path part matches a data node
// Remove last path part and try again searching for a page
// clear possible entry points
request.removeAttribute(POSSIBLE_ENTRY_POINTS_KEY);
rootElement = findPage(securityContext, pages, StringUtils.substringBeforeLast(path, PathHelper.PATH_SEP), edit);
renderContext.setDetailsDataObject(dataNode);
// Start rendering on data node
if (rootElement == null && dataNode instanceof DOMNode) {
// check visibleForSite here as well
if (!(dataNode instanceof Page) || isVisibleForSite(request, (Page) dataNode)) {
rootElement = ((DOMNode) dataNode);
}
}
}
}
// look for pages with HTTP Basic Authentication (must be done as superuser)
if (rootElement == null) {
final HttpBasicAuthResult authResult = checkHttpBasicAuth(request, response, path);
switch(authResult.authState()) {
// Element with Basic Auth found and authentication succeeded
case Authenticated:
final Linkable result = authResult.getRootElement();
if (result instanceof Page) {
rootElement = (DOMNode) result;
securityContext = authResult.getSecurityContext();
renderContext.pushSecurityContext(securityContext);
} else if (result instanceof File) {
streamFile(authResult.getSecurityContext(), (File) result, request, response, EditMode.NONE);
tx.success();
return;
}
break;
// Page with Basic Auth found but not yet authenticated
case MustAuthenticate:
final Page errorPage = StructrApp.getInstance().nodeQuery(Page.class).and(StructrApp.key(Page.class, "showOnErrorCodes"), "401", false).getFirst();
if (errorPage != null && isVisibleForSite(request, errorPage)) {
// set error page
rootElement = errorPage;
// don't cache the error page
dontCache = true;
} else {
// send error
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
tx.success();
return;
}
break;
// no Basic Auth for given path, go on
case NoBasicAuth:
break;
}
}
// Still nothing found, do error handling
if (rootElement == null) {
rootElement = notFound(response, securityContext);
}
if (rootElement == null) {
tx.success();
return;
}
// check dont cache flag on page (if root element is a page)
// but don't modify true to false
dontCache |= rootElement.dontCache();
if (EditMode.WIDGET.equals(edit) || dontCache) {
setNoCacheHeaders(response);
}
if (!securityContext.isVisible(rootElement)) {
rootElement = notFound(response, securityContext);
if (rootElement == null) {
tx.success();
return;
}
} else {
if (!EditMode.WIDGET.equals(edit) && !dontCache && notModifiedSince(request, response, rootElement, dontCache)) {
ServletOutputStream out = response.getOutputStream();
out.flush();
// response.flushBuffer();
out.close();
} else {
// prepare response
response.setCharacterEncoding("UTF-8");
String contentType = rootElement.getProperty(StructrApp.key(Page.class, "contentType"));
if (contentType == null) {
// Default
contentType = "text/html;charset=UTF-8";
}
if (contentType.equals("text/html")) {
contentType = contentType.concat(";charset=UTF-8");
}
response.setContentType(contentType);
setCustomResponseHeaders(response);
final boolean createsRawData = rootElement.getProperty(StructrApp.key(Page.class, "pageCreatesRawData"));
// async or not?
if (isAsync && !createsRawData) {
final AsyncContext async = request.startAsync();
final ServletOutputStream out = async.getResponse().getOutputStream();
final AtomicBoolean finished = new AtomicBoolean(false);
final DOMNode rootNode = rootElement;
threadPool.submit(new Runnable() {
@Override
public void run() {
try (final Tx tx = app.tx()) {
// render
rootNode.render(renderContext, 0);
finished.set(true);
tx.success();
} catch (Throwable t) {
t.printStackTrace();
logger.warn("Error while rendering page {}: {}", rootNode.getName(), t.getMessage());
try {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
finished.set(true);
} catch (IOException ex) {
logger.warn("", ex);
}
}
}
});
// start output write listener
out.setWriteListener(new WriteListener() {
@Override
public void onWritePossible() throws IOException {
try {
final Queue<String> queue = renderContext.getBuffer().getQueue();
while (out.isReady()) {
String buffer = null;
synchronized (queue) {
buffer = queue.poll();
}
if (buffer != null) {
out.print(buffer);
} else {
if (finished.get()) {
async.complete();
// prevent this block from being called again
break;
}
Thread.sleep(1);
}
}
} catch (Throwable t) {
logger.warn("", t);
}
}
@Override
public void onError(Throwable t) {
logger.warn("", t);
}
});
} else {
final StringRenderBuffer buffer = new StringRenderBuffer();
renderContext.setBuffer(buffer);
// render
rootElement.render(renderContext, 0);
try {
response.getOutputStream().write(buffer.getBuffer().toString().getBytes("utf-8"));
response.getOutputStream().flush();
response.getOutputStream().close();
} catch (IOException ioex) {
logger.warn("", ioex);
}
}
}
}
tx.success();
} catch (FrameworkException fex) {
logger.error("Exception while processing request: {}", fex.getMessage());
}
} catch (FrameworkException fex) {
logger.error("Exception while processing request: {}", fex.getMessage());
UiAuthenticator.writeFrameworkException(response, fex);
} catch (IOException ioex) {
logger.error("Exception while processing request: {}", ioex.getMessage());
UiAuthenticator.writeInternalServerError(response);
}
}
Aggregations