use of com.helger.photon.security.user.IUser in project phoss-smp by phax.
the class SMPUserManagerPhoton method validateUserCredentials.
/**
* Check if the provided credentials are valid. This checks if the user
* exists, if it is not deleted, if the password matches and if the user is
* not disabled. If valid, the resolved user is returned.
*
* @param aCredentials
* The credentials to check. May not be <code>null</code>.
* @return <code>null</code> if something does wrong, the user on success
* only.
* @throws SMPUnknownUserException
* if the user does not exist or if the user is marked as deleted.
* @throws SMPUnauthorizedException
* If the password is invalid or if the user is marked as disabled
*/
@Nonnull
public static IUser validateUserCredentials(@Nonnull final BasicAuthClientCredentials aCredentials) throws SMPUnknownUserException, SMPUnauthorizedException {
final IUserManager aUserMgr = PhotonSecurityManager.getUserMgr();
final IUser aUser = aUserMgr.getUserOfLoginName(aCredentials.getUserName());
if (aUser == null || aUser.isDeleted()) {
// Deleted users are handled like non-existing users
LOGGER.warn("Invalid login name provided: '" + aCredentials.getUserName() + "'");
throw new SMPUnknownUserException(aCredentials.getUserName());
}
if (!aUserMgr.areUserIDAndPasswordValid(aUser.getID(), aCredentials.getPassword())) {
LOGGER.warn("Invalid password provided for '" + aCredentials.getUserName() + "'");
throw new SMPUnauthorizedException("Username and/or password are invalid!");
}
if (aUser.isDisabled()) {
LOGGER.warn("User '" + aCredentials.getUserName() + "' is disabled");
throw new SMPUnauthorizedException("User is disabled!");
}
return aUser;
}
use of com.helger.photon.security.user.IUser in project phoss-smp by phax.
the class APIExecutorExportByOwnerXMLVer1 method invokeAPI.
public void invokeAPI(@Nonnull final IAPIDescriptor aAPIDescriptor, @Nonnull @Nonempty final String sPath, @Nonnull final Map<String, String> aPathVariables, @Nonnull final IRequestWebScopeWithoutResponse aRequestScope, @Nonnull final UnifiedResponse aUnifiedResponse) throws Exception {
final String sPathUserLoginName = aPathVariables.get(SMPRestFilter.PARAM_USER_ID);
final String sLogPrefix = "[REST API Export-ByOwner-XML-V1] ";
LOGGER.info(sLogPrefix + "Starting Export for all of owner '" + sPathUserLoginName + "'");
// Only authenticated user may do so
final BasicAuthClientCredentials aBasicAuth = getMandatoryAuth(aRequestScope.headers());
final IUser aUser = SMPUserManagerPhoton.validateUserCredentials(aBasicAuth);
// Start action after authentication
final ISMPSettingsManager aSettingsMgr = SMPMetaManager.getSettingsMgr();
final ISMPServiceGroupManager aServiceGroupMgr = SMPMetaManager.getServiceGroupMgr();
final ISMPServerAPIDataProvider aDataProvider = new SMPRestDataProvider(aRequestScope, null);
if (!aBasicAuth.getUserName().equals(sPathUserLoginName)) {
throw new SMPUnauthorizedException("URL user '" + sPathUserLoginName + "' does not match HTTP Basic Auth user name '" + aBasicAuth.getUserName() + "'", aDataProvider.getCurrentURI());
}
// Now get all relevant service groups
final ICommonsList<ISMPServiceGroup> aAllServiceGroups = aServiceGroupMgr.getAllSMPServiceGroupsOfOwner(aUser.getID());
final boolean bIncludeBusinessCards = aRequestScope.params().getAsBoolean(PARAM_INCLUDE_BUSINESS_CARDS, aSettingsMgr.getSettings().isDirectoryIntegrationEnabled());
final IMicroDocument aDoc = ServiceGroupExport.createExportDataXMLVer10(aAllServiceGroups, bIncludeBusinessCards);
LOGGER.info(sLogPrefix + "Finished creating Export data");
// Build the XML response
final IXMLWriterSettings aXWS = new XMLWriterSettings();
aUnifiedResponse.setContentAndCharset(MicroWriter.getNodeAsString(aDoc, aXWS), aXWS.getCharset()).setMimeType(new MimeType(CMimeType.APPLICATION_XML).addParameter(CMimeType.PARAMETER_NAME_CHARSET, aXWS.getCharset().name())).disableCaching();
}
use of com.helger.photon.security.user.IUser in project phoss-smp by phax.
the class APIExecutorImportXMLVer1 method invokeAPI.
public void invokeAPI(@Nonnull final IAPIDescriptor aAPIDescriptor, @Nonnull @Nonempty final String sPath, @Nonnull final Map<String, String> aPathVariables, @Nonnull final IRequestWebScopeWithoutResponse aRequestScope, @Nonnull final UnifiedResponse aUnifiedResponse) throws Exception {
final ISMPServerAPIDataProvider aDataProvider = new SMPRestDataProvider(aRequestScope, null);
// Is the writable API disabled?
if (SMPMetaManager.getSettings().isRESTWritableAPIDisabled()) {
throw new SMPPreconditionFailedException("The writable REST API is disabled. importServiceGroups will not be executed", aDataProvider.getCurrentURI());
}
final String sLogPrefix = "[REST API Import-XML-V1] ";
final String sPathUserLoginName = aPathVariables.get(SMPRestFilter.PARAM_USER_ID);
LOGGER.info(sLogPrefix + "Starting Import");
// Only authenticated user may do so
final BasicAuthClientCredentials aBasicAuth = getMandatoryAuth(aRequestScope.headers());
SMPUserManagerPhoton.validateUserCredentials(aBasicAuth);
// Start action after authentication
final ISMPServiceGroupManager aServiceGroupMgr = SMPMetaManager.getServiceGroupMgr();
final ISMPBusinessCardManager aBusinessCardMgr = SMPMetaManager.getBusinessCardMgr();
final IUserManager aUserMgr = PhotonSecurityManager.getUserMgr();
final ICommonsSet<String> aAllServiceGroupIDs = aServiceGroupMgr.getAllSMPServiceGroupIDs();
final ICommonsSet<String> aAllBusinessCardIDs = aBusinessCardMgr.getAllSMPBusinessCardIDs();
// Try to use ID or login name
IUser aDefaultOwner = aUserMgr.getUserOfID(sPathUserLoginName);
if (aDefaultOwner == null)
aDefaultOwner = aUserMgr.getUserOfLoginName(sPathUserLoginName);
if (aDefaultOwner == null || aDefaultOwner.isDeleted()) {
// Setting the owner to a disabled user might make sense
throw new SMPBadRequestException(sLogPrefix + "The user ID or login name '" + sPathUserLoginName + "' does not exist", aDataProvider.getCurrentURI());
}
LOGGER.info(sLogPrefix + "Using '" + aDefaultOwner.getID() + "' / '" + aDefaultOwner.getLoginName() + "' as the default owner");
final boolean bOverwriteExisting = aRequestScope.params().getAsBoolean(PARAM_OVERVWRITE_EXISTING, DEFAULT_OVERWRITE_EXISTING);
final byte[] aPayload = StreamHelper.getAllBytes(aRequestScope.getRequest().getInputStream());
final IMicroDocument aDoc = MicroReader.readMicroXML(aPayload);
if (aDoc == null || aDoc.getDocumentElement() == null) {
// Cannot parse
throw new SMPBadRequestException("Failed to parse XML payload", aDataProvider.getCurrentURI());
}
final String sVersion = aDoc.getDocumentElement().getAttributeValue(CSMPExchange.ATTR_VERSION);
if (!CSMPExchange.VERSION_10.equals(sVersion)) {
throw new SMPBadRequestException("The provided payload is not an XML file version 1.0", aDataProvider.getCurrentURI());
}
// Version 1.0
LOGGER.info(sLogPrefix + "The provided payload is an XML file version 1.0");
final ZonedDateTime aQueryDT = PDTFactory.getCurrentZonedDateTimeUTC();
final StopWatch aSW = StopWatch.createdStarted();
// Start the import
final ICommonsList<ImportActionItem> aActionList = new CommonsArrayList<>();
final ImportSummary aImportSummary = new ImportSummary();
ServiceGroupImport.importXMLVer10(aDoc.getDocumentElement(), bOverwriteExisting, aDefaultOwner, aAllServiceGroupIDs, aAllBusinessCardIDs, aActionList, aImportSummary);
aSW.stop();
LOGGER.info(sLogPrefix + "Finished import after " + aSW.getMillis() + " milliseconds");
// Everything added to the action list is already logged
final boolean bResponseAsXML = true;
if (bResponseAsXML) {
// Create XML version
final IMicroDocument aResponseDoc = new MicroDocument();
final IMicroElement eRoot = aResponseDoc.appendElement("importResult");
eRoot.setAttribute("version", "1");
eRoot.setAttribute("importStartDateTime", PDTWebDateHelper.getAsStringXSD(aQueryDT));
final IMicroElement eSettings = eRoot.appendElement("settings");
eSettings.setAttribute("overwriteExisting", bOverwriteExisting);
eSettings.setAttribute("defaultOwnerID", aDefaultOwner.getID());
eSettings.setAttribute("defaultOwnerLoginName", aDefaultOwner.getLoginName());
final ICommonsMap<String, MutableInt> aErrorLevelCount = new CommonsTreeMap<>();
for (final ImportActionItem aAction : aActionList) {
eRoot.appendChild(aAction.getAsMicroElement("action"));
aErrorLevelCount.computeIfAbsent(aAction.getErrorLevelName(), k -> new MutableInt(0)).inc();
}
{
final IMicroElement eSummary = eRoot.appendElement("summary");
eSummary.setAttribute("durationMillis", aSW.getMillis());
for (final Map.Entry<String, MutableInt> aEntry : aErrorLevelCount.entrySet()) eSummary.appendElement("errorlevel").setAttribute("id", aEntry.getKey()).setAttribute("count", aEntry.getValue().intValue());
aImportSummary.appendTo(eSummary);
}
final XMLWriterSettings aXWS = new XMLWriterSettings().setIndent(EXMLSerializeIndent.INDENT_AND_ALIGN);
aUnifiedResponse.setContentAndCharset(MicroWriter.getNodeAsString(aResponseDoc, aXWS), aXWS.getCharset()).setMimeType(new MimeType(CMimeType.APPLICATION_XML).addParameter(CMimeType.PARAMETER_NAME_CHARSET, aXWS.getCharset().name()));
} else {
// Create JSON version
final IJsonObject aJson = new JsonObject();
aJson.add("version", "1");
aJson.add("importStartDateTime", DateTimeFormatter.ISO_ZONED_DATE_TIME.format(aQueryDT));
aJson.addJson("settings", new JsonObject().add("overwriteExisting", bOverwriteExisting).add("defaultOwnerID", aDefaultOwner.getID()).add("defaultOwnerLoginName", aDefaultOwner.getLoginName()));
final IJsonArray aActions = new JsonArray();
final ICommonsMap<String, MutableInt> aLevelCount = new CommonsTreeMap<>();
for (final ImportActionItem aAction : aActionList) {
aActions.add(aAction.getAsJsonObject());
aLevelCount.computeIfAbsent(aAction.getErrorLevelName(), k -> new MutableInt(0)).inc();
}
aJson.addJson("actions", aActions);
{
final IJsonObject aSummary = new JsonObject();
aSummary.add("durationMillis", aSW.getMillis());
final IJsonArray aLevels = new JsonArray();
for (final Map.Entry<String, MutableInt> aEntry : aLevelCount.entrySet()) aLevels.add(new JsonObject().add("id", aEntry.getKey()).add("count", aEntry.getValue().intValue()));
aSummary.addJson("errorlevels", aLevels);
aImportSummary.appendTo(aSummary);
aJson.addJson("summary", aSummary);
}
final String sRet = new JsonWriter(JsonWriterSettings.DEFAULT_SETTINGS_FORMATTED).writeAsString(aJson);
aUnifiedResponse.setContentAndCharset(sRet, StandardCharsets.UTF_8).setMimeType(CMimeType.APPLICATION_JSON);
}
aUnifiedResponse.disableCaching();
}
use of com.helger.photon.security.user.IUser in project phoss-smp by phax.
the class APIExecutorMigrationInboundFromPathPut method migrationInbound.
public static void migrationInbound(@Nonnull final String sServiceGroupID, @Nonnull final String sMigrationKey, @Nonnull final String sLogPrefix, @Nonnull final IRequestWebScopeWithoutResponse aRequestScope, @Nonnull final UnifiedResponse aUnifiedResponse) throws SMPServerException, GeneralSecurityException {
LOGGER.info(sLogPrefix + "Starting inbound migration for Service Group ID '" + sServiceGroupID + "' and migration key '" + sMigrationKey + "'");
// Only authenticated user may do so
final BasicAuthClientCredentials aBasicAuth = getMandatoryAuth(aRequestScope.headers());
final IUser aOwningUser = SMPUserManagerPhoton.validateUserCredentials(aBasicAuth);
final ISMPServerAPIDataProvider aDataProvider = new SMPRestDataProvider(aRequestScope, sServiceGroupID);
final ISMPSettings aSettings = SMPMetaManager.getSettings();
final ISMLInfo aSMLInfo = aSettings.getSMLInfo();
final IIdentifierFactory aIdentifierFactory = SMPMetaManager.getIdentifierFactory();
final ISMPServiceGroupManager aServiceGroupMgr = SMPMetaManager.getServiceGroupMgr();
final ISMPParticipantMigrationManager aParticipantMigrationMgr = SMPMetaManager.getParticipantMigrationMgr();
if (aSMLInfo == null) {
throw new SMPPreconditionFailedException("Currently no SML is available. Please select it in the UI at the 'SMP Settings' page", aDataProvider.getCurrentURI());
}
if (!aSettings.isSMLEnabled()) {
throw new SMPPreconditionFailedException("SML Connection is not enabled hence no participant can be migrated", aDataProvider.getCurrentURI());
}
final IParticipantIdentifier aParticipantID = aIdentifierFactory.parseParticipantIdentifier(sServiceGroupID);
if (aParticipantID == null) {
// Invalid identifier
throw SMPBadRequestException.failedToParseSG(sServiceGroupID, aDataProvider.getCurrentURI());
}
// Check that service group does not exist yet
if (aServiceGroupMgr.containsSMPServiceGroupWithID(aParticipantID)) {
throw new SMPBadRequestException("The Service Group '" + sServiceGroupID + "' already exists.", aDataProvider.getCurrentURI());
}
if (false) {
// valid
if (aParticipantMigrationMgr.containsInboundMigration(aParticipantID)) {
throw new SMPBadRequestException("The inbound migration of the Service Group '" + sServiceGroupID + "' is already contained.", aDataProvider.getCurrentURI());
}
}
// create the Service Group locally
try {
final ManageParticipantIdentifierServiceCaller aCaller = new ManageParticipantIdentifierServiceCaller(aSettings.getSMLInfo());
aCaller.setSSLSocketFactory(SMPKeyManager.getInstance().createSSLContext().getSocketFactory());
// SML call
aCaller.migrate(aParticipantID, sMigrationKey, SMPServerConfiguration.getSMLSMPID());
LOGGER.info(sLogPrefix + "Successfully migrated '" + aParticipantID.getURIEncoded() + "' in the SML to this SMP using migration key '" + sMigrationKey + "'");
} catch (final BadRequestFault | InternalErrorFault | NotFoundFault | UnauthorizedFault | ClientTransportException ex) {
throw new SMPSMLException("Failed to confirm the migration for participant '" + aParticipantID.getURIEncoded() + "' in SML, hence the migration failed." + " Please check the participant identifier and the migration key.", ex);
}
// Now create the service group locally (it was already checked that the
// PID is available on this SMP)
ISMPServiceGroup aSG = null;
Exception aCaughtEx = null;
try {
// Do not allow any Extension here
// Do NOT create in SMK/SML
aSG = aServiceGroupMgr.createSMPServiceGroup(aOwningUser.getID(), aParticipantID, (String) null, false);
} catch (final Exception ex) {
aCaughtEx = ex;
}
if (aSG != null) {
LOGGER.info(sLogPrefix + "The new SMP Service Group for participant '" + aParticipantID.getURIEncoded() + "' was successfully created.");
} else {
// No exception here
LOGGER.error(sLogPrefix + "Error creating the new SMP Service Group for participant '" + aParticipantID.getURIEncoded() + "'.", aCaughtEx);
}
// Remember internally
final ISMPParticipantMigration aMigration = aParticipantMigrationMgr.createInboundParticipantMigration(aParticipantID, sMigrationKey);
if (aMigration != null) {
LOGGER.info(sLogPrefix + "The participant migration for '" + aParticipantID.getURIEncoded() + "' with migration key '" + sMigrationKey + "' was successfully performed. Please inform the source SMP that the migration was successful.");
} else {
// No exception here
LOGGER.error(sLogPrefix + "Failed to store the participant migration for '" + aParticipantID.getURIEncoded() + "'.");
}
final IMicroDocument aResponseDoc = new MicroDocument();
final IMicroElement eRoot = aResponseDoc.appendElement("migrationInboundResponse");
eRoot.setAttribute("success", aSG != null && aMigration != null);
eRoot.setAttribute("serviceGroupCreated", aSG != null);
eRoot.setAttribute("migrationCreated", aMigration != null);
final XMLWriterSettings aXWS = new XMLWriterSettings().setIndent(EXMLSerializeIndent.INDENT_AND_ALIGN);
aUnifiedResponse.setContentAndCharset(MicroWriter.getNodeAsString(aResponseDoc, aXWS), aXWS.getCharset()).setMimeType(new MimeType(CMimeType.APPLICATION_XML).addParameter(CMimeType.PARAMETER_NAME_CHARSET, aXWS.getCharset().name())).disableCaching();
}
use of com.helger.photon.security.user.IUser in project peppol-practical by phax.
the class CommentUI method getCommentList.
@Nonnull
public static IHCNode getCommentList(@Nonnull final ILayoutExecutionContext aLEC, @Nonnull final ITypedObject<String> aObject, @Nonnull final CommentAction aCommentAction, @Nullable final CommentFormErrors aFormErrors, @Nullable final IHCNode aMessageBox, final boolean bShowCreateComments) {
ValueEnforcer.notNull(aLEC, "LEC");
ValueEnforcer.notNull(aObject, "Object");
ValueEnforcer.notNull(aCommentAction, "CommentAction");
final Locale aDisplayLocale = aLEC.getDisplayLocale();
final IRequestWebScopeWithoutResponse aRequestScope = aLEC.getRequestScope();
final HCDiv ret = new HCDiv();
final String sResultDivID = ret.ensureID().getID();
final boolean bUserCanCreateComments = CommentSecurity.canCurrentUserPostComments();
final boolean bIsAdmin = aLEC.isLoggedInUserAdministrator();
// Get all existing comments
final List<ICommentThread> aComments = CommentThreadManager.getInstance().getAllCommentThreadsOfObject(aObject);
if (CollectionHelper.isNotEmpty(aComments)) {
final IUserManager aUserMgr = PhotonSecurityManager.getUserMgr();
final boolean bIsCommentModerator = CommentSecurity.isCurrentUserCommentModerator();
// Container for all threads
final HCDiv aAllThreadsContainer = new HCDiv().addClass(CCommentCSS.CSS_CLASS_COMMENT_CONTAINER);
for (final ICommentThread aCommentThread : CollectionHelper.getSorted(aComments, Comparator.comparing(ICommentThread::getInitialCommentCreationDateTime))) {
// Container for this thread
final HCDiv aThreadContainer = new HCDiv();
aThreadContainer.addClass(CCommentCSS.CSS_CLASS_COMMENT_THREAD);
final NonBlockingStack<AbstractHCDiv<?>> aStack = new NonBlockingStack<>();
aStack.push(aThreadContainer);
aCommentThread.iterateAllComments(new ICommentIterationCallback() {
public void onCommentStart(final int nLevel, @Nullable final IComment aParentComment, @Nonnull final IComment aComment) {
// Show only approved comments
final boolean bIsApproved = aComment.getState().isApproved();
if (bIsApproved || bIsCommentModerator) {
// Get author name and determine if it is a registered user
boolean bRegisteredUser = false;
String sAuthor = null;
if (StringHelper.hasText(aComment.getUserID())) {
final IUser aUser = aUserMgr.getUserOfID(aComment.getUserID());
if (aUser != null) {
sAuthor = aUser.getDisplayName();
bRegisteredUser = true;
}
}
if (sAuthor == null)
sAuthor = aComment.getCreatorName();
// Fill panel header
final BootstrapCard aCommentPanel = new BootstrapCard();
final BootstrapCardHeader aHeader = aCommentPanel.createAndAddHeader();
final BootstrapCardBody aBody = aCommentPanel.createAndAddBody();
if (!bIsApproved)
aHeader.addClass(CBootstrapCSS.BG_DANGER);
// Is comment deleted?
if (aComment.isDeleted())
aHeader.addChild(new HCStrong().addChild(ECommentText.MSG_IS_DELETED.getDisplayText(aDisplayLocale)));
// Creation date
aHeader.addChild(new HCSpan().addChild(PDTToString.getAsString(aComment.getCreationDateTime(), aDisplayLocale)).addClass(CCommentCSS.CSS_CLASS_COMMENT_CREATIONDT));
// Author
aHeader.addChild(ECommentText.MSG_BY.getDisplayText(aDisplayLocale));
final HCSpan aAuthor = new HCSpan().addChild(sAuthor).addClass(CCommentCSS.CSS_CLASS_COMMENT_AUTHOR);
if (bRegisteredUser)
aAuthor.addClass(CCommentCSS.CSS_CLASS_COMMENT_REGISTERED_USER);
if (bIsAdmin)
aAuthor.addChild(bRegisteredUser ? " [registered]" : " [not-registered]");
aHeader.addChild(aAuthor);
// Title
if (StringHelper.hasText(aComment.getTitle())) {
aHeader.addChild(ECommentText.MSG_SEPARATOR_AUTHOR_TITLE.getDisplayText(aDisplayLocale));
aHeader.addChild(new HCSpan().addChild(aComment.getTitle()).addClass(CCommentCSS.CSS_CLASS_COMMENT_TITLE));
}
// Toolbar
final HCSpan aCommentToolbar = new HCSpan().addClass(CCommentCSS.CSS_CLASS_COMMENT_TOOLBAR);
HCDiv aCommentResponseContainer = null;
// Respond to a comment - at maximum 6 levels
if (bShowCreateComments && bUserCanCreateComments && !aComment.isDeleted() && nLevel < 6) {
aCommentResponseContainer = new HCDiv();
final BootstrapButton aResponseButton = new BootstrapButton(EBootstrapButtonSize.SMALL).setIcon(EDefaultIcon.ADD);
aCommentToolbar.addChild(aResponseButton);
aCommentToolbar.addChild(new BootstrapTooltip(aResponseButton).setTitle(ECommentText.TOOLTIP_RESPONSE.getDisplayText(aDisplayLocale)));
if (aCommentAction.isMatching(ECommentAction.ADD_COMMENT, aCommentThread, aComment) && aFormErrors != null && aFormErrors.isReplyTo(aCommentThread, aComment)) {
// Upon adding a response
if (aMessageBox == null || !aFormErrors.isEmpty()) {
// Show the input form again
aCommentResponseContainer.addChild(getCreateComment(aLEC, sResultDivID, aObject, aCommentThread, aComment, aFormErrors, aMessageBox));
} else {
// Show the success or error message
aBody.addChild(aMessageBox);
}
} else {
// Add the JS to show the input form
final JSAnonymousFunction aOnSuccess = new JSAnonymousFunction();
final JSVar aJSData = aOnSuccess.param("data");
aOnSuccess.body().add(JQuery.idRef(aCommentResponseContainer).empty().append(aJSData.ref(PhotonUnifiedResponse.HtmlHelper.PROPERTY_HTML)));
final JQueryInvocation aResponseAction = new JQueryAjaxBuilder().url(CAjax.COMMENT_SHOW_INPUT.getInvocationURL(aRequestScope)).data(new JSAssocArray().add(AjaxExecutorCommentShowInput.PARAM_OBJECT_TYPE, aObject.getObjectType().getName()).add(AjaxExecutorCommentShowInput.PARAM_OBJECT_ID, aObject.getID()).add(AjaxExecutorCommentShowInput.PARAM_COMMENT_THREAD_ID, aCommentThread.getID()).add(AjaxExecutorCommentShowInput.PARAM_COMMENT_ID, aComment.getID()).add(AjaxExecutorCommentShowInput.PARAM_RESULT_DIV_ID, sResultDivID)).success(JSJQueryHelper.jqueryAjaxSuccessHandler(aOnSuccess, null)).build();
aResponseButton.setOnClick(aResponseAction);
}
}
if (bIsCommentModerator) {
if (aCommentAction.isMatching(ECommentAction.DELETE_COMMENT, aCommentThread, aComment))
aBody.addChild(aMessageBox);
// Can the comment be deleted?
if (!aComment.isDeleted()) {
final BootstrapButton aDeleteButton = new BootstrapButton(EBootstrapButtonSize.SMALL).setIcon(EDefaultIcon.DELETE);
aCommentToolbar.addChild(aDeleteButton);
aCommentToolbar.addChild(new BootstrapTooltip(aDeleteButton).setTitle(ECommentText.TOOLTIP_DELETE.getDisplayText(aDisplayLocale)));
final JSAnonymousFunction aOnSuccess = new JSAnonymousFunction();
final JSVar aJSData = aOnSuccess.param("data");
aOnSuccess.body().add(JQuery.idRef(sResultDivID).replaceWith(aJSData.ref(PhotonUnifiedResponse.HtmlHelper.PROPERTY_HTML)));
final JQueryInvocation aDeleteAction = new JQueryAjaxBuilder().url(CAjax.COMMENT_DELETE.getInvocationURL(aRequestScope)).data(new JSAssocArray().add(AjaxExecutorCommentDelete.PARAM_OBJECT_TYPE, aObject.getObjectType().getName()).add(AjaxExecutorCommentDelete.PARAM_OBJECT_ID, aObject.getID()).add(AjaxExecutorCommentDelete.PARAM_COMMENT_THREAD_ID, aCommentThread.getID()).add(AjaxExecutorCommentDelete.PARAM_COMMENT_ID, aComment.getID())).success(JSJQueryHelper.jqueryAjaxSuccessHandler(aOnSuccess, null)).build();
aDeleteButton.setOnClick(aDeleteAction);
}
// Show source host and further info
aCommentToolbar.addChild(BootstrapSimpleTooltip.createSimpleTooltip(ECommentText.TOOLTIP_HOST.getDisplayTextWithArgs(aDisplayLocale, aComment.getHost())));
}
if (aCommentToolbar.hasChildren())
aHeader.addChild(aCommentToolbar);
// Last modification
if (aComment.getLastModificationDateTime() != null) {
final String sLastModDT = PDTToString.getAsString(aComment.getLastModificationDateTime(), aDisplayLocale);
final String sLastModText = aComment.getEditCount() > 0 ? ECommentText.MSG_EDITED_AND_LAST_MODIFICATION.getDisplayTextWithArgs(aDisplayLocale, Integer.valueOf(aComment.getEditCount()), sLastModDT) : ECommentText.MSG_LAST_MODIFICATION.getDisplayTextWithArgs(aDisplayLocale, sLastModDT);
aHeader.addChild(new HCDiv().addChild(sLastModText).addClass(CCommentCSS.CSS_CLASS_COMMENT_LAST_MODIFICATION));
}
// Show the main comment text
aBody.addClass(CCommentCSS.CSS_CLASS_SINGLE_COMMENT);
// Always put the text as the first part of the body
aBody.addChildAt(0, new HCDiv().addChildren(HCExtHelper.nl2brList(aComment.getText())).addClass(CCommentCSS.CSS_CLASS_COMMENT_TEXT));
// the dummy container for new comment form
aBody.addChild(aCommentResponseContainer);
aStack.peek().addChild(aCommentPanel);
aStack.push(aBody);
} else {
// Don't display - push the previous item
aStack.push(aStack.peek());
}
}
public void onCommentEnd(final int nLevel, @Nullable final IComment aParentComment, @Nonnull final IComment aComment) {
aStack.pop();
}
});
// Show only thread panels which contain at least one comment
if (aThreadContainer.hasChildren())
aAllThreadsContainer.addChild(aThreadContainer);
}
ret.addChild(aAllThreadsContainer);
}
if (bShowCreateComments) {
// Create comment only for logged in users
if (bUserCanCreateComments) {
// Add "create comment" button
final boolean bIsForCreateThread = aCommentAction.isMatching(ECommentAction.CREATE_THREAD);
ret.addChild(getCreateComment(aLEC, sResultDivID, aObject, null, null, bIsForCreateThread ? aFormErrors : null, bIsForCreateThread ? aMessageBox : null));
} else
ret.addChild(new BootstrapBadge(EBootstrapBadgeType.INFO).addChild(ECommentText.MSG_LOGIN_TO_COMMENT.getDisplayText(aDisplayLocale)));
}
return ret;
}
Aggregations