diff --git a/bower.json b/bower.json index c1b8d78f6..f21ad1cf5 100644 --- a/bower.json +++ b/bower.json @@ -11,6 +11,7 @@ "highlightjs": "8.3.0", "bootbox": "4.3.0", "bootstrap-tagsinput": "0.4.2", + "bootstrap3-typeahead": "3.1.1", "bootstrap-fileinput": "4.1.6", "jquery-file-upload": "9.8.1", "teambox.free-file-icons": "teambox/Free-file-icons", diff --git a/pom.xml b/pom.xml index 236b54394..98e112549 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.support-project knowledge war - 0.5.2 + 0.5.3 webapp for knowledge https://support-project.org/ @@ -16,7 +16,7 @@ org.support-project web - 0.5.2 + 0.5.3 @@ -78,7 +78,13 @@ org.apache.tika tika-parsers - 1.6 + 1.9 + + + org.ow2.asm + asm-debug-all + + @@ -98,6 +104,12 @@ diffutils 1.2.1 + + + org.pegdown + pegdown + 1.5.0 + diff --git a/src/main/java/org/support/project/knowledge/bat/AbstractBat.java b/src/main/java/org/support/project/knowledge/bat/AbstractBat.java index ef7f635e4..02c3f3b08 100644 --- a/src/main/java/org/support/project/knowledge/bat/AbstractBat.java +++ b/src/main/java/org/support/project/knowledge/bat/AbstractBat.java @@ -1,8 +1,35 @@ package org.support.project.knowledge.bat; +import org.apache.log4j.FileAppender; +import org.apache.log4j.Logger; +import org.support.project.common.log.Log; +import org.support.project.common.log.LogFactory; +import org.support.project.common.util.PropertyUtil; +import org.support.project.knowledge.config.AppConfig; +import org.support.project.knowledge.config.SystemConfig; import org.support.project.web.logic.DBConnenctionLogic; public abstract class AbstractBat { + /** ログ */ + private static Log LOG = LogFactory.getLog(AbstractBat.class); + + public static void initLogName(String logname) { + Logger log = Logger.getRootLogger(); + FileAppender appendar= (FileAppender) log.getAppender("APP_FILEOUT"); + appendar.setFile(logname); + appendar.activateOptions();//変更の反映 + } + + protected static void configInit(String batName) { + AppConfig.initEnvKey(SystemConfig.KNOWLEDGE_ENV_KEY); + String envValue = System.getenv(SystemConfig.KNOWLEDGE_ENV_KEY); + LOG.info(batName + " is start."); + if (LOG.isDebugEnabled()) { + LOG.debug("Env [" + SystemConfig.KNOWLEDGE_ENV_KEY + "] is [" + envValue + "]."); + LOG.debug("Config :" + PropertyUtil.reflectionToString(AppConfig.get())); + } + } + /** * コネクションの接続先がカスタマイズされていたら、バッチでもカスタマイズ先を参照する */ diff --git a/src/main/java/org/support/project/knowledge/bat/CreateExportDataBat.java b/src/main/java/org/support/project/knowledge/bat/CreateExportDataBat.java index ff9633bb4..07706a10e 100644 --- a/src/main/java/org/support/project/knowledge/bat/CreateExportDataBat.java +++ b/src/main/java/org/support/project/knowledge/bat/CreateExportDataBat.java @@ -8,6 +8,7 @@ import java.util.List; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; +import org.apache.commons.lang.ClassUtils; import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.common.serialize.SerializeUtils; @@ -37,16 +38,18 @@ public class CreateExportDataBat extends AbstractBat { public static final String DATA_DIR = "DataExport"; public static void main(String[] args) throws Exception { - LOG.trace("start"); - AppConfig.initEnvKey("KNOWLEDGE_HOME"); + initLogName("CreateExportDataBat.log"); + configInit(ClassUtils.getShortClassName(CreateExportDataBat.class)); + CreateExportDataBat bat = new CreateExportDataBat(); + bat.dbInit(); bat.start(); } private void start() throws Exception { super.dbInit(); - SystemConfigsEntity entity = SystemConfigsDao.get().selectOnKey(SystemConfig.DATA_EXPORT, AppConfig.SYSTEM_NAME); + SystemConfigsEntity entity = SystemConfigsDao.get().selectOnKey(SystemConfig.DATA_EXPORT, AppConfig.get().getSystemName()); if (entity == null) { send("[Fail] create fail. please try again."); return; diff --git a/src/main/java/org/support/project/knowledge/bat/DataTransferBat.java b/src/main/java/org/support/project/knowledge/bat/DataTransferBat.java index cc5159411..6a9d2405c 100644 --- a/src/main/java/org/support/project/knowledge/bat/DataTransferBat.java +++ b/src/main/java/org/support/project/knowledge/bat/DataTransferBat.java @@ -1,5 +1,6 @@ package org.support.project.knowledge.bat; +import org.apache.commons.lang.ClassUtils; import org.h2.tools.Server; import org.support.project.common.config.ConfigLoader; import org.support.project.common.log.Log; @@ -17,10 +18,11 @@ public class DataTransferBat extends AbstractBat implements Runnable { private boolean serverStarted = false; public static void main(String[] args) throws Exception { - LOG.trace("start"); - AppConfig.initEnvKey("KNOWLEDGE_HOME"); + initLogName("DataTransferBat.log"); + configInit(ClassUtils.getShortClassName(DataTransferBat.class)); DataTransferBat bat = new DataTransferBat(); + bat.dbInit(); bat.start(); } diff --git a/src/main/java/org/support/project/knowledge/bat/FileParseBat.java b/src/main/java/org/support/project/knowledge/bat/FileParseBat.java index dd8837172..8a8061edb 100644 --- a/src/main/java/org/support/project/knowledge/bat/FileParseBat.java +++ b/src/main/java/org/support/project/knowledge/bat/FileParseBat.java @@ -7,6 +7,7 @@ import java.nio.file.StandardCopyOption; import java.util.List; +import org.apache.commons.lang.ClassUtils; import org.apache.tika.mime.MimeType; import org.apache.tika.mime.MimeTypes; import org.support.project.common.config.ConfigLoader; @@ -35,6 +36,7 @@ public class FileParseBat extends AbstractBat { public static final int PARSE_STATUS_WAIT = 0; public static final int PARSE_STATUS_PARSING = 1; + public static final int PARSE_STATUS_ERROR_FINISHED = -100; public static final int PARSE_STATUS_PARSED = 100; public static final int PARSE_STATUS_NO_TARGET = -1; @@ -45,15 +47,16 @@ public class FileParseBat extends AbstractBat { public static final String ID_PREFIX = "FILE-"; public static void main(String[] args) throws Exception { - AppConfig.initEnvKey("KNOWLEDGE_HOME"); + initLogName("FileParseBat.log"); + configInit(ClassUtils.getShortClassName(FileParseBat.class)); FileParseBat bat = new FileParseBat(); bat.dbInit(); bat.start(); + LOG.info("finished"); } private void start() throws Exception { - LOG.info("start"); KnowledgeFilesDao filesDao = KnowledgeFilesDao.get(); IndexLogic indexLogic = IndexLogic.get(); KnowledgesDao knowledgesDao = KnowledgesDao.get(); @@ -68,7 +71,8 @@ private void start() throws Exception { // ナレッジを取得 KnowledgesEntity knowledgesEntity = knowledgesDao.selectOnKey(knowledgeFilesEntity.getKnowledgeId()); if (knowledgesEntity == null) { - // 紐づくナレッジが存在していないのであれば解析はしない + // 紐づくナレッジが存在していないのであれば解析はしない(例えば、一度添付ファイル付きのナレッジを登録後、ナレッジを削除した場合) + // ナレッジに紐づいていないファイルで、かつ更新日が24時間前のものは削除される filesDao.changeStatus(knowledgeFilesEntity.getFileNo(), PARSE_STATUS_NO_TARGET, UPDATE_USER_ID); continue; } @@ -108,33 +112,40 @@ private void start() throws Exception { // パースステータスをパース中(1)に変更(もしパースでエラーが発生しても、次回から対象外になる) filesDao.changeStatus(entity.getFileNo(), PARSE_STATUS_PARSING, UPDATE_USER_ID); - // パースを実行 - Parser parser = ParserFactory.getParser(tmp.getAbsolutePath()); - ParseResult result = parser.parse(tmp); - LOG.info("content text(length): " + result.getText().length()); - - // 全文検索エンジンへ登録 - IndexingValue value = new IndexingValue(); - value.setType(TYPE_FILE); - value.setId(ID_PREFIX + entity.getFileNo()); - value.setTitle(entity.getFileName()); - value.setContents(result.getText()); - value.addUser(entity.getInsertUser()); - if (knowledgesEntity.getPublicFlag() == null - || KnowledgeLogic.PUBLIC_FLAG_PUBLIC == knowledgesEntity.getPublicFlag()) { - value.addUser(KnowledgeLogic.ALL_USER); - } - for (TagsEntity tagsEntity : tagsEntities) { - value.addTag(tagsEntity.getTagId()); + try { + // パースを実行 + Parser parser = ParserFactory.getParser(tmp.getAbsolutePath()); + ParseResult result = parser.parse(tmp); + LOG.info("content text(length): " + result.getText().length()); + + // 全文検索エンジンへ登録 + IndexingValue value = new IndexingValue(); + value.setType(TYPE_FILE); + value.setId(ID_PREFIX + entity.getFileNo()); + value.setTitle(entity.getFileName()); + value.setContents(result.getText()); + value.addUser(entity.getInsertUser()); + if (knowledgesEntity.getPublicFlag() == null + || KnowledgeLogic.PUBLIC_FLAG_PUBLIC == knowledgesEntity.getPublicFlag()) { + value.addUser(KnowledgeLogic.ALL_USER); + } + for (TagsEntity tagsEntity : tagsEntities) { + value.addTag(tagsEntity.getTagId()); + } + value.setCreator(entity.getInsertUser()); + value.setTime(entity.getUpdateDatetime().getTime()); // 更新日時をセットするので、更新日時でソート + indexLogic.save(value); + + // パースステータスをパース完了に変更(もしパースでエラーが発生しても、次回から対象外になる) + filesDao.changeStatus(entity.getFileNo(), PARSE_STATUS_PARSED, UPDATE_USER_ID); + + } catch (Exception e) { + // パースの解析でなんらかのエラー + filesDao.changeStatus(entity.getFileNo(), PARSE_STATUS_ERROR_FINISHED, UPDATE_USER_ID); + LOG.error("File parse error.", e); + throw e; } - value.setCreator(entity.getInsertUser()); - value.setTime(entity.getUpdateDatetime().getTime()); // 更新日時をセットするので、更新日時でソート - indexLogic.save(value); - - // パースステータスをパース完了に変更(もしパースでエラーが発生しても、次回から対象外になる) - filesDao.changeStatus(entity.getFileNo(), PARSE_STATUS_PARSED, UPDATE_USER_ID); - - // 正常に終了すれば、テンポラリを削除 + // 終了すれば、テンポラリを削除 tmp.delete(); LOG.info("deleteed: " + tmp.getAbsolutePath()); } diff --git a/src/main/java/org/support/project/knowledge/bat/KnowledgeFileClearBat.java b/src/main/java/org/support/project/knowledge/bat/KnowledgeFileClearBat.java index d5eee382b..ac7576fea 100644 --- a/src/main/java/org/support/project/knowledge/bat/KnowledgeFileClearBat.java +++ b/src/main/java/org/support/project/knowledge/bat/KnowledgeFileClearBat.java @@ -1,9 +1,17 @@ package org.support.project.knowledge.bat; +import java.util.List; + +import org.apache.commons.lang.ClassUtils; +import org.support.project.common.config.Flag; import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; -import org.support.project.knowledge.config.AppConfig; +import org.support.project.common.util.NumberUtils; import org.support.project.knowledge.dao.KnowledgeFilesDao; +import org.support.project.knowledge.dao.NotifyQueuesDao; +import org.support.project.knowledge.entity.NotifyQueuesEntity; +import org.support.project.web.dao.MailsDao; +import org.support.project.web.entity.MailsEntity; public class KnowledgeFileClearBat extends AbstractBat { @@ -11,12 +19,13 @@ public class KnowledgeFileClearBat extends AbstractBat { private static Log LOG = LogFactory.getLog(KnowledgeFileClearBat.class); public static void main(String[] args) { - LOG.trace("start"); - AppConfig.initEnvKey("KNOWLEDGE_HOME"); + initLogName("KnowledgeFileClearBat.log"); + configInit(ClassUtils.getShortClassName(KnowledgeFileClearBat.class)); KnowledgeFileClearBat bat = new KnowledgeFileClearBat(); bat.dbInit(); bat.start(); + LOG.info("finished"); } private void start() { @@ -25,6 +34,23 @@ private void start() { if (count > 0) { LOG.debug("Knowledge Files deleted. Count: " + count + ""); } + + // メール送信とNotifyのゴミ情報をクリア + List notifyQueuesEntities = NotifyQueuesDao.get().physicalSelectAll(); + for (NotifyQueuesEntity notifyQueuesEntity : notifyQueuesEntities) { + if (Flag.is(notifyQueuesEntity.getDeleteFlag())) { + // 削除フラグはONになっているのに、物理削除していないものは物理削除する(とっておいてもしかたない) + NotifyQueuesDao.get().physicalDelete(notifyQueuesEntity); + } + } + + List mailsEntities = MailsDao.get().physicalSelectAll(); + for (MailsEntity mailsEntity : mailsEntities) { + if (NumberUtils.is(mailsEntity.getStatus(), MailSendBat.MAIL_STATUS_SENDED)) { + // 送信済みになっているものは、削除 + MailsDao.get().physicalDelete(mailsEntity); + } + } } } diff --git a/src/main/java/org/support/project/knowledge/bat/MailSendBat.java b/src/main/java/org/support/project/knowledge/bat/MailSendBat.java index 4b17f9398..0f4f70acf 100644 --- a/src/main/java/org/support/project/knowledge/bat/MailSendBat.java +++ b/src/main/java/org/support/project/knowledge/bat/MailSendBat.java @@ -18,6 +18,7 @@ import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; +import org.apache.commons.lang.ClassUtils; import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.common.util.PasswordUtil; @@ -54,7 +55,8 @@ public class MailSendBat extends AbstractBat { + "@" + "[a-zA-Z0-9][a-zA-Z0-9\\-]*(\\.[a-zA-Z0-9\\-]+)*$"; public static void main(String[] args) throws Exception { - AppConfig.initEnvKey("KNOWLEDGE_HOME"); + initLogName("MailSendBat.log"); + configInit(ClassUtils.getShortClassName(MailSendBat.class)); MailSendBat bat = new MailSendBat(); bat.dbInit(); @@ -75,7 +77,7 @@ public static void main(String[] args) throws Exception { public void start() throws UnsupportedEncodingException, MessagingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { MailConfigsDao mailConfigsDao = MailConfigsDao.get(); - MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(org.support.project.knowledge.config.AppConfig.SYSTEM_NAME); + MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(AppConfig.get().getSystemName()); if (mailConfigsEntity == null) { // メールの設定が登録されていなければ、送信処理は終了 return; @@ -87,6 +89,8 @@ public void start() throws UnsupportedEncodingException, MessagingException, Inv for (MailsEntity mailsEntity : entities) { if (mailsEntity.getToAddress().matches(MAIL_FORMAT)) { mailSend(mailConfigsEntity, mailsEntity); + // 正常に送信できたら、物理削除 + dao.physicalDelete(mailsEntity); } else { mailsEntity.setStatus(MAIL_STATUS_FORMAT_ERROR); dao.save(mailsEntity); diff --git a/src/main/java/org/support/project/knowledge/bat/NotifyMailBat.java b/src/main/java/org/support/project/knowledge/bat/NotifyMailBat.java index dc045889b..291516ac4 100644 --- a/src/main/java/org/support/project/knowledge/bat/NotifyMailBat.java +++ b/src/main/java/org/support/project/knowledge/bat/NotifyMailBat.java @@ -9,6 +9,7 @@ import java.util.Locale; import java.util.UUID; +import org.apache.commons.lang.ClassUtils; import org.support.project.common.config.INT_FLAG; import org.support.project.common.config.LocaleConfigLoader; import org.support.project.common.log.Log; @@ -44,17 +45,22 @@ public class NotifyMailBat extends AbstractBat { /** ログ */ - private static Log LOG = LogFactory.getLog(MailSendBat.class); + private static Log LOG = LogFactory.getLog(NotifyMailBat.class); private static final String MAIL_CONFIG_DIR = "/org/support/project/knowledge/mail/"; private static final DateFormat DAY_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss"); - + + private List sendedCommentKnowledgeIds = new ArrayList<>(); + private List sendedLikeKnowledgeIds = new ArrayList<>(); + public static void main(String[] args) throws Exception { - AppConfig.initEnvKey("KNOWLEDGE_HOME"); + initLogName("NotifyMailBat.log"); + configInit(ClassUtils.getShortClassName(NotifyMailBat.class)); NotifyMailBat bat = new NotifyMailBat(); bat.dbInit(); bat.start(); + LOG.info("finished"); } /** @@ -73,9 +79,10 @@ private void start() { notifyLikeInsert(notifyQueuesEntity); } // 通知のキューから削除 - notifyQueuesDao.delete(notifyQueuesEntity); - //notifyQueuesDao.physicalDelete(notifyQueuesEntity); + //notifyQueuesDao.delete(notifyQueuesEntity); + notifyQueuesDao.physicalDelete(notifyQueuesEntity); // とっておいてもしょうがないので物理削除 } + LOG.info("Notify process finished. count: " + notifyQueuesEntities.size()); } /** @@ -85,7 +92,7 @@ private void start() { */ private String makeURL(KnowledgesEntity knowledge) { SystemConfigsDao dao = SystemConfigsDao.get(); - SystemConfigsEntity config = dao.selectOnKey(SystemConfig.SYSTEM_URL, AppConfig.SYSTEM_NAME); + SystemConfigsEntity config = dao.selectOnKey(SystemConfig.SYSTEM_URL, AppConfig.get().getSystemName()); if (config == null) { return ""; } @@ -111,6 +118,15 @@ private void notifyLikeInsert(NotifyQueuesEntity notifyQueuesEntity) { KnowledgesDao knowledgesDao = KnowledgesDao.get(); KnowledgesEntity knowledge = knowledgesDao.selectOnKey(like.getKnowledgeId()); + if (sendedLikeKnowledgeIds.contains(knowledge.getKnowledgeId())) { + if (LOG.isDebugEnabled()) { + LOG.debug("Knowledge [" + knowledge.getKnowledgeId() + "] "); + } + return; + } else { + sendedLikeKnowledgeIds.add(knowledge.getKnowledgeId()); + } + UsersDao usersDao = UsersDao.get(); UsersEntity likeUser = usersDao.selectOnKey(like.getInsertUser()); @@ -130,9 +146,15 @@ private void notifyLikeInsert(NotifyQueuesEntity notifyQueuesEntity) { private void sendLikeMail(LikesEntity like, KnowledgesEntity knowledge, UsersEntity likeUser, UsersEntity user, MailConfig config) { MailConfigsDao mailConfigsDao = MailConfigsDao.get(); - MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(org.support.project.knowledge.config.AppConfig.SYSTEM_NAME); + MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(AppConfig.get().getSystemName()); if (mailConfigsEntity == null) { // メールの設定が登録されていなければ、送信処理は終了 + LOG.info("mail config is not exists."); + return; + } + if (!StringUtils.isEmailAddress(user.getMailAddress())) { + // 送信先のメールアドレスが不正なので、送信処理は終了 + LOG.warn("mail targget [" + user.getMailAddress() + "] is wrong."); return; } @@ -140,7 +162,7 @@ private void sendLikeMail(LikesEntity like, KnowledgesEntity knowledge, UsersEnt String mailId = idGenu("Notify"); mailsEntity.setMailId(mailId); mailsEntity.setStatus(MailSendBat.MAIL_STATUS_UNSENT); - mailsEntity.setToAddress(user.getUserKey()); + mailsEntity.setToAddress(user.getMailAddress()); mailsEntity.setToName(user.getUserName()); String title = config.getTitle(); @@ -159,6 +181,10 @@ private void sendLikeMail(LikesEntity like, KnowledgesEntity knowledge, UsersEnt contents = contents.replace("{URL}", makeURL(knowledge)); mailsEntity.setContent(contents); + if (LOG.isDebugEnabled()) { + LOG.debug("News email has been registered. [type] Like added. [knowledge]" + knowledge.getKnowledgeId().toString() + + " [target] " + user.getMailAddress()); + } MailsDao.get().insert(mailsEntity); } @@ -172,6 +198,15 @@ private void notifyCommentInsert(NotifyQueuesEntity notifyQueuesEntity) { KnowledgesDao knowledgesDao = KnowledgesDao.get(); KnowledgesEntity knowledge = knowledgesDao.selectOnKey(comment.getKnowledgeId()); + if (sendedCommentKnowledgeIds.contains(knowledge.getKnowledgeId())) { + if (LOG.isDebugEnabled()) { + LOG.debug("Knowledge [" + knowledge.getKnowledgeId() + "] "); + } + return; + } else { + sendedCommentKnowledgeIds.add(knowledge.getKnowledgeId()); + } + UsersDao usersDao = UsersDao.get(); UsersEntity commentUser = usersDao.selectOnKey(comment.getInsertUser()); @@ -239,9 +274,15 @@ private void notifyCommentInsert(NotifyQueuesEntity notifyQueuesEntity) { */ private void sendCommentMail(CommentsEntity comment, KnowledgesEntity knowledge, UsersEntity commentUser, UsersEntity user, MailConfig config) { MailConfigsDao mailConfigsDao = MailConfigsDao.get(); - MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(org.support.project.knowledge.config.AppConfig.SYSTEM_NAME); + MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(AppConfig.get().getSystemName()); if (mailConfigsEntity == null) { // メールの設定が登録されていなければ、送信処理は終了 + LOG.info("mail config is not exists."); + return; + } + if (!StringUtils.isEmailAddress(user.getMailAddress())) { + // 送信先のメールアドレスが不正なので、送信処理は終了 + LOG.warn("mail targget [" + user.getMailAddress() + "] is wrong."); return; } @@ -249,7 +290,7 @@ private void sendCommentMail(CommentsEntity comment, KnowledgesEntity knowledge, String mailId = idGenu("Notify"); mailsEntity.setMailId(mailId); mailsEntity.setStatus(MailSendBat.MAIL_STATUS_UNSENT); - mailsEntity.setToAddress(user.getUserKey()); + mailsEntity.setToAddress(user.getMailAddress()); mailsEntity.setToName(user.getUserName()); String title = config.getTitle(); @@ -269,6 +310,10 @@ private void sendCommentMail(CommentsEntity comment, KnowledgesEntity knowledge, contents = contents.replace("{URL}", makeURL(knowledge)); mailsEntity.setContent(contents); + if (LOG.isDebugEnabled()) { + LOG.debug("News email has been registered. [type] comment added. [knowledge]" + knowledge.getKnowledgeId().toString() + + " [target] " + user.getMailAddress()); + } MailsDao.get().insert(mailsEntity); } @@ -359,9 +404,22 @@ private void notifyPublicKnowledgeUpdate(NotifyQueuesEntity notifyQueuesEntity, * @param users */ private void notifyKnowledgeUpdateToUsers(NotifyQueuesEntity notifyQueuesEntity, KnowledgesEntity knowledge, List users) { + MailConfigsDao mailConfigsDao = MailConfigsDao.get(); + MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(AppConfig.get().getSystemName()); + if (mailConfigsEntity == null) { + // メールの設定が登録されていなければ、送信処理は終了 + LOG.info("mail config is not exists."); + return; + } + for (UsersEntity usersEntity : users) { + if (!StringUtils.isEmailAddress(usersEntity.getMailAddress())) { + // 送信先のメールアドレスが不正なのでこのユーザにはメール送信しない + LOG.warn("mail targget [" + usersEntity.getMailAddress() + "] is wrong."); + continue; + } if (LOG.isTraceEnabled()) { - LOG.trace("[Notify] " + usersEntity.getUserKey()); + LOG.trace("[Notify] " + usersEntity.getMailAddress()); } Locale locale = usersEntity.getLocale(); MailConfig config = null; @@ -384,9 +442,15 @@ private void notifyKnowledgeUpdateToUsers(NotifyQueuesEntity notifyQueuesEntity, */ private void insertNotifyKnowledgeUpdateMailQue(KnowledgesEntity knowledge, UsersEntity usersEntity, MailConfig config) { MailConfigsDao mailConfigsDao = MailConfigsDao.get(); - MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(org.support.project.knowledge.config.AppConfig.SYSTEM_NAME); + MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(AppConfig.get().getSystemName()); if (mailConfigsEntity == null) { // メールの設定が登録されていなければ、送信処理は終了 + LOG.info("mail config is not exists."); + return; + } + if (!StringUtils.isEmailAddress(usersEntity.getMailAddress())) { + // 送信先のメールアドレスが不正なので、送信処理は終了 + LOG.warn("mail targget [" + usersEntity.getMailAddress() + "] is wrong."); return; } @@ -394,7 +458,7 @@ private void insertNotifyKnowledgeUpdateMailQue(KnowledgesEntity knowledge, User String mailId = idGenu("Notify"); mailsEntity.setMailId(mailId); mailsEntity.setStatus(MailSendBat.MAIL_STATUS_UNSENT); - mailsEntity.setToAddress(usersEntity.getUserKey()); + mailsEntity.setToAddress(usersEntity.getMailAddress()); mailsEntity.setToName(usersEntity.getUserName()); String title = config.getTitle(); title = title.replace("{KnowledgeId}", knowledge.getKnowledgeId().toString()); @@ -407,6 +471,11 @@ private void insertNotifyKnowledgeUpdateMailQue(KnowledgesEntity knowledge, User contents = contents.replace("{URL}", makeURL(knowledge)); mailsEntity.setContent(contents); + + if (LOG.isDebugEnabled()) { + LOG.debug("News email has been registered. [type] knowledge update. [knowledge]" + knowledge.getKnowledgeId().toString() + + " [target] " + usersEntity.getMailAddress()); + } MailsDao.get().insert(mailsEntity); } diff --git a/src/main/java/org/support/project/knowledge/bat/ReIndexingBat.java b/src/main/java/org/support/project/knowledge/bat/ReIndexingBat.java index 5ff41a9fa..0b771be01 100644 --- a/src/main/java/org/support/project/knowledge/bat/ReIndexingBat.java +++ b/src/main/java/org/support/project/knowledge/bat/ReIndexingBat.java @@ -2,6 +2,7 @@ import java.util.List; +import org.apache.commons.lang.ClassUtils; import org.support.project.knowledge.config.AppConfig; import org.support.project.knowledge.config.SystemConfig; import org.support.project.knowledge.dao.KnowledgesDao; @@ -14,7 +15,8 @@ public class ReIndexingBat extends AbstractBat { public static void main(String[] args) throws Exception { - AppConfig.initEnvKey("KNOWLEDGE_HOME"); + initLogName("ReIndexingBat.log"); + configInit(ClassUtils.getShortClassName(ReIndexingBat.class)); ReIndexingBat bat = new ReIndexingBat(); bat.dbInit(); //カスタマイズDBが設定されていてばそれを参照 @@ -23,7 +25,7 @@ public static void main(String[] args) throws Exception { private void start() throws Exception { out("start"); - SystemConfigsEntity entity = SystemConfigsDao.get().selectOnKey(SystemConfig.RE_INDEXING, AppConfig.SYSTEM_NAME); + SystemConfigsEntity entity = SystemConfigsDao.get().selectOnKey(SystemConfig.RE_INDEXING, AppConfig.get().getSystemName()); if (entity != null) { String[] values = entity.getConfigValue().split(","); Long start = Long.valueOf(values[0].substring("start=".length())); diff --git a/src/main/java/org/support/project/knowledge/config/AppConfig.java b/src/main/java/org/support/project/knowledge/config/AppConfig.java index 43322613f..845c6ee56 100644 --- a/src/main/java/org/support/project/knowledge/config/AppConfig.java +++ b/src/main/java/org/support/project/knowledge/config/AppConfig.java @@ -1,11 +1,7 @@ package org.support.project.knowledge.config; -import java.util.ArrayList; -import java.util.List; - import org.support.project.common.config.ConfigLoader; import org.support.project.common.util.StringUtils; -import org.support.project.web.bean.LabelValue; public class AppConfig extends org.support.project.web.config.AppConfig { @@ -18,8 +14,6 @@ public static AppConfig get() { } private static AppConfig appConfig = null; - public static final String SYSTEM_NAME = "knowledge"; - private String indexPath; private boolean convIndexPath = false; diff --git a/src/main/java/org/support/project/knowledge/config/SystemConfig.java b/src/main/java/org/support/project/knowledge/config/SystemConfig.java index 46f1ff9c7..5e9177e21 100644 --- a/src/main/java/org/support/project/knowledge/config/SystemConfig.java +++ b/src/main/java/org/support/project/knowledge/config/SystemConfig.java @@ -1,8 +1,7 @@ package org.support.project.knowledge.config; public class SystemConfig { - public static final String ROLE_ADMIN = "admin"; - public static final String ROLE_USER = "user"; + public static final String KNOWLEDGE_ENV_KEY = "KNOWLEDGE_HOME"; /** ユーザ登録のやりかたを判定するシステム設定のラベル */ public static final String USER_ADD_TYPE = "USER_ADD_TYPE"; @@ -30,4 +29,12 @@ public class SystemConfig { /** エクスポートのための設定値 */ public static final String DATA_EXPORT = "DATA_EXPORT"; + /** 「公開」の情報であれば、ログインしなくても参照出来る */ + public static final String SYSTEM_EXPOSE_TYPE = "SYSTEM_EXPOSE_TYPE"; + /** 「公開」の情報であれば、ログインしなくても参照出来る */ + public static final String SYSTEM_EXPOSE_TYPE_OPEN = "OPEN"; + /** 全ての機能は、ログインしないとアクセス出来ない */ + public static final String SYSTEM_EXPOSE_TYPE_CLOSE = "CLOSE"; + + } diff --git a/src/main/java/org/support/project/knowledge/control/Control.java b/src/main/java/org/support/project/knowledge/control/Control.java index 1a368e256..67d5bac71 100644 --- a/src/main/java/org/support/project/knowledge/control/Control.java +++ b/src/main/java/org/support/project/knowledge/control/Control.java @@ -5,14 +5,10 @@ import javax.servlet.http.HttpServletRequest; -import org.owasp.validator.html.AntiSamy; -import org.owasp.validator.html.CleanResults; -import org.owasp.validator.html.Policy; -import org.owasp.validator.html.PolicyException; -import org.owasp.validator.html.ScanException; import org.support.project.common.bean.ValidateError; import org.support.project.common.config.INT_FLAG; import org.support.project.common.config.Resources; +import org.support.project.common.exception.ParseException; import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.common.log.LogLevel; @@ -23,15 +19,13 @@ import org.support.project.knowledge.entity.NotifyConfigsEntity; import org.support.project.web.boundary.ForwardBoundary; import org.support.project.web.common.HttpUtil; -import org.support.project.web.util.JspUtil; +import org.support.project.web.logic.SanitizingLogic; @DI(instance=Instance.Prototype) public abstract class Control extends org.support.project.web.control.Control { /** ログ */ private static Log LOG = LogFactory.getLog(Control.class); - public static final String PATH_ANTISAMY_POLICY = JspUtil.PATH_ANTISAMY_POLICY; - public static final String MSG_INFO = "NOTIFY_MSG_INFO"; public static final String MSG_SUCCESS = "NOTIFY_MSG_SUCCESS"; public static final String MSG_WARN = "NOTIFY_MSG_WARN"; @@ -103,17 +97,8 @@ protected void setResult(String successMsg, List errors, String.. } } - public static String doSamy(String str) throws PolicyException, ScanException { - Policy policy = Policy.getInstance(Control.class.getResourceAsStream(PATH_ANTISAMY_POLICY)); - AntiSamy as = new AntiSamy(); - CleanResults cr = as.scan(str, policy); - String escape = cr.getCleanHTML(); - if (LOG.isDebugEnabled()) { - if (str != null && !str.equals(escape)) { - LOG.debug("escape string\n before:" + str + "\naftter:" + escape); - } - } - return escape; + public static String sanitize(String str) throws ParseException { + return SanitizingLogic.get().sanitize(str); } /* (non-Javadoc) diff --git a/src/main/java/org/support/project/knowledge/control/admin/ConfigControl.java b/src/main/java/org/support/project/knowledge/control/admin/ConfigControl.java index 86a008911..256e1423a 100644 --- a/src/main/java/org/support/project/knowledge/control/admin/ConfigControl.java +++ b/src/main/java/org/support/project/knowledge/control/admin/ConfigControl.java @@ -5,19 +5,25 @@ import org.support.project.common.bean.ValidateError; import org.support.project.common.util.StringUtils; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.config.AppConfig; import org.support.project.knowledge.config.SystemConfig; import org.support.project.knowledge.control.Control; +import org.support.project.knowledge.logic.SystemConfigLogic; import org.support.project.web.annotation.Auth; import org.support.project.web.boundary.Boundary; import org.support.project.web.common.HttpUtil; import org.support.project.web.control.service.Get; import org.support.project.web.control.service.Post; +import org.support.project.web.dao.LdapConfigsDao; import org.support.project.web.dao.MailConfigsDao; import org.support.project.web.dao.SystemConfigsDao; +import org.support.project.web.entity.LdapConfigsEntity; import org.support.project.web.entity.MailConfigsEntity; import org.support.project.web.entity.SystemConfigsEntity; +@DI(instance=Instance.Prototype) public class ConfigControl extends Control { /** @@ -30,20 +36,28 @@ public class ConfigControl extends Control { public Boundary config() { SystemConfigsDao dao = SystemConfigsDao.get(); - SystemConfigsEntity userAddType = dao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + SystemConfigsEntity userAddType = dao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); if (userAddType == null) { - userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); userAddType.setConfigValue(SystemConfig.USER_ADD_TYPE_VALUE_ADMIN); } setAttribute("userAddType", userAddType.getConfigValue()); - SystemConfigsEntity userAddNotify = dao.selectOnKey(SystemConfig.USER_ADD_NOTIFY, AppConfig.SYSTEM_NAME); + SystemConfigsEntity userAddNotify = dao.selectOnKey(SystemConfig.USER_ADD_NOTIFY, AppConfig.get().getSystemName()); if (userAddNotify == null) { - userAddNotify = new SystemConfigsEntity(SystemConfig.USER_ADD_NOTIFY, AppConfig.SYSTEM_NAME); + userAddNotify = new SystemConfigsEntity(SystemConfig.USER_ADD_NOTIFY, AppConfig.get().getSystemName()); userAddNotify.setConfigValue(SystemConfig.USER_ADD_NOTIFY_OFF); } setAttribute("userAddNotify", userAddNotify.getConfigValue()); + LdapConfigsDao ldapConfigsDao = LdapConfigsDao.get(); + LdapConfigsEntity ldapConfigsEntity = ldapConfigsDao.selectOnKey(AppConfig.get().getSystemName()); + if (ldapConfigsEntity == null || ldapConfigsEntity.getAuthType() == null) { + setAttribute("authType", 0); + } else { + setAttribute("authType", ldapConfigsEntity.getAuthType().intValue()); + } + return forward("config.jsp"); } @@ -62,7 +76,7 @@ public Boundary save() { if ((type != null && type.equals(SystemConfig.USER_ADD_TYPE_VALUE_MAIL)) || (notify != null && notify.equals(SystemConfig.USER_ADD_NOTIFY_ON))) { MailConfigsDao mailConfigsDao = MailConfigsDao.get(); - MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(AppConfig.SYSTEM_NAME); + MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(AppConfig.get().getSystemName()); if (mailConfigsEntity == null) { ValidateError error = new ValidateError("knowledge.config.mail.require"); errors.add(error); @@ -74,11 +88,11 @@ public Boundary save() { } SystemConfigsDao dao = SystemConfigsDao.get(); - SystemConfigsEntity userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + SystemConfigsEntity userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); userAddType.setConfigValue(type); dao.save(userAddType); - SystemConfigsEntity userAddNotify = new SystemConfigsEntity(SystemConfig.USER_ADD_NOTIFY, AppConfig.SYSTEM_NAME); + SystemConfigsEntity userAddNotify = new SystemConfigsEntity(SystemConfig.USER_ADD_NOTIFY, AppConfig.get().getSystemName()); userAddNotify.setConfigValue(notify); dao.save(userAddNotify); @@ -97,14 +111,20 @@ public Boundary save() { @Auth(roles = "admin") public Boundary system() { SystemConfigsDao dao = SystemConfigsDao.get(); - SystemConfigsEntity config = dao.selectOnKey(SystemConfig.SYSTEM_URL, AppConfig.SYSTEM_NAME); + SystemConfigsEntity config = dao.selectOnKey(SystemConfig.SYSTEM_URL, AppConfig.get().getSystemName()); if (config == null) { String url = HttpUtil.getContextUrl(getRequest()); - config = new SystemConfigsEntity(SystemConfig.SYSTEM_URL, AppConfig.SYSTEM_NAME); + config = new SystemConfigsEntity(SystemConfig.SYSTEM_URL, AppConfig.get().getSystemName()); config.setConfigValue(url); dao.save(config); } setAttribute("systemurl", config.getConfigValue()); + + config = dao.selectOnKey(SystemConfig.SYSTEM_EXPOSE_TYPE, AppConfig.get().getSystemName()); + if (config != null) { + setAttribute("system_open_type", config.getConfigValue()); + } + return forward("system.jsp"); } @@ -129,10 +149,23 @@ public Boundary save_params() { } SystemConfigsDao dao = SystemConfigsDao.get(); - SystemConfigsEntity config = new SystemConfigsEntity(SystemConfig.SYSTEM_URL, AppConfig.SYSTEM_NAME); + SystemConfigsEntity config = new SystemConfigsEntity(SystemConfig.SYSTEM_URL, AppConfig.get().getSystemName()); config.setConfigValue(systemurl); dao.save(config); + String system_open_type = getParam("system_open_type"); + if (StringUtils.isNotEmpty(system_open_type)) { + config = new SystemConfigsEntity(SystemConfig.SYSTEM_EXPOSE_TYPE, AppConfig.get().getSystemName()); + config.setConfigValue(system_open_type); + dao.save(config); + + if (SystemConfig.SYSTEM_EXPOSE_TYPE_CLOSE.equals(system_open_type)) { + SystemConfigLogic.get().setClose(true); + } else { + SystemConfigLogic.get().setClose(false); + } + } + String successMsg = "message.success.save"; setResult(successMsg, errors); diff --git a/src/main/java/org/support/project/knowledge/control/admin/DatabaseControl.java b/src/main/java/org/support/project/knowledge/control/admin/DatabaseControl.java index 1b7c270ec..183713583 100644 --- a/src/main/java/org/support/project/knowledge/control/admin/DatabaseControl.java +++ b/src/main/java/org/support/project/knowledge/control/admin/DatabaseControl.java @@ -18,6 +18,8 @@ import org.support.project.common.serialize.SerializeUtils; import org.support.project.common.wrapper.FileInputStreamWithDeleteWrapper; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.bat.CreateExportDataBat; import org.support.project.knowledge.config.AppConfig; import org.support.project.knowledge.config.SystemConfig; @@ -40,6 +42,7 @@ import org.support.project.web.entity.SystemConfigsEntity; import org.support.project.web.logic.DBConnenctionLogic; +@DI(instance=Instance.Prototype) public class DatabaseControl extends Control { /* (non-Javadoc) @@ -295,7 +298,7 @@ public Boundary data_transfer_back() throws IOException { @Get @Auth(roles="admin") public Boundary reindexing() { - SystemConfigsEntity entity = SystemConfigsDao.get().selectOnKey(SystemConfig.RE_INDEXING, AppConfig.SYSTEM_NAME); + SystemConfigsEntity entity = SystemConfigsDao.get().selectOnKey(SystemConfig.RE_INDEXING, AppConfig.get().getSystemName()); if (entity != null) { setAttribute("start_reindexing", Boolean.TRUE); } else { @@ -311,7 +314,7 @@ public Boundary reindexing() { @Post @Auth(roles="admin") public Boundary start_reindexing() { - SystemConfigsEntity entity = SystemConfigsDao.get().selectOnKey(SystemConfig.RE_INDEXING, AppConfig.SYSTEM_NAME); + SystemConfigsEntity entity = SystemConfigsDao.get().selectOnKey(SystemConfig.RE_INDEXING, AppConfig.get().getSystemName()); if (entity != null) { addMsgInfo("message.allready.started"); return reindexing(); @@ -321,7 +324,7 @@ public Boundary start_reindexing() { String val = "start=" + start + ",end=" + end; entity = new SystemConfigsEntity(); - entity.setSystemName(AppConfig.SYSTEM_NAME); + entity.setSystemName(AppConfig.get().getSystemName()); entity.setConfigName(SystemConfig.RE_INDEXING); entity.setConfigValue(val); SystemConfigsDao.get().save(entity); @@ -335,7 +338,7 @@ public Boundary start_reindexing() { @Get @Auth(roles="admin") public Boundary export() { - SystemConfigsEntity entity = SystemConfigsDao.get().selectOnKey(SystemConfig.DATA_EXPORT, AppConfig.SYSTEM_NAME); + SystemConfigsEntity entity = SystemConfigsDao.get().selectOnKey(SystemConfig.DATA_EXPORT, AppConfig.get().getSystemName()); if (entity != null) { setAttribute("start_export", Boolean.TRUE); } else { @@ -351,13 +354,13 @@ public Boundary export() { @Get @Auth(roles="admin") public Boundary export_data_create() { - SystemConfigsEntity entity = SystemConfigsDao.get().selectOnKey(SystemConfig.DATA_EXPORT, AppConfig.SYSTEM_NAME); + SystemConfigsEntity entity = SystemConfigsDao.get().selectOnKey(SystemConfig.DATA_EXPORT, AppConfig.get().getSystemName()); if (entity != null) { addMsgInfo("message.allready.started"); return export(); } entity = new SystemConfigsEntity(); - entity.setSystemName(AppConfig.SYSTEM_NAME); + entity.setSystemName(AppConfig.get().getSystemName()); entity.setConfigName(SystemConfig.DATA_EXPORT); entity.setConfigValue("START"); SystemConfigsDao.get().save(entity); diff --git a/src/main/java/org/support/project/knowledge/control/admin/LdapControl.java b/src/main/java/org/support/project/knowledge/control/admin/LdapControl.java new file mode 100644 index 000000000..e776a7096 --- /dev/null +++ b/src/main/java/org/support/project/knowledge/control/admin/LdapControl.java @@ -0,0 +1,212 @@ +package org.support.project.knowledge.control.admin; + +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.List; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +import net.arnx.jsonic.JSONException; + +import org.apache.directory.api.ldap.model.exception.LdapException; +import org.support.project.common.bean.ValidateError; +import org.support.project.common.config.INT_FLAG; +import org.support.project.common.util.PasswordUtil; +import org.support.project.common.util.StringUtils; +import org.support.project.di.DI; +import org.support.project.di.Instance; +import org.support.project.knowledge.config.AppConfig; +import org.support.project.knowledge.control.Control; +import org.support.project.web.annotation.Auth; +import org.support.project.web.bean.LdapInfo; +import org.support.project.web.boundary.Boundary; +import org.support.project.web.control.service.Get; +import org.support.project.web.control.service.Post; +import org.support.project.web.dao.LdapConfigsDao; +import org.support.project.web.entity.LdapConfigsEntity; +import org.support.project.web.exception.InvalidParamException; +import org.support.project.web.logic.LdapLogic; + +@DI(instance=Instance.Prototype) +public class LdapControl extends Control { + + private static final String NO_CHANGE_PASSWORD = "NO_CHANGE_PASSWORD-fXLSJ_V-ZJ2E-X6c2_iGCpkE"; //パスワードを更新しなかったことを表すパスワード + + /** + * 設定画面を表示 + * @return + */ + @Get + @Auth(roles="admin") + public Boundary config() { + LdapConfigsDao dao = LdapConfigsDao.get(); + LdapConfigsEntity entity = dao.selectOnKey(AppConfig.get().getSystemName()); + if (entity == null) { + entity = new LdapConfigsEntity(); + } else { + entity.setBindPassword(NO_CHANGE_PASSWORD); + entity.setSalt(""); + } + entity.setSystemName(AppConfig.get().getSystemName()); + setAttributeOnProperty(entity); + + if (entity.getUseSsl() != null && entity.getUseSsl().intValue() == INT_FLAG.ON.getValue()) { + setAttribute("security", "usessl"); + } else if (entity.getUseTls() != null && entity.getUseTls().intValue() == INT_FLAG.ON.getValue()) { + setAttribute("security", "usetls"); + } else { + setAttribute("security", "plain"); + } + return forward("config.jsp"); + } + + /** + * リクエストの情報からLdapの設定情報を抽出(共通処理) + * @return + * @throws InstantiationException + * @throws IllegalAccessException + * @throws IOException + * @throws InvalidParamException + * @throws NoSuchAlgorithmException + * @throws NoSuchPaddingException + * @throws InvalidKeyException + * @throws IllegalBlockSizeException + * @throws BadPaddingException + */ + private LdapConfigsEntity loadLdapConfig() throws InstantiationException, IllegalAccessException, IOException, InvalidParamException, + NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { + LdapConfigsDao dao = LdapConfigsDao.get(); + LdapConfigsEntity entity = super.getParamOnProperty(LdapConfigsEntity.class); + String security = getParam("security"); + if (!StringUtils.isEmpty(security)) { + if (security.toLowerCase().equals("usessl")) { + entity.setUseSsl(INT_FLAG.ON.getValue()); + } else if (security.toLowerCase().equals("usetls")) { + entity.setUseTls(INT_FLAG.ON.getValue()); + } + } + String password = entity.getBindPassword(); + if (password.equals(NO_CHANGE_PASSWORD)) { + LdapConfigsEntity saved = dao.selectOnKey(AppConfig.get().getSystemName()); + if (saved != null) { + String encPass = saved.getBindPassword(); + String salt = saved.getSalt(); + password = PasswordUtil.decrypt(encPass, salt); + entity.setBindPassword(password); + } + } + return entity; + } + + /** + * Ldap認証の設定のテスト + * @return + * @throws InvalidParamException + * @throws IOException + * @throws JSONException + * @throws IllegalAccessException + * @throws InstantiationException + * @throws LdapException + * @throws BadPaddingException + * @throws IllegalBlockSizeException + * @throws NoSuchPaddingException + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + */ + @Post + @Auth(roles="admin") + public Boundary check() throws InstantiationException, IllegalAccessException, JSONException, IOException, InvalidParamException, LdapException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { + List errors = LdapConfigsEntity.get().validate(getParams()); + if (errors != null && !errors.isEmpty()) { + super.setResult("", errors); + return forward("config.jsp"); + } + LdapConfigsEntity entity = loadLdapConfig(); + + LdapLogic ldapLogic = LdapLogic.get(); + LdapInfo result = ldapLogic.auth(entity, entity.getBindDn(), entity.getBindPassword()); + if (result == null) { + addMsgWarn("knowledge.ldap.msg.connect.error"); + } else { + addMsgSuccess("knowledge.ldap.msg.connect.success" + , result.getId() + , result.getName() + , result.getMail() + , String.valueOf(result.isAdmin())); + } + return forward("config.jsp"); + } + + + + + /** + * Ldap認証の設定のテスト + * @return + * @throws InvalidParamException + * @throws IOException + * @throws JSONException + * @throws IllegalAccessException + * @throws InstantiationException + * @throws LdapException + * @throws BadPaddingException + * @throws IllegalBlockSizeException + * @throws NoSuchPaddingException + * @throws NoSuchAlgorithmException + * @throws InvalidKeyException + */ + @Post + @Auth(roles="admin") + public Boundary save() throws InstantiationException, IllegalAccessException, JSONException, IOException, InvalidParamException, LdapException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { + List errors = LdapConfigsEntity.get().validate(getParams()); + if (errors != null && !errors.isEmpty()) { + super.setResult("", errors); + return forward("config.jsp"); + } + LdapConfigsEntity entity = loadLdapConfig(); + LdapLogic ldapLogic = LdapLogic.get(); + LdapInfo result = ldapLogic.auth(entity, entity.getBindDn(), entity.getBindPassword()); + if (result == null) { + addMsgWarn("knowledge.ldap.msg.save.error"); + } else { + //Ldap設定を保存 + LdapConfigsDao dao = LdapConfigsDao.get(); + entity.setSystemName(AppConfig.get().getSystemName()); + String salt = PasswordUtil.getSalt(); + String passHash = PasswordUtil.encrypt(entity.getBindPassword(), salt); + entity.setBindPassword(passHash); + entity.setSalt(salt); + dao.save(entity); + + entity.setBindPassword(NO_CHANGE_PASSWORD); + setAttributeOnProperty(entity); + addMsgSuccess("knowledge.ldap.msg.save.success"); + } + return forward("config.jsp"); + } + + /** + * Ldap設定の削除 + * @return + */ + @Post + @Auth(roles="admin") + public Boundary delete() { + LdapConfigsDao dao = LdapConfigsDao.get(); + LdapConfigsEntity entity = dao.selectOnKey(AppConfig.get().getSystemName()); + if (entity != null) { + dao.physicalDelete(AppConfig.get().getSystemName()); + } + entity = new LdapConfigsEntity(); + entity.setSystemName(AppConfig.get().getSystemName()); + setAttributeOnProperty(entity); + + addMsgInfo("message.success.delete.target", getResource("knowledge.ldap.title")); + + return config(); + } + +} diff --git a/src/main/java/org/support/project/knowledge/control/admin/MailControl.java b/src/main/java/org/support/project/knowledge/control/admin/MailControl.java index a44cb9cd8..a04224512 100644 --- a/src/main/java/org/support/project/knowledge/control/admin/MailControl.java +++ b/src/main/java/org/support/project/knowledge/control/admin/MailControl.java @@ -13,6 +13,8 @@ import org.support.project.common.config.INT_FLAG; import org.support.project.common.util.PasswordUtil; import org.support.project.common.util.StringUtils; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.config.AppConfig; import org.support.project.knowledge.control.Control; import org.support.project.web.annotation.Auth; @@ -22,6 +24,7 @@ import org.support.project.web.dao.MailConfigsDao; import org.support.project.web.entity.MailConfigsEntity; +@DI(instance=Instance.Prototype) public class MailControl extends Control { /** @@ -32,11 +35,11 @@ public class MailControl extends Control { @Auth(roles="admin") public Boundary config() { MailConfigsDao dao = MailConfigsDao.get(); - MailConfigsEntity entity = dao.selectOnKey(AppConfig.SYSTEM_NAME); + MailConfigsEntity entity = dao.selectOnKey(AppConfig.get().getSystemName()); if (entity == null) { entity = new MailConfigsEntity(); } - entity.setSystemName(AppConfig.SYSTEM_NAME); + entity.setSystemName(AppConfig.get().getSystemName()); entity.setSmtpPassword(""); // パスワードは送らない setAttributeOnProperty(entity); @@ -105,10 +108,10 @@ public Boundary save() throws InvalidKeyException, NoSuchAlgorithmException, NoS @Auth(roles="admin") public Boundary delete() { MailConfigsDao dao = MailConfigsDao.get(); - dao.physicalDelete(AppConfig.SYSTEM_NAME); // 物理削除で消してしまう + dao.physicalDelete(AppConfig.get().getSystemName()); // 物理削除で消してしまう MailConfigsEntity entity = new MailConfigsEntity(); - entity.setSystemName(AppConfig.SYSTEM_NAME); + entity.setSystemName(AppConfig.get().getSystemName()); setAttributeOnProperty(entity); addMsgInfo("message.success.delete.target", getResource("knowledge.config.mail")); diff --git a/src/main/java/org/support/project/knowledge/control/admin/UsersControl.java b/src/main/java/org/support/project/knowledge/control/admin/UsersControl.java index e05157e76..7240b3fba 100644 --- a/src/main/java/org/support/project/knowledge/control/admin/UsersControl.java +++ b/src/main/java/org/support/project/knowledge/control/admin/UsersControl.java @@ -204,12 +204,14 @@ public Boundary create() { // エラーが無い場合のみ登録 user = super.getParams(UsersEntity.class); String[] roles = getRequest().getParameterValues("roles"); - user = UserLogic.get().insert(user, roles, getLoginedUser()); + user = UserLogic.get().insert(user, roles); setAttributeOnProperty(user); // 登録されているロールをセット setSystemRoles(user); + UserLogic.get().insertDefaultGroup(user); + String successMsg = "message.success.insert"; setResult(successMsg, errors); return forward("view_edit.jsp"); diff --git a/src/main/java/org/support/project/knowledge/control/open/KnowledgeControl.java b/src/main/java/org/support/project/knowledge/control/open/KnowledgeControl.java index 70af1306a..bb87e0be5 100644 --- a/src/main/java/org/support/project/knowledge/control/open/KnowledgeControl.java +++ b/src/main/java/org/support/project/knowledge/control/open/KnowledgeControl.java @@ -5,8 +5,7 @@ import javax.servlet.http.Cookie; -import org.owasp.validator.html.PolicyException; -import org.owasp.validator.html.ScanException; +import org.support.project.common.exception.ParseException; import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.common.util.StringUtils; @@ -24,10 +23,12 @@ import org.support.project.knowledge.entity.TagsEntity; import org.support.project.knowledge.logic.DiffLogic; import org.support.project.knowledge.logic.KnowledgeLogic; +import org.support.project.knowledge.logic.MarkdownLogic; import org.support.project.knowledge.logic.TagLogic; import org.support.project.knowledge.logic.TargetLogic; import org.support.project.knowledge.logic.UploadedFileLogic; import org.support.project.knowledge.vo.LikeCount; +import org.support.project.knowledge.vo.MarkDown; import org.support.project.knowledge.vo.UploadFile; import org.support.project.web.bean.LabelValue; import org.support.project.web.bean.LoginedUser; @@ -53,9 +54,10 @@ public class KnowledgeControl extends KnowledgeControlBase { * ナレッジを表示 * @return * @throws InvalidParamException + * @throws ParseException */ @Get - public Boundary view() throws InvalidParamException { + public Boundary view() throws InvalidParamException, ParseException { // 共通処理呼の表示条件の保持の呼び出し setViewParam(); @@ -101,6 +103,11 @@ public Boundary view() throws InvalidParamException { if (entity == null) { return sendError(HttpStatus.SC_404_NOT_FOUND, "NOT FOUND"); } + //Markdownを処理 + entity.setTitle(sanitize(entity.getTitle())); + MarkDown markDown = MarkdownLogic.get().markdownToHtml(entity.getContent()); + entity.setContent(markDown.getHtml()); + setAttributeOnProperty(entity); String offset = super.getParam("offset", String.class); @@ -125,6 +132,11 @@ public Boundary view() throws InvalidParamException { // コメント取得 CommentsDao commentsDao = CommentsDao.get(); List comments = commentsDao.selectOnKnowledgeId(knowledgeId); + // Markdown を処理 + for (CommentsEntity commentsEntity : comments) { + MarkDown markDown2 = MarkdownLogic.get().markdownToHtml(commentsEntity.getComment()); + commentsEntity.setComment(markDown2.getHtml()); + } setAttribute("comments", comments); // 表示するグループを取得 @@ -162,6 +174,8 @@ public Boundary list() throws Exception { String keyword = getParam("keyword"); String tag = getParam("tag"); String user = getParam("user"); + String tagNames = getParam("tagNames"); + List knowledges = new ArrayList<>(); if (StringUtils.isInteger(tag)) { //タグを選択している @@ -175,8 +189,27 @@ public Boundary list() throws Exception { int userId = Integer.parseInt(user); knowledges.addAll(knowledgeLogic.showKnowledgeOnUser(userId, loginedUser, offset * PAGE_LIMIT, PAGE_LIMIT)); UsersEntity usersEntity = UsersDao.get().selectOnKey(userId); - usersEntity.setPassword(""); - setAttribute("selectedUser", usersEntity); + if (user != null) { + usersEntity.setPassword(""); + setAttribute("selectedUser", usersEntity); + } + } else if (StringUtils.isNotEmpty(tagNames)) { + // タグとキーワードで検索 + LOG.trace("show on Tags and keyword"); + String[] taglist = tagNames.split(","); + List tags = new ArrayList<>(); + for (String string : taglist) { + String tagname = string.trim(); + if (tagname.startsWith(" ") && tagname.length() > " ".length()) { + tagname = tagname.substring(" ".length()); + } + TagsEntity tagsEntity = tagsDao.selectOnTagName(tagname); + if (tagsEntity != null) { + tags.add(tagsEntity); + } + } + setAttribute("searchTags", tags); + knowledges.addAll(knowledgeLogic.searchKnowledge(keyword, tags, loginedUser, offset * PAGE_LIMIT, PAGE_LIMIT)); } else { // その他(キーワード検索) LOG.trace("search"); @@ -263,27 +296,42 @@ public Boundary like() throws InvalidParamException { /** * タイトルとコンテンツの危険なタグをエスケープした結果を返す - * (KnowledgesEntityのgetXXXで実施しているので、entityにセットしてJSONで返すだけで良い) - * TODO クライアント側で出来ないか? * @param entity * @return - * @throws ScanException - * @throws PolicyException + * @throws ParseException */ @Post - public Boundary escape(KnowledgesEntity entity) throws PolicyException, ScanException { + public Boundary escape(KnowledgesEntity entity) throws ParseException { super.setSendEscapeHtml(false); - entity.setTitle(doSamy(entity.getTitle())); - entity.setContent(doSamy(entity.getContent())); + entity.setTitle(sanitize(entity.getTitle())); + entity.setContent(sanitize(entity.getContent())); return super.send(entity); } + /** + * タイトルの危険なタグをサニタイズし、コンテンツのmarkdownをHTMLへ変換する + * @param entity + * @return + * @throws ParseException + */ + @Post + public Boundary marked(KnowledgesEntity entity) throws ParseException { + super.setSendEscapeHtml(false); + entity.setTitle(sanitize(entity.getTitle())); + MarkDown markDown = MarkdownLogic.get().markdownToHtml(entity.getContent()); + entity.setContent(markDown.getHtml()); + return super.send(entity); + } + /** * 検索画面を表示 * @return */ @Get public Boundary search() { + List tagitems = TagsDao.get().selectAll(); + setAttribute("tagitems", tagitems); + // 共通処理呼の表示条件の保持の呼び出し setViewParam(); return forward("search.jsp"); diff --git a/src/main/java/org/support/project/knowledge/control/open/PasswordInitializationControl.java b/src/main/java/org/support/project/knowledge/control/open/PasswordInitializationControl.java index be3737ee6..dcef0c8a9 100644 --- a/src/main/java/org/support/project/knowledge/control/open/PasswordInitializationControl.java +++ b/src/main/java/org/support/project/knowledge/control/open/PasswordInitializationControl.java @@ -8,6 +8,8 @@ import org.support.project.common.util.StringUtils; import org.support.project.common.validate.Validator; import org.support.project.common.validate.ValidatorFactory; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.control.Control; import org.support.project.knowledge.logic.PasswordInitializationLogic; import org.support.project.web.boundary.Boundary; @@ -19,6 +21,7 @@ import org.support.project.web.entity.PasswordResetsEntity; import org.support.project.web.exception.InvalidParamException; +@DI(instance=Instance.Prototype) public class PasswordInitializationControl extends Control { /** diff --git a/src/main/java/org/support/project/knowledge/control/open/SignupControl.java b/src/main/java/org/support/project/knowledge/control/open/SignupControl.java index 49fdd13a8..2f0b9c58b 100644 --- a/src/main/java/org/support/project/knowledge/control/open/SignupControl.java +++ b/src/main/java/org/support/project/knowledge/control/open/SignupControl.java @@ -10,15 +10,17 @@ import org.support.project.common.validate.Validator; import org.support.project.common.validate.ValidatorFactory; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.config.AppConfig; import org.support.project.knowledge.config.SystemConfig; import org.support.project.knowledge.control.Control; import org.support.project.knowledge.logic.MailLogic; -import org.support.project.knowledge.logic.UserLogic; import org.support.project.web.boundary.Boundary; import org.support.project.web.common.HttpStatus; import org.support.project.web.common.HttpUtil; import org.support.project.web.config.HttpMethod; +import org.support.project.web.config.WebConfig; import org.support.project.web.control.service.Get; import org.support.project.web.control.service.Post; import org.support.project.web.dao.ProvisionalRegistrationsDao; @@ -28,8 +30,10 @@ import org.support.project.web.entity.SystemConfigsEntity; import org.support.project.web.entity.UsersEntity; import org.support.project.web.logic.AuthenticationLogic; +import org.support.project.web.logic.UserLogic; import org.support.project.web.logic.impl.DefaultAuthenticationLogicImpl; +@DI(instance=Instance.Prototype) public class SignupControl extends Control { /** @@ -48,7 +52,7 @@ public Boundary view() { @Post public Boundary save() { SystemConfigsDao systemConfigsDao = SystemConfigsDao.get(); - SystemConfigsEntity userAddType = systemConfigsDao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + SystemConfigsEntity userAddType = systemConfigsDao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); if (userAddType == null) { // ユーザによるデータの追加は認められていない return sendError(HttpStatus.SC_404_NOT_FOUND, "NOT FOUND"); @@ -138,8 +142,8 @@ private ProvisionalRegistrationsEntity addProvisionalRegistration() { private void addUser() { // エラーが無い場合のみ登録 UsersEntity user = super.getParams(UsersEntity.class); - String[] roles = {SystemConfig.ROLE_USER}; - user = UserLogic.get().insert(user, roles, getLoginedUser()); + String[] roles = {WebConfig.ROLE_USER}; + user = UserLogic.get().insert(user, roles); setAttributeOnProperty(user); // 管理者へユーザが追加されたことを通知 diff --git a/src/main/java/org/support/project/knowledge/control/open/TagControl.java b/src/main/java/org/support/project/knowledge/control/open/TagControl.java index 7e139fef5..a12027de2 100644 --- a/src/main/java/org/support/project/knowledge/control/open/TagControl.java +++ b/src/main/java/org/support/project/knowledge/control/open/TagControl.java @@ -1,18 +1,24 @@ package org.support.project.knowledge.control.open; -import java.util.ArrayList; import java.util.List; +import org.support.project.common.log.Log; +import org.support.project.common.log.LogFactory; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.control.Control; import org.support.project.knowledge.dao.TagsDao; import org.support.project.knowledge.entity.TagsEntity; -import org.support.project.web.bean.LoginedUser; +import org.support.project.knowledge.logic.TagLogic; import org.support.project.web.boundary.Boundary; import org.support.project.web.control.service.Get; -import org.support.project.web.entity.GroupsEntity; import org.support.project.web.exception.InvalidParamException; +@DI(instance=Instance.Prototype) public class TagControl extends Control { + /** ログ */ + private static Log LOG = LogFactory.getLog(FileControl.class); + private static final int LIST_LIMIT = 20; /** @@ -24,20 +30,7 @@ public class TagControl extends Control { @Get public Boundary list() throws InvalidParamException { Integer offset = super.getPathInteger(0); - int userId = super.getLoginUserId(); - LoginedUser loginedUser = super.getLoginedUser(); - List groups = new ArrayList(); - if (loginedUser != null && loginedUser.getGroups() != null) { - groups = loginedUser.getGroups(); - } - - TagsDao tagsDao = TagsDao.get(); - List tags; - if (super.getLoginedUser() != null && super.getLoginedUser().isAdmin()) { - tags = tagsDao.selectWithKnowledgeCountAdmin(offset * LIST_LIMIT, LIST_LIMIT); - } else { - tags = tagsDao.selectWithKnowledgeCount(userId, groups, offset * LIST_LIMIT, LIST_LIMIT); - } + List tags = TagLogic.get().selectTagsWithCount(super.getLoginedUser(), offset * LIST_LIMIT, LIST_LIMIT); setAttribute("tags", tags); int previous = offset -1; @@ -51,4 +44,24 @@ public Boundary list() throws InvalidParamException { return forward("list.jsp"); } + /** + * タグの選択画面で表示するデータをJSON形式で取得 + * @return + * @throws InvalidParamException + */ + @Get + public Boundary json() throws InvalidParamException { + int limit = 10; + String keyword = super.getParam("keyword"); + Integer offset = super.getPathInteger(0); + // タグに紐付いているナレッジの件数でデータをソートして取得(ナレッジへのアクセス件は考慮しない) + List tags = TagsDao.get().selectWithKnowledgeCountOnTagName(keyword, offset * limit, limit); + return send(tags); + } + + + + + + } diff --git a/src/main/java/org/support/project/knowledge/control/protect/AccountControl.java b/src/main/java/org/support/project/knowledge/control/protect/AccountControl.java index f426347ec..1168d709a 100644 --- a/src/main/java/org/support/project/knowledge/control/protect/AccountControl.java +++ b/src/main/java/org/support/project/knowledge/control/protect/AccountControl.java @@ -6,9 +6,9 @@ import java.util.Map; import org.apache.commons.fileupload.FileItem; -import org.owasp.validator.html.PolicyException; -import org.owasp.validator.html.ScanException; import org.support.project.common.bean.ValidateError; +import org.support.project.common.config.INT_FLAG; +import org.support.project.common.exception.ParseException; import org.support.project.common.util.StringUtils; import org.support.project.common.validate.Validator; import org.support.project.common.validate.ValidatorFactory; @@ -48,9 +48,9 @@ public class AccountControl extends Control { @Override public Boundary index() { SystemConfigsDao dao = SystemConfigsDao.get(); - SystemConfigsEntity userAddType = dao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + SystemConfigsEntity userAddType = dao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); if (userAddType == null) { - userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); userAddType.setConfigValue(SystemConfig.USER_ADD_TYPE_VALUE_ADMIN); } setAttribute("userAddType", userAddType.getConfigValue()); @@ -73,16 +73,17 @@ public Boundary index() { /** * ユーザの情報更新 * @return + * @throws ParseException * @throws ScanException * @throws PolicyException */ @Post - public Boundary update() throws PolicyException, ScanException { + public Boundary update() throws ParseException { SystemConfigsDao systemConfigsDao = SystemConfigsDao.get(); - SystemConfigsEntity userAddType = systemConfigsDao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + SystemConfigsEntity userAddType = systemConfigsDao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); if (userAddType == null) { - userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); userAddType.setConfigValue(SystemConfig.USER_ADD_TYPE_VALUE_ADMIN); } setAttribute("userAddType", userAddType.getConfigValue()); @@ -98,7 +99,7 @@ public Boundary update() throws PolicyException, ScanException { if (StringUtils.isEmpty(getParam("password"))) { values.put("password", "-"); } - values.put("userName", super.doSamy(values.get("userName"))); // ユーザ名はXSS対策する + values.put("userName", super.sanitize(values.get("userName"))); // ユーザ名はXSS対策する UsersEntity user = new UsersEntity(); List errors = user.validate(values); @@ -117,6 +118,9 @@ public Boundary update() throws PolicyException, ScanException { if (user == null) { return sendError(HttpStatus.SC_400_BAD_REQUEST, "user is allready removed."); } + if (user.getAuthLdap() != null && user.getAuthLdap().intValue() == INT_FLAG.ON.getValue()) { + return sendError(HttpStatus.SC_400_BAD_REQUEST, "can not edit ldap user."); + } if (userAddType.getConfigValue().equals(SystemConfig.USER_ADD_TYPE_VALUE_ADMIN)) { //ユーザ登録を管理者が行っている場合、メールアドレスは変更出来ない(変更用の画面も使えない) } else if (userAddType.getConfigValue().equals(SystemConfig.USER_ADD_TYPE_VALUE_APPROVE)) { @@ -131,6 +135,11 @@ public Boundary update() throws PolicyException, ScanException { user.setPassword(getParam("password")); user.setEncrypted(false); } + if (StringUtils.isEmpty(user.getMailAddress())) { + if (StringUtils.isEmailAddress(user.getUserKey())) { + user.setMailAddress(user.getUserKey()); + } + } dao.update(user); } String successMsg = "message.success.update"; @@ -232,9 +241,9 @@ private ValidateError checkFile(FileItem fileItem) { @Get public Boundary changekey() { SystemConfigsDao dao = SystemConfigsDao.get(); - SystemConfigsEntity userAddType = dao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + SystemConfigsEntity userAddType = dao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); if (userAddType == null) { - userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); userAddType.setConfigValue(SystemConfig.USER_ADD_TYPE_VALUE_ADMIN); } if (!userAddType.getConfigValue().equals(SystemConfig.USER_ADD_TYPE_VALUE_MAIL)) { @@ -253,9 +262,9 @@ public Boundary changekey() { @Post public Boundary changerequest() { SystemConfigsDao dao = SystemConfigsDao.get(); - SystemConfigsEntity userAddType = dao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + SystemConfigsEntity userAddType = dao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); if (userAddType == null) { - userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); userAddType.setConfigValue(SystemConfig.USER_ADD_TYPE_VALUE_ADMIN); } if (!userAddType.getConfigValue().equals(SystemConfig.USER_ADD_TYPE_VALUE_MAIL)) { @@ -283,9 +292,9 @@ public Boundary changerequest() { public Boundary confirm_mail() throws InvalidParamException { // メールアドレス変更ができるのは、ダブルオプトインでユーザ登録する設定になっている場合のみ SystemConfigsDao dao = SystemConfigsDao.get(); - SystemConfigsEntity userAddType = dao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + SystemConfigsEntity userAddType = dao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); if (userAddType == null) { - userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + userAddType = new SystemConfigsEntity(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); userAddType.setConfigValue(SystemConfig.USER_ADD_TYPE_VALUE_ADMIN); } if (!userAddType.getConfigValue().equals(SystemConfig.USER_ADD_TYPE_VALUE_MAIL)) { diff --git a/src/main/java/org/support/project/knowledge/control/protect/GroupControl.java b/src/main/java/org/support/project/knowledge/control/protect/GroupControl.java index f84dea752..8d9196d04 100644 --- a/src/main/java/org/support/project/knowledge/control/protect/GroupControl.java +++ b/src/main/java/org/support/project/knowledge/control/protect/GroupControl.java @@ -4,18 +4,20 @@ import java.util.List; import java.util.Map; -import org.owasp.validator.html.PolicyException; -import org.owasp.validator.html.ScanException; import org.support.project.common.bean.ValidateError; +import org.support.project.common.exception.ParseException; import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.common.util.RandomUtil; import org.support.project.common.util.StringUtils; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.control.Control; import org.support.project.knowledge.logic.GroupLogic; import org.support.project.knowledge.vo.GroupUser; import org.support.project.web.bean.LabelValue; import org.support.project.web.bean.LoginedUser; +import org.support.project.web.bean.MessageResult; import org.support.project.web.boundary.Boundary; import org.support.project.web.common.HttpStatus; import org.support.project.web.config.CommonWebParameter; @@ -27,6 +29,7 @@ import org.support.project.web.entity.UserGroupsEntity; import org.support.project.web.exception.InvalidParamException; +@DI(instance=Instance.Prototype) public class GroupControl extends Control { /** ログ */ private static Log LOG = LogFactory.getLog(GroupControl.class); @@ -95,16 +98,17 @@ public Boundary view_add() { /** * グループを追加 * @return + * @throws ParseException * @throws ScanException * @throws PolicyException */ @Post - public Boundary add() throws PolicyException, ScanException { + public Boundary add() throws ParseException { // 入力チェック GroupsEntity groupsEntity = new GroupsEntity(); Map params = super.getParams(); params.put("groupKey", "g-" + RandomUtil.randamGen(16)); - params.put("groupName", super.doSamy(params.get("groupName"))); //XSS対策 + params.put("groupName", super.sanitize(params.get("groupName"))); //XSS対策 List errors = groupsEntity.validate(params); if (!errors.isEmpty()) { @@ -158,6 +162,14 @@ public Boundary view() throws InvalidParamException { } } + int previous = offset -1; + if (previous < 0) { + previous = 0; + } + setAttribute("offset", offset); + setAttribute("previous", previous); + setAttribute("next", offset + 1); + setAttribute("users", users); setAttribute("belong", belong); @@ -187,15 +199,16 @@ public Boundary view_edit() throws InvalidParamException { /** * グループを更新 * @return + * @throws ParseException * @throws ScanException * @throws PolicyException */ @Post - public Boundary update() throws PolicyException, ScanException { + public Boundary update() throws ParseException { // 入力チェック GroupsEntity groupsEntity = new GroupsEntity(); Map params = super.getParams(); - params.put("groupName", super.doSamy(params.get("groupName"))); //XSS対策 + params.put("groupName", super.sanitize(params.get("groupName"))); //XSS対策 List errors = groupsEntity.validate(params); if (!errors.isEmpty()) { @@ -371,7 +384,7 @@ public Boundary accept() throws InvalidParamException { * @return * @throws InvalidParamException */ - @Post + @Get public Boundary change() throws InvalidParamException { Integer groupId = super.getPathInteger(0); String userIdstr = super.getParam("userId"); @@ -395,12 +408,19 @@ public Boundary change() throws InvalidParamException { addMsgWarn("message.allready.updated"); } else if (userGroupsEntity != null) { if (status >= CommonWebParameter.GROUP_ROLE_MEMBER) { + // 権限変更 userGroupsEntity.setGroupRole(status); userGroupsDao.save(userGroupsEntity); - addMsgSuccess("message.success.accept"); + addMsgSuccess("message.success.update"); } else { - userGroupsDao.physicalDelete(userGroupsEntity); - addMsgSuccess("message.success.delete"); + // グループから削除 + if (groupId.intValue() == 0) { + // ALLグループから削除は出来ない + addMsgWarn("Can not remove user from Group [ALL]."); + } else { + userGroupsDao.physicalDelete(userGroupsEntity); + addMsgSuccess("message.success.delete"); + } } } return super.devolution(HttpMethod.get, "protect.Group/view"); @@ -434,5 +454,17 @@ public Boundary typeahead() throws InvalidParamException { return send(aHeads); } - + /** + * 非公開グループにユーザを追加 + * @return + */ + @Post + public Boundary addUsers() { + Integer groupId = getParam("group", Integer.class); + String users = getParam("users"); + GroupLogic groupLogic = GroupLogic.get(); + MessageResult result = groupLogic.addUsers(super.getLoginedUser(), groupId, users); + return send(result); + } + } diff --git a/src/main/java/org/support/project/knowledge/control/protect/KnowledgeControl.java b/src/main/java/org/support/project/knowledge/control/protect/KnowledgeControl.java index 39b14b61a..6613dac4b 100644 --- a/src/main/java/org/support/project/knowledge/control/protect/KnowledgeControl.java +++ b/src/main/java/org/support/project/knowledge/control/protect/KnowledgeControl.java @@ -5,6 +5,7 @@ import java.util.List; import org.support.project.common.bean.ValidateError; +import org.support.project.common.exception.ParseException; import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.common.util.StringUtils; @@ -12,10 +13,8 @@ import org.support.project.di.DI; import org.support.project.di.Instance; import org.support.project.knowledge.control.KnowledgeControlBase; -import org.support.project.knowledge.dao.KnowledgeGroupsDao; import org.support.project.knowledge.dao.KnowledgesDao; -import org.support.project.knowledge.entity.KnowledgeGroupsEntity; -import org.support.project.knowledge.entity.KnowledgeUsersEntity; +import org.support.project.knowledge.dao.TagsDao; import org.support.project.knowledge.entity.KnowledgesEntity; import org.support.project.knowledge.entity.TagsEntity; import org.support.project.knowledge.logic.KnowledgeLogic; @@ -29,7 +28,6 @@ import org.support.project.web.config.HttpMethod; import org.support.project.web.control.service.Get; import org.support.project.web.control.service.Post; -import org.support.project.web.entity.GroupsEntity; import org.support.project.web.exception.InvalidParamException; @DI(instance=Instance.Prototype) @@ -54,7 +52,10 @@ public Boundary view_add() { offset = "0"; } setAttribute("offset", offset); - + + List tagitems = TagsDao.get().selectAll(); + setAttribute("tagitems", tagitems); + return forward("view_add.jsp"); } /** @@ -101,6 +102,9 @@ public Boundary view_edit() throws InvalidParamException { return devolution(HttpMethod.get, "open.Knowledge/view", String.valueOf(knowledgeId)); } + List tagitems = TagsDao.get().selectAll(); + setAttribute("tagitems", tagitems); + return forward("view_edit.jsp"); } @@ -108,9 +112,10 @@ public Boundary view_edit() throws InvalidParamException { * 登録する * @return * @throws Exception + * @throws ParseException */ @Post - public Boundary add(KnowledgesEntity entity) throws Exception { + public Boundary add(KnowledgesEntity entity) throws Exception, ParseException { // 共通処理呼の表示条件の保持の呼び出し setViewParam(); @@ -125,6 +130,9 @@ public Boundary add(KnowledgesEntity entity) throws Exception { List editors = TargetLogic.get().selectTargets(editordids); setAttribute("editors", editors); + List tagitems = TagsDao.get().selectAll(); + setAttribute("tagitems", tagitems); + List fileNos = new ArrayList(); Object obj = getParam("files", Object.class); if (obj != null) { @@ -143,8 +151,8 @@ public Boundary add(KnowledgesEntity entity) throws Exception { } } - entity.setTitle(super.doSamy(entity.getTitle())); //XSS対策 - entity.setContent(super.doSamy(entity.getContent())); //XSS対策 + //entity.setTitle(super.sanitize(entity.getTitle())); //XSS対策 + //entity.setContent(super.sanitize(entity.getContent())); //XSS対策 List errors = entity.validate(); if (!errors.isEmpty()) { @@ -197,6 +205,9 @@ public Boundary update(KnowledgesEntity entity) throws Exception { List editors = TargetLogic.get().selectTargets(editordids); setAttribute("editors", editors); + List tagitems = TagsDao.get().selectAll(); + setAttribute("tagitems", tagitems); + List fileNos = new ArrayList(); Object obj = getParam("files", Object.class); if (obj != null) { @@ -215,8 +226,8 @@ public Boundary update(KnowledgesEntity entity) throws Exception { } } - entity.setTitle(super.doSamy(entity.getTitle())); //XSS対策 - entity.setContent(super.doSamy(entity.getContent())); //XSS対策 + //entity.setTitle(super.sanitize(entity.getTitle())); //XSS対策 + //entity.setContent(super.sanitize(entity.getContent())); //XSS対策 KnowledgesDao dao = Container.getComp(KnowledgesDao.class); List errors = entity.validate(); @@ -285,6 +296,10 @@ public Boundary delete() throws Exception { //return super.devolution("open.knowledge/list"); return forward("/commons/errors/server_error.jsp"); } + + List tagitems = TagsDao.get().selectAll(); + setAttribute("tagitems", tagitems); + Long knowledgeId = new Long(id); KnowledgesEntity check = dao.selectOnKey(knowledgeId); if (check == null) { @@ -328,7 +343,8 @@ public Boundary comment() throws Exception { // 共通処理呼の表示条件の保持の呼び出し String params = setViewParam(); Long knowledgeId = super.getPathLong(Long.valueOf(-1)); - String comment = super.doSamy(getParam("addcomment")); + //String comment = super.sanitize(getParam("addcomment")); + String comment = getParam("addcomment"); // 必須チェック if (StringUtils.isEmpty(comment)) { diff --git a/src/main/java/org/support/project/knowledge/control/protect/TargetControl.java b/src/main/java/org/support/project/knowledge/control/protect/TargetControl.java index 03207abd3..ead6721f5 100644 --- a/src/main/java/org/support/project/knowledge/control/protect/TargetControl.java +++ b/src/main/java/org/support/project/knowledge/control/protect/TargetControl.java @@ -5,6 +5,8 @@ import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.common.util.StringUtils; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.control.Control; import org.support.project.knowledge.logic.TargetLogic; import org.support.project.web.bean.LabelValue; @@ -12,6 +14,7 @@ import org.support.project.web.control.service.Get; import org.support.project.web.exception.InvalidParamException; +@DI(instance=Instance.Prototype) public class TargetControl extends Control { /** ログ */ private static Log LOG = LogFactory.getLog(GroupControl.class); @@ -33,10 +36,16 @@ public Boundary typeahead() throws InvalidParamException { if (StringUtils.isInteger(off)) { offset = Integer.parseInt(off); } - - TargetLogic groupLogic = TargetLogic.get(); - List aHeads = groupLogic.selectOnKeyword(keyword, super.getLoginedUser(), offset * limit, limit); - return send(aHeads); + String filter = getParam("filter"); + if (!StringUtils.isEmpty(filter) && "user".equals(filter)) { + TargetLogic groupLogic = TargetLogic.get(); + List aHeads = groupLogic.selectUsersOnKeyword(keyword, super.getLoginedUser(), offset * limit, limit); + return send(aHeads); + } else { + TargetLogic groupLogic = TargetLogic.get(); + List aHeads = groupLogic.selectOnKeyword(keyword, super.getLoginedUser(), offset * limit, limit); + return send(aHeads); + } } } diff --git a/src/main/java/org/support/project/knowledge/dao/NotifyQueuesDao.java b/src/main/java/org/support/project/knowledge/dao/NotifyQueuesDao.java index 240ceef37..cf2cc84ba 100644 --- a/src/main/java/org/support/project/knowledge/dao/NotifyQueuesDao.java +++ b/src/main/java/org/support/project/knowledge/dao/NotifyQueuesDao.java @@ -3,8 +3,8 @@ import org.support.project.di.Container; import org.support.project.di.DI; import org.support.project.di.Instance; - import org.support.project.knowledge.dao.gen.GenNotifyQueuesDao; +import org.support.project.knowledge.entity.NotifyQueuesEntity; /** * 通知待ちキュー @@ -22,6 +22,17 @@ public class NotifyQueuesDao extends GenNotifyQueuesDao { public static NotifyQueuesDao get() { return Container.getComp(NotifyQueuesDao.class); } + + /** + * 通知キューに、同一の通知種類/IDの情報が無いか検索する + * @param type + * @param id + * @return + */ + public NotifyQueuesEntity selectOnTypeAndId(Integer type, Long id) { + String sql = "SELECT * FROM NOTIFY_QUEUES WHERE TYPE = ? AND ID = ? AND DELETE_FLAG = 0"; + return super.executeQuerySingle(sql, NotifyQueuesEntity.class, type, id); + } diff --git a/src/main/java/org/support/project/knowledge/dao/TagsDao.java b/src/main/java/org/support/project/knowledge/dao/TagsDao.java index a79b2b3fd..65cb1cef0 100644 --- a/src/main/java/org/support/project/knowledge/dao/TagsDao.java +++ b/src/main/java/org/support/project/knowledge/dao/TagsDao.java @@ -137,4 +137,21 @@ public List selectWithKnowledgeCountAdmin(int offset, int limit) { return executeQueryList(sql, TagsEntity.class, limit, offset); } + + + /** + * タグの一覧と、それに紐づくナレッジの件数を取得 + * 管理者用で、ナレッジにアクセス可能かのアクセス権限チェックはしない + * @param offset + * @param limit + * @return + */ + public List selectWithKnowledgeCountOnTagName(String keyword, int offset, int limit) { + String sql = SQLManager.getInstance().getSql("/org/support/project/knowledge/dao/sql/TagsDao/TagsDao_selectWithKnowledgeCountOnTagName.sql"); + StringBuilder builder = new StringBuilder(); + builder.append("%").append(keyword).append("%"); + return executeQueryList(sql, TagsEntity.class, builder.toString(), limit, offset); + } + + } diff --git a/src/main/java/org/support/project/knowledge/deploy/InitDB.java b/src/main/java/org/support/project/knowledge/deploy/InitDB.java index e2a555104..9a1ace59e 100644 --- a/src/main/java/org/support/project/knowledge/deploy/InitDB.java +++ b/src/main/java/org/support/project/knowledge/deploy/InitDB.java @@ -12,6 +12,8 @@ import org.support.project.knowledge.deploy.v0_5_0.Migrate_0_5_0; import org.support.project.knowledge.deploy.v0_5_1.Migrate_0_5_1; import org.support.project.knowledge.deploy.v0_5_2pre2.Migrate_0_5_2pre2; +import org.support.project.knowledge.deploy.v0_5_3pre2.Migrate_0_5_3pre2; +import org.support.project.knowledge.deploy.v0_5_3pre3.Migrate_0_5_3pre3; import org.support.project.web.dao.SystemsDao; import org.support.project.web.entity.SystemsEntity; @@ -20,11 +22,11 @@ public class InitDB { /** ログ */ private static Log LOG = LogFactory.getLog(InitDB.class); - private static final String SYSTEM_NAME = org.support.project.knowledge.config.AppConfig.SYSTEM_NAME; + private static final String SYSTEM_NAME = org.support.project.knowledge.config.AppConfig.get().getSystemName(); private static final Map MAP = new LinkedHashMap<>(); private static final Migrate INIT = InitializeSystem.get(); - public static final String CURRENT = "0.5.2.pre2"; + public static final String CURRENT = "0.5.3.pre3"; public InitDB() { super(); @@ -32,8 +34,9 @@ public InitDB() { MAP.put("0.4.4", Migrate_0_4_4.get()); // ナレッジ一覧の付加情報をナレッジテーブルに持つ MAP.put("0.5.0", Migrate_0_5_0.get()); // 通知設定 MAP.put("0.5.1", Migrate_0_5_1.get()); // ナレッジの更新履歴 - MAP.put(CURRENT, Migrate_0_5_2pre2.get()); // 共同編集 - + MAP.put("0.5.2.pre2", Migrate_0_5_2pre2.get()); // 共同編集 + MAP.put("0.5.3.pre2", Migrate_0_5_3pre2.get()); // ALLグループ + MAP.put(CURRENT, Migrate_0_5_3pre3.get()); // メールアドレス } public static void main(String[] args) throws Exception { diff --git a/src/main/java/org/support/project/knowledge/deploy/v0_0_1/InitializeSystem.java b/src/main/java/org/support/project/knowledge/deploy/v0_0_1/InitializeSystem.java index 75266b17e..ecd58cfb5 100644 --- a/src/main/java/org/support/project/knowledge/deploy/v0_0_1/InitializeSystem.java +++ b/src/main/java/org/support/project/knowledge/deploy/v0_0_1/InitializeSystem.java @@ -1,8 +1,8 @@ package org.support.project.knowledge.deploy.v0_0_1; -import org.support.project.knowledge.config.SystemConfig; import org.support.project.knowledge.deploy.Migrate; import org.support.project.ormapping.tool.dao.InitializeDao; +import org.support.project.web.config.WebConfig; import org.support.project.web.dao.RolesDao; import org.support.project.web.dao.UserRolesDao; import org.support.project.web.dao.UsersDao; @@ -27,13 +27,13 @@ private void addInitDatas() { //権限の追加 RolesEntity adminRole = RolesEntity.get(); adminRole.setRoleId(1); - adminRole.setRoleKey(SystemConfig.ROLE_ADMIN); + adminRole.setRoleKey(WebConfig.ROLE_ADMIN); adminRole.setRoleName("Administrator"); RolesDao.get().insert(adminRole); RolesEntity userRole = RolesEntity.get(); userRole.setRoleId(2); - userRole.setRoleKey(SystemConfig.ROLE_USER); + userRole.setRoleKey(WebConfig.ROLE_USER); userRole.setRoleName("User"); RolesDao.get().insert(userRole); @@ -61,7 +61,8 @@ private void createTables() { String[] sqlpaths = { "/org/support/project/web/database/ddl.sql", - "/org/support/project/knowledge/database/ddl.sql" + "/org/support/project/knowledge/database/ddl.sql", + "/org/support/project/knowledge/database/init_datas.sql" }; initializeDao.initializeDatabase(sqlpaths); } diff --git a/src/main/java/org/support/project/knowledge/deploy/v0_5_3pre2/Migrate_0_5_3pre2.java b/src/main/java/org/support/project/knowledge/deploy/v0_5_3pre2/Migrate_0_5_3pre2.java new file mode 100644 index 000000000..abf23aee5 --- /dev/null +++ b/src/main/java/org/support/project/knowledge/deploy/v0_5_3pre2/Migrate_0_5_3pre2.java @@ -0,0 +1,41 @@ +package org.support.project.knowledge.deploy.v0_5_3pre2; + +import java.util.List; + +import org.support.project.common.util.StringUtils; +import org.support.project.knowledge.deploy.Migrate; +import org.support.project.ormapping.tool.dao.InitializeDao; +import org.support.project.web.config.CommonWebParameter; +import org.support.project.web.dao.UserGroupsDao; +import org.support.project.web.dao.UsersDao; +import org.support.project.web.entity.UserGroupsEntity; +import org.support.project.web.entity.UsersEntity; + +public class Migrate_0_5_3pre2 implements Migrate { + + public static Migrate_0_5_3pre2 get() { + return org.support.project.di.Container.getComp(Migrate_0_5_3pre2.class); + } + + @Override + public boolean doMigrate() throws Exception { + InitializeDao initializeDao = InitializeDao.get(); + String[] sqlpaths = { + "/org/support/project/knowledge/deploy/v0_5_3pre2/migrate.sql" + }; + initializeDao.initializeDatabase(sqlpaths); + + List users = UsersDao.get().selectAll(); + UserGroupsDao userGroupsDao = UserGroupsDao.get(); + for (UsersEntity usersEntity : users) { + UserGroupsEntity userGroupsEntity = new UserGroupsEntity(); + userGroupsEntity.setUserId(usersEntity.getUserId()); + userGroupsEntity.setGroupId(0); //ALL + userGroupsEntity.setGroupRole(CommonWebParameter.GROUP_ROLE_MEMBER); + userGroupsDao.save(userGroupsEntity); + } + return true; + } + + +} diff --git a/src/main/java/org/support/project/knowledge/deploy/v0_5_3pre3/Migrate_0_5_3pre3.java b/src/main/java/org/support/project/knowledge/deploy/v0_5_3pre3/Migrate_0_5_3pre3.java new file mode 100644 index 000000000..bac0e7de5 --- /dev/null +++ b/src/main/java/org/support/project/knowledge/deploy/v0_5_3pre3/Migrate_0_5_3pre3.java @@ -0,0 +1,30 @@ +package org.support.project.knowledge.deploy.v0_5_3pre3; + +import java.util.List; + +import org.support.project.common.util.StringUtils; +import org.support.project.knowledge.deploy.Migrate; +import org.support.project.web.dao.UsersDao; +import org.support.project.web.entity.UsersEntity; + +public class Migrate_0_5_3pre3 implements Migrate { + + public static Migrate_0_5_3pre3 get() { + return org.support.project.di.Container.getComp(Migrate_0_5_3pre3.class); + } + + @Override + public boolean doMigrate() throws Exception { + List users = UsersDao.get().selectAll(); + for (UsersEntity usersEntity : users) { + if (StringUtils.isEmailAddress(usersEntity.getUserKey())) { + usersEntity.setMailAddress(usersEntity.getUserKey()); + usersEntity.setEncrypted(true); + UsersDao.get().save(usersEntity); + } + } + return true; + } + + +} diff --git a/src/main/java/org/support/project/knowledge/listener/CloseAbleAuthenticationFilter.java b/src/main/java/org/support/project/knowledge/listener/CloseAbleAuthenticationFilter.java new file mode 100644 index 000000000..589acfdbd --- /dev/null +++ b/src/main/java/org/support/project/knowledge/listener/CloseAbleAuthenticationFilter.java @@ -0,0 +1,98 @@ +package org.support.project.knowledge.listener; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.support.project.common.util.StringUtils; +import org.support.project.knowledge.config.AppConfig; +import org.support.project.knowledge.config.SystemConfig; +import org.support.project.knowledge.logic.SystemConfigLogic; +import org.support.project.web.common.HttpStatus; +import org.support.project.web.common.HttpUtil; +import org.support.project.web.dao.SystemConfigsDao; +import org.support.project.web.entity.SystemConfigsEntity; +import org.support.project.web.filter.AuthenticationFilter; + +public class CloseAbleAuthenticationFilter extends AuthenticationFilter { + + private Pattern pattern = null; + + /* (non-Javadoc) + * @see org.support.project.web.filter.AuthenticationFilter#init(javax.servlet.FilterConfig) + */ + @Override + public void init(FilterConfig filterconfig) throws ServletException { + SystemConfigsDao dao = SystemConfigsDao.get(); + SystemConfigsEntity config = dao.selectOnKey(SystemConfig.SYSTEM_EXPOSE_TYPE, AppConfig.get().getSystemName()); + if (config != null) { + if (SystemConfig.SYSTEM_EXPOSE_TYPE_CLOSE.equals(config.getConfigValue())) { + SystemConfigLogic.get().setClose(true); + } + } + String ignoreRegularExpression = filterconfig.getInitParameter("close-ignore-regular-expression"); + if (StringUtils.isNotEmpty(ignoreRegularExpression)) { + this.pattern = Pattern.compile(ignoreRegularExpression); + } + super.init(filterconfig); + } + + + + /* (non-Javadoc) + * @see org.support.project.web.filter.AuthenticationFilter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) + */ + @Override + public void doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain) throws IOException, + ServletException { + if (SystemConfigLogic.get().isClose()) { + HttpServletRequest req = (HttpServletRequest) servletrequest; + HttpServletResponse res = (HttpServletResponse) servletresponse; + try { + if (!isLogin(req)) { + cookieLogin(req, res); + } + + if (!isLogin(req)) { + // ログインしていない + if (pattern != null) { + StringBuilder pathBuilder = new StringBuilder(); + pathBuilder.append(req.getServletPath()); + if (req.getPathInfo() != null && req.getPathInfo().length() > 0) { + pathBuilder.append(req.getPathInfo()); + } + String path = pathBuilder.toString(); + Matcher matcher = pattern.matcher(path); + if (!matcher.find() && !path.equals(getLoginProcess())) { + // 対象外でないし、ログインページへの遷移でない + String page = req.getParameter("page"); + req.setAttribute("page", page); + + res.setStatus(HttpStatus.SC_401_UNAUTHORIZED); + StringBuilder builder = new StringBuilder(); + builder.append(getLoginPage()); + HttpUtil.forward(res, req, builder.toString()); + return; + } + } + } + } catch (Exception e) { + throw new ServletException(e); + } + } + super.doFilter(servletrequest, servletresponse, filterchain); + } + + + + + +} diff --git a/src/main/java/org/support/project/knowledge/listener/CronListener.java b/src/main/java/org/support/project/knowledge/listener/CronListener.java index 80415d565..303e6ab53 100644 --- a/src/main/java/org/support/project/knowledge/listener/CronListener.java +++ b/src/main/java/org/support/project/knowledge/listener/CronListener.java @@ -1,6 +1,8 @@ package org.support.project.knowledge.listener; import java.io.File; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -12,10 +14,13 @@ import org.support.project.common.bat.JobResult; import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; +import org.support.project.common.util.StringUtils; import org.support.project.knowledge.bat.FileParseBat; import org.support.project.knowledge.bat.KnowledgeFileClearBat; import org.support.project.knowledge.bat.MailSendBat; import org.support.project.knowledge.bat.NotifyMailBat; +import org.support.project.knowledge.config.AppConfig; +import org.support.project.knowledge.config.SystemConfig; public class CronListener implements ServletContextListener { @@ -29,6 +34,10 @@ public class CronListener implements ServletContextListener { @Override public void contextInitialized(final ServletContextEvent sce) { + String rootPath = AppConfig.get().getBasePath(); + File logDir = new File(rootPath + "/logs"); + String envValue = System.getenv(SystemConfig.KNOWLEDGE_ENV_KEY); + service = new ScheduledThreadPoolExecutor(1); fileClearfuture = service.scheduleAtFixedRate(new Runnable() { @Override @@ -37,9 +46,13 @@ public void run() { // Java を別のVMで実行(添付ファイルの定期的なクリア) JavaJob job = new JavaJob(); + job.setCurrentDirectory(logDir); job.addjarDir(new File(sce.getServletContext().getRealPath("/WEB-INF/lib"))); job.addClassPathDir(new File(sce.getServletContext().getRealPath("/WEB-INF/classes"))); job.setMainClass(KnowledgeFileClearBat.class.getName()); + if (StringUtils.isNotEmpty(envValue)) { + job.addEnvironment(SystemConfig.KNOWLEDGE_ENV_KEY, envValue); + } try { JobResult result = job.execute(); if (LOG.isDebugEnabled()) { @@ -52,7 +65,7 @@ public void run() { LOG.error("Faild clear files.", e); } } - }, 10, 60, TimeUnit.MINUTES); // 10分後に実行、60分毎に実行 + }, 1, 60, TimeUnit.MINUTES); // 1分後に実行、60分毎に実行 parsefuture = service.scheduleAtFixedRate(new Runnable() { @Override @@ -60,9 +73,13 @@ public void run() { LOG.trace("called. [parsefuture]"); // Java を別のVMで実行(添付ファイルの中身を抽出し検索可能にする) JavaJob job = new JavaJob(); + job.setCurrentDirectory(logDir); job.addjarDir(new File(sce.getServletContext().getRealPath("/WEB-INF/lib"))); job.addClassPathDir(new File(sce.getServletContext().getRealPath("/WEB-INF/classes"))); job.setMainClass(FileParseBat.class.getName()); + if (StringUtils.isNotEmpty(envValue)) { + job.addEnvironment(SystemConfig.KNOWLEDGE_ENV_KEY, envValue); + } try { JobResult result = job.execute(); if (LOG.isDebugEnabled()) { @@ -75,7 +92,7 @@ public void run() { LOG.error("Faild parse.", e); } } - }, 120, 30, TimeUnit.SECONDS); // 30秒毎に実行 + }, 70, 60, TimeUnit.SECONDS); // 60秒毎に実行 mailfuture = service.scheduleAtFixedRate(new Runnable() { @Override @@ -83,9 +100,13 @@ public void run() { LOG.trace("called. [mailfuture]"); // Java を別のVMで実行(添付ファイルの中身を抽出し検索可能にする) JavaJob job = new JavaJob(); + job.setCurrentDirectory(logDir); job.addjarDir(new File(sce.getServletContext().getRealPath("/WEB-INF/lib"))); job.addClassPathDir(new File(sce.getServletContext().getRealPath("/WEB-INF/classes"))); job.setMainClass(MailSendBat.class.getName()); + if (StringUtils.isNotEmpty(envValue)) { + job.addEnvironment(SystemConfig.KNOWLEDGE_ENV_KEY, envValue); + } try { JobResult result = job.execute(); if (LOG.isDebugEnabled()) { @@ -98,7 +119,7 @@ public void run() { LOG.error("Failed send mail.", e); } } - }, 120, 10, TimeUnit.SECONDS); // 10秒毎に実行 + }, 50, 60, TimeUnit.SECONDS); // 60秒毎に実行 notifyfuture = service.scheduleAtFixedRate(new Runnable() { @Override @@ -106,13 +127,17 @@ public void run() { LOG.trace("called. [notifyfuture]"); // Java を別のVMで実行(添付ファイルの中身を抽出し検索可能にする) JavaJob job = new JavaJob(); + job.setCurrentDirectory(logDir); job.addjarDir(new File(sce.getServletContext().getRealPath("/WEB-INF/lib"))); job.addClassPathDir(new File(sce.getServletContext().getRealPath("/WEB-INF/classes"))); job.setMainClass(NotifyMailBat.class.getName()); + if (StringUtils.isNotEmpty(envValue)) { + job.addEnvironment(SystemConfig.KNOWLEDGE_ENV_KEY, envValue); + } try { JobResult result = job.execute(); - if (LOG.isTraceEnabled()) { - LOG.trace("finish NotifyMailBat [result]" + result.getResultCode()); + if (LOG.isDebugEnabled()) { + LOG.debug("finish NotifyMailBat [result]" + result.getResultCode()); } if (LOG.isTraceEnabled()) { LOG.trace(result.getStdout()); @@ -121,17 +146,36 @@ public void run() { LOG.error("Failed to Notify", e); } } - }, 120, 10, TimeUnit.SECONDS); // 10秒毎に実行 - + }, 40, 60, TimeUnit.SECONDS); // 60秒毎に実行 } @Override public void contextDestroyed(final ServletContextEvent sce) { - fileClearfuture.cancel(true); - parsefuture.cancel(true); - mailfuture.cancel(true); - notifyfuture.cancel(true); - service.shutdown(); + LOG.info("finish batch processes."); + try { + fileClearfuture.cancel(true); + fileClearfuture.get(); + } catch (Exception e) { + LOG.debug("An error has occurred in the end processing of the batch", e); // 基本は無視でOK + } + try { + parsefuture.cancel(true); + parsefuture.get(); + } catch (Exception e) { + LOG.debug("An error has occurred in the end processing of the batch", e); // 基本は無視でOK + } + try { + mailfuture.cancel(true); + mailfuture.get(); + } catch (Exception e) { + LOG.debug("An error has occurred in the end processing of the batch", e); // 基本は無視でOK + } + try { + notifyfuture.cancel(true); + service.shutdown(); + notifyfuture.get(); + } catch (Exception e) { + LOG.debug("An error has occurred in the end processing of the batch", e); // 基本は無視でOK + } } - } diff --git a/src/main/java/org/support/project/knowledge/listener/GlobalInitializationListener.java b/src/main/java/org/support/project/knowledge/listener/GlobalInitializationListener.java index 1a8af4f28..70b139b78 100644 --- a/src/main/java/org/support/project/knowledge/listener/GlobalInitializationListener.java +++ b/src/main/java/org/support/project/knowledge/listener/GlobalInitializationListener.java @@ -1,15 +1,41 @@ package org.support.project.knowledge.listener; +import java.io.File; + import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; +import org.apache.log4j.FileAppender; +import org.apache.log4j.Logger; +import org.support.project.common.log.Log; +import org.support.project.common.log.LogFactory; +import org.support.project.common.util.StringUtils; import org.support.project.knowledge.config.AppConfig; +import org.support.project.knowledge.config.SystemConfig; public class GlobalInitializationListener implements ServletContextListener { + private static Log LOG = LogFactory.getLog(GlobalInitializationListener.class); @Override public void contextInitialized(ServletContextEvent config) { - AppConfig.initEnvKey("KNOWLEDGE_HOME"); + AppConfig.initEnvKey(SystemConfig.KNOWLEDGE_ENV_KEY); + String envValue = System.getenv(SystemConfig.KNOWLEDGE_ENV_KEY); + if (StringUtils.isNotEmpty(envValue)) { + LOG.info("Env [" + SystemConfig.KNOWLEDGE_ENV_KEY + "] is [" + envValue + "]."); + } + + String rootPath = AppConfig.get().getBasePath(); + System.setProperty("user.dir", rootPath); + File logDir = new File(rootPath + "/logs"); + if (!logDir.exists()) { + logDir.mkdirs(); + } + Logger log = Logger.getRootLogger(); + FileAppender appendar= (FileAppender) log.getAppender("APP_FILEOUT"); + appendar.setFile(logDir + "/app.log"); + appendar.activateOptions();//変更の反映 + System.out.println("[APP LOG] " + logDir.getAbsolutePath() + "/app.log"); + LOG.info(logDir.getAbsolutePath()); } @Override diff --git a/src/main/java/org/support/project/knowledge/logic/AccountLogic.java b/src/main/java/org/support/project/knowledge/logic/AccountLogic.java index e7cd45dde..1c7bbd51d 100644 --- a/src/main/java/org/support/project/knowledge/logic/AccountLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/AccountLogic.java @@ -17,6 +17,8 @@ import org.support.project.common.validate.Validator; import org.support.project.common.validate.ValidatorFactory; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.dao.AccountImagesDao; import org.support.project.knowledge.entity.AccountImagesEntity; import org.support.project.knowledge.vo.UploadFile; @@ -26,6 +28,7 @@ import org.support.project.web.entity.ConfirmMailChangesEntity; import org.support.project.web.entity.UsersEntity; +@DI(instance=Instance.Singleton) public class AccountLogic { /** ログ */ private static Log LOG = LogFactory.getLog(AccountLogic.class); @@ -195,6 +198,7 @@ public List completeChangeEmailRequest(String id, LoginedUser log errors.add(error); } else { usersEntity.setUserKey(mailChangesEntity.getMailAddress()); + usersEntity.setMailAddress(mailChangesEntity.getMailAddress()); usersDao.update(usersEntity); } // メール変更を無効化 diff --git a/src/main/java/org/support/project/knowledge/logic/CompressLogic.java b/src/main/java/org/support/project/knowledge/logic/CompressLogic.java index 4afc18619..d218d9353 100644 --- a/src/main/java/org/support/project/knowledge/logic/CompressLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/CompressLogic.java @@ -17,7 +17,10 @@ import org.support.project.common.log.LogFactory; import org.support.project.common.util.StringUtils; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; +@DI(instance=Instance.Singleton) public class CompressLogic { /** ログ */ private static Log LOG = LogFactory.getLog(CompressLogic.class); diff --git a/src/main/java/org/support/project/knowledge/logic/DataTransferLogic.java b/src/main/java/org/support/project/knowledge/logic/DataTransferLogic.java index 8c7b41825..37a14952e 100644 --- a/src/main/java/org/support/project/knowledge/logic/DataTransferLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/DataTransferLogic.java @@ -21,6 +21,8 @@ import org.support.project.common.log.LogFactory; import org.support.project.common.util.DateUtils; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.config.AppConfig; import org.support.project.knowledge.deploy.InitDB; import org.support.project.ormapping.config.ConnectionConfig; @@ -31,6 +33,7 @@ import org.support.project.web.dao.SystemsDao; import org.support.project.web.entity.SystemsEntity; +@DI(instance=Instance.Singleton) public class DataTransferLogic { private static final String TRANSFER_REQEST = "TRANSFER_REQEST"; private static final String TRANSFER_REQEST_BACK = "TRANSFER_REQEST_BACK"; @@ -47,7 +50,7 @@ public void transferData(ConnectionConfig from, ConnectionConfig to) throws Exce // FromのDBのDBのバージョンチェック ConnectionManager.getInstance().addConnectionConfig(from); SystemsDao systemsDao = SystemsDao.get(); - SystemsEntity systemEntity = systemsDao.selectOnKey(AppConfig.SYSTEM_NAME); + SystemsEntity systemEntity = systemsDao.selectOnKey(AppConfig.get().getSystemName()); if (systemEntity == null) { // Systemバージョン情報が無い未初期化のDBからコピーしてもしょうがない System.out.println("Data transfer is failed."); diff --git a/src/main/java/org/support/project/knowledge/logic/DatabaseLogic.java b/src/main/java/org/support/project/knowledge/logic/DatabaseLogic.java index 5de20569a..702a137e8 100644 --- a/src/main/java/org/support/project/knowledge/logic/DatabaseLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/DatabaseLogic.java @@ -22,8 +22,11 @@ import org.support.project.common.util.FileUtil; import org.support.project.common.wrapper.FileInputStreamWithDeleteWrapper; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.config.AppConfig; +@DI(instance=Instance.Singleton) public class DatabaseLogic { /** ログ */ private static Log LOG = LogFactory.getLog(DatabaseLogic.class); diff --git a/src/main/java/org/support/project/knowledge/logic/DiffLogic.java b/src/main/java/org/support/project/knowledge/logic/DiffLogic.java index 87ce1ccca..275bc9666 100644 --- a/src/main/java/org/support/project/knowledge/logic/DiffLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/DiffLogic.java @@ -6,11 +6,14 @@ import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import difflib.Delta; import difflib.DiffUtils; import difflib.Patch; +@DI(instance=Instance.Singleton) public class DiffLogic { /** ログ */ private static Log LOG = LogFactory.getLog(DiffLogic.class); diff --git a/src/main/java/org/support/project/knowledge/logic/GroupLogic.java b/src/main/java/org/support/project/knowledge/logic/GroupLogic.java index 812ddcc7f..16292962f 100644 --- a/src/main/java/org/support/project/knowledge/logic/GroupLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/GroupLogic.java @@ -8,6 +8,8 @@ import org.support.project.common.log.LogFactory; import org.support.project.common.util.StringUtils; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.dao.ExUsersDao; import org.support.project.knowledge.dao.KnowledgeGroupsDao; import org.support.project.knowledge.dao.TargetsDao; @@ -15,12 +17,15 @@ import org.support.project.knowledge.vo.GroupUser; import org.support.project.web.bean.LabelValue; import org.support.project.web.bean.LoginedUser; +import org.support.project.web.bean.MessageResult; import org.support.project.web.config.CommonWebParameter; +import org.support.project.web.config.MessageStatus; import org.support.project.web.dao.GroupsDao; import org.support.project.web.dao.UserGroupsDao; import org.support.project.web.entity.GroupsEntity; import org.support.project.web.entity.UserGroupsEntity; +@DI(instance=Instance.Singleton) public class GroupLogic { /** ログ */ private static Log LOG = LogFactory.getLog(GroupLogic.class); @@ -260,6 +265,47 @@ public List selectGroupsOnKnowledgeId(Long knowledgeId) { TargetsDao groupsDao = TargetsDao.get(); return groupsDao.selectGroupsOnKnowledgeId(knowledgeId); } + + + /** + * グループ管理者におけるユーザの追加 + * @param loginedUser + * @param groupId + * @param users + * @return + */ + public MessageResult addUsers(LoginedUser loginedUser, Integer groupId, String users) { + GroupsDao groupsDao = GroupsDao.get(); + if (!loginedUser.isAdmin()) { + if (groupsDao.selectAccessAbleGroup(groupId, loginedUser) == null) { + MessageResult messageResult = new MessageResult(); + messageResult.setStatus(MessageStatus.Error.getValue()); + messageResult.setCode(org.support.project.web.common.HttpStatus.SC_403_FORBIDDEN); + return messageResult; // アクセス権がないユーザ + } + } + + UserGroupsDao userGroupsDao = UserGroupsDao.get(); + String[] split = users.split(","); + for (String string : split) { + if (string.startsWith(TargetLogic.ID_PREFIX_USER)) { + string = string.substring(TargetLogic.ID_PREFIX_USER.length()); + } + if (StringUtils.isInteger(string)) { + Integer user = Integer.parseInt(string); + if (userGroupsDao.selectOnKey(groupId, user) == null) { + UserGroupsEntity userGroupsEntity = new UserGroupsEntity(); + userGroupsEntity.setGroupId(groupId); + userGroupsEntity.setUserId(user); + userGroupsEntity.setGroupRole(CommonWebParameter.GROUP_ROLE_MEMBER); + userGroupsDao.insert(userGroupsEntity); + } + } + } + MessageResult messageResult = new MessageResult(); + messageResult.setMessage("message.success.insert"); + return messageResult; + } diff --git a/src/main/java/org/support/project/knowledge/logic/IndexLogic.java b/src/main/java/org/support/project/knowledge/logic/IndexLogic.java index d9c80a7fa..418b66e70 100644 --- a/src/main/java/org/support/project/knowledge/logic/IndexLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/IndexLogic.java @@ -5,6 +5,8 @@ import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.indexer.Indexer; import org.support.project.knowledge.indexer.IndexingValue; import org.support.project.knowledge.searcher.SearchResultValue; @@ -18,6 +20,7 @@ * @author Koda * */ +@DI(instance=Instance.Singleton) public class IndexLogic { /** ログ */ private static Log LOG = LogFactory.getLog(IndexLogic.class); diff --git a/src/main/java/org/support/project/knowledge/logic/KnowledgeLogic.java b/src/main/java/org/support/project/knowledge/logic/KnowledgeLogic.java index 17446fd25..dd18f7ee2 100644 --- a/src/main/java/org/support/project/knowledge/logic/KnowledgeLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/KnowledgeLogic.java @@ -14,6 +14,8 @@ import org.support.project.common.util.StringJoinBuilder; import org.support.project.common.util.StringUtils; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.bat.FileParseBat; import org.support.project.knowledge.config.IndexType; import org.support.project.knowledge.dao.CommentsDao; @@ -47,6 +49,7 @@ import org.support.project.web.bean.LoginedUser; import org.support.project.web.entity.GroupsEntity; +@DI(instance=Instance.Singleton) public class KnowledgeLogic { /** ログ */ private static Log LOG = LogFactory.getLog(KnowledgeLogic.class); @@ -94,6 +97,15 @@ public List manegeTags(String tags) { } for (String tag : splits) { + tag = tag.trim(); + if (tag.startsWith(" ")) { + tag = tag.substring(" ".length()); + } + if (tag.startsWith(" ")) { + tag = tag.substring(" ".length()); + } + + TagsEntity tagsEntity = tagsDao.selectOnTagName(tag); if (tagsEntity == null) { tagsEntity = new TagsEntity(); @@ -385,41 +397,24 @@ private List searchKnowledge(SearchingValue searchingValue) th return result; } - /** - * ナレッジの検索 + * ナレッジ検索 * @param keyword + * @param tags * @param loginedUser - * @param offset - * @param limit + * @param i + * @param pageLimit * @return - * @throws Exception + * @throws Exception */ - public List searchKnowledge(String keyword, LoginedUser loginedUser, Integer offset, Integer limit) throws Exception { + public List searchKnowledge(String keyword, List tags, + LoginedUser loginedUser, Integer offset, Integer limit) throws Exception { SearchingValue searchingValue = new SearchingValue(); searchingValue.setKeyword(keyword); searchingValue.setOffset(offset); searchingValue.setLimit(limit); - if (loginedUser != null && loginedUser.isAdmin()) { - // 管理者の場合はユーザのアクセス権を考慮しないので、何もセットしない - -// DBからの直接取得はやめた -// if (StringUtils.isEmpty(keyword)) { -// //キーワードが指定されていなければDBから直接取得 -// List list = knowledgesDao.selectKnowledge(offset, limit, loginedUser.getUserId()); -// for (KnowledgesEntity entity : list) { -// entity.setContent(org.apache.commons.lang.StringUtils.abbreviate(entity.getContent(), LuceneSearcher.CONTENTS_LIMIT_LENGTH)); -// // タグを取得(1件づつ処理するのでパフォーマンス悪いかも?) -// setTags(entity); -// // いいねの回数 -// setLikeCount(entity); -// // コメント件数 -// setCommentsCount(entity); -// } -// return list; -// } - } else { + if (loginedUser == null || !loginedUser.isAdmin()) { searchingValue.addUser(ALL_USER); Integer userId = null; if (loginedUser != null) { @@ -434,8 +429,26 @@ public List searchKnowledge(String keyword, LoginedUser logine } } } + if (tags != null && !tags.isEmpty()) { + for (TagsEntity tagsEntity : tags) { + searchingValue.addTag(tagsEntity.getTagId()); + } + } return searchKnowledge(searchingValue); } + + /** + * ナレッジの検索 + * @param keyword + * @param loginedUser + * @param offset + * @param limit + * @return + * @throws Exception + */ + public List searchKnowledge(String keyword, LoginedUser loginedUser, Integer offset, Integer limit) throws Exception { + return searchKnowledge(keyword, null, loginedUser, offset, limit); + } /** * ナレッジをタグ指定で表示 @@ -1054,4 +1067,5 @@ public boolean isEditor(LoginedUser loginedUser, KnowledgesEntity entity, List users = usersDao.selectOnRoleKey(SystemConfig.ROLE_ADMIN); + List users = usersDao.selectOnRoleKey(WebConfig.ROLE_ADMIN); for (UsersEntity entity : users) { + if (!StringUtils.isEmailAddress(entity.getMailAddress())) { + // 送信先のメールアドレスが不正なので、送信処理は終了 + LOG.warn("mail targget [" + entity.getMailAddress() + "] is wrong."); + continue; + } Locale locale = entity.getLocale(); MailConfig mailConfig = load("notify_add_user", locale); @@ -209,7 +218,7 @@ public void sendNotifyAddUser(UsersEntity user) { String mailId = idGen("Notify"); mailsEntity.setMailId(mailId); mailsEntity.setStatus(MailSendBat.MAIL_STATUS_UNSENT); - mailsEntity.setToAddress(entity.getUserKey()); + mailsEntity.setToAddress(entity.getMailAddress()); mailsEntity.setToName(entity.getUserName()); mailsEntity.setTitle(title); mailsEntity.setContent(contents); @@ -225,7 +234,7 @@ public void sendNotifyAddUser(UsersEntity user) { */ public void sendNotifyAcceptUser(ProvisionalRegistrationsEntity registrationsEntity) { MailConfigsDao mailConfigsDao = MailConfigsDao.get(); - MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(org.support.project.knowledge.config.AppConfig.SYSTEM_NAME); + MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(org.support.project.knowledge.config.AppConfig.get().getSystemName()); if (mailConfigsEntity == null) { // メールの設定が登録されていなければ、送信処理は終了 return; @@ -233,12 +242,17 @@ public void sendNotifyAcceptUser(ProvisionalRegistrationsEntity registrationsEnt LOG.trace("sendNotifyAcceptUser"); SystemConfigsDao configsDao = SystemConfigsDao.get(); - SystemConfigsEntity configsEntity = configsDao.selectOnKey(SystemConfig.USER_ADD_NOTIFY, AppConfig.SYSTEM_NAME); + SystemConfigsEntity configsEntity = configsDao.selectOnKey(SystemConfig.USER_ADD_NOTIFY, AppConfig.get().getSystemName()); if (configsEntity != null && SystemConfig.USER_ADD_NOTIFY_ON.equals(configsEntity.getConfigValue())) { // 管理者へのメール通知がONなので、メールを送信する UsersDao usersDao = UsersDao.get(); - List users = usersDao.selectOnRoleKey(SystemConfig.ROLE_ADMIN); + List users = usersDao.selectOnRoleKey(WebConfig.ROLE_ADMIN); for (UsersEntity entity : users) { + if (!StringUtils.isEmailAddress(entity.getMailAddress())) { + // 送信先のメールアドレスが不正なので、送信処理は終了 + LOG.warn("mail targget [" + entity.getMailAddress() + "] is wrong."); + continue; + } Locale locale = entity.getLocale(); MailConfig mailConfig = load("notify_accept_user", locale); @@ -250,7 +264,7 @@ public void sendNotifyAcceptUser(ProvisionalRegistrationsEntity registrationsEnt String mailId = idGen("Notify"); mailsEntity.setMailId(mailId); mailsEntity.setStatus(MailSendBat.MAIL_STATUS_UNSENT); - mailsEntity.setToAddress(entity.getUserKey()); + mailsEntity.setToAddress(entity.getMailAddress()); mailsEntity.setToName(entity.getUserName()); mailsEntity.setTitle(title); mailsEntity.setContent(contents); @@ -268,7 +282,7 @@ public void sendNotifyAcceptUser(ProvisionalRegistrationsEntity registrationsEnt */ public void sendPasswordReset(String email, Locale locale, PasswordResetsEntity resetsEntity) { MailConfigsDao mailConfigsDao = MailConfigsDao.get(); - MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(org.support.project.knowledge.config.AppConfig.SYSTEM_NAME); + MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(org.support.project.knowledge.config.AppConfig.get().getSystemName()); if (mailConfigsEntity == null) { // メールの設定が登録されていなければ、送信処理は終了 return; @@ -302,7 +316,7 @@ public void sendPasswordReset(String email, Locale locale, PasswordResetsEntity */ public void sendChangeEmailRequest(ConfirmMailChangesEntity mailChangesEntity, LoginedUser loginedUser) { MailConfigsDao mailConfigsDao = MailConfigsDao.get(); - MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(org.support.project.knowledge.config.AppConfig.SYSTEM_NAME); + MailConfigsEntity mailConfigsEntity = mailConfigsDao.selectOnKey(org.support.project.knowledge.config.AppConfig.get().getSystemName()); if (mailConfigsEntity == null) { // メールの設定が登録されていなければ、送信処理は終了 return; diff --git a/src/main/java/org/support/project/knowledge/logic/MarkdownLogic.java b/src/main/java/org/support/project/knowledge/logic/MarkdownLogic.java new file mode 100644 index 000000000..4f8e62171 --- /dev/null +++ b/src/main/java/org/support/project/knowledge/logic/MarkdownLogic.java @@ -0,0 +1,180 @@ +package org.support.project.knowledge.logic; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; +import java.util.Date; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; + +import org.pegdown.Extensions; +import org.pegdown.LinkRenderer; +import org.pegdown.PegDownProcessor; +import org.pegdown.ast.AnchorLinkNode; +import org.support.project.common.exception.ParseException; +import org.support.project.common.log.Log; +import org.support.project.common.log.LogFactory; +import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; +import org.support.project.knowledge.vo.MarkDown; +import org.support.project.web.logic.SanitizingLogic; + +@DI(instance = Instance.Singleton) +public class MarkdownLogic { + /** ログ */ + private static Log LOG = LogFactory.getLog(MarkdownLogic.class); + + public static final int ENGINE_PEGDOWN = 1; + public static final int ENGINE_MARKEDJS = 2; + + private ScriptEngine engine = null; + private boolean initEngine = false; + + public static MarkdownLogic get() { + return Container.getComp(MarkdownLogic.class); + } + + /** + * マークダウンをパースしてHTMLを取得 + * @param markdown + * @return + * @throws ParseException + */ + public MarkDown markdownToHtml(String markdown) throws ParseException { + return markdownToHtml(markdown, ENGINE_PEGDOWN); + } + /** + * マークダウンをパースしてHTMLを取得(エンジンを指定) + * @param markdown + * @param engine + * @return + * @throws ParseException + */ + public MarkDown markdownToHtml(String markdown, int engine) throws ParseException { + MarkDown result = new MarkDown(); + if (engine == ENGINE_MARKEDJS) { + markdownToHtmlOnMarkedJs(markdown, result); + } else { + markdownToHtmlOnPegDown(markdown, result); + } + return sanitize(markdown, result); + } + + + /** + * サニタイジング + * @param markdown + * @param result + * @return + * @throws ParseException + */ + private MarkDown sanitize(String markdown, MarkDown result) throws ParseException { + try { + String html = result.getHtml(); + if (LOG.isDebugEnabled()) { + LOG.debug("[Markdown] : " + markdown); + LOG.debug("[ParsedHtml] : " + html); + } + // 危険なHTMLは削除 + html = SanitizingLogic.get().sanitize(html); + if (LOG.isDebugEnabled()) { + LOG.debug("[SanitizeHtml] : " + html); + } + result.setHtml(html); + return result; + } catch (Exception e) { + // サニタイズではエラーにならないはず + throw new ParseException(e); + } + } + + /** + * PegDownでMarkDownのパース + * @param markdown + * @param result + */ + private void markdownToHtmlOnPegDown(String markdown, MarkDown result) { + Date start = new Date(); + result.setMarkdown(markdown); + String html = markdown; + try { + // Markdownのパース + PegDownProcessor processor = new PegDownProcessor(Extensions.ALL - Extensions.ANCHORLINKS); + html = processor.markdownToHtml(markdown, new LinkRenderer() { + @Override + public Rendering render(AnchorLinkNode node) { + return new Rendering(node.getText(), node.getText()); + } + }); + result.setHtml(html); + result.setParsed(true); + if (LOG.isDebugEnabled()) { + Date end = new Date(); + LOG.debug("Parse time (PegDown): " + (end.getTime() - start.getTime()) + " [ms]"); + } + } catch (Exception e) { + // Markdownのパースに失敗する事がある + LOG.error("Markdown parse error.", e); + // PegDownをデフォルトとして、失敗した場合、Marked.jsでパースしてみる + markdownToHtmlOnMarkedJs(markdown, result); + } + } + + private ScriptEngine getScriptEngine() throws ScriptException, IOException { + if (initEngine) { + return engine; + } + ScriptEngineManager manager = new ScriptEngineManager(); + engine = manager.getEngineByName("js"); + if (engine == null) { + System.out.println("JavaScriptはサポート外"); + initEngine = true; + return null; + } + Reader fr = null; + try { + fr = new InputStreamReader(this.getClass().getResourceAsStream("/org/support/project/knowledge/logic/marked.js"), Charset.forName("UTF-8")); + engine.eval(fr); + initEngine = true; + return engine; + } finally { + if (fr != null) { + fr.close(); + } + } + } + + + /** + * marked.jsでMarkDownのパース + * @param markdown + * @param result + */ + private void markdownToHtmlOnMarkedJs(String markdown, MarkDown result) { + Date start = new Date(); + result.setMarkdown(markdown); + String html = markdown; + try { + engine = getScriptEngine(); + if (engine == null) { + return; + } + engine.put("content", markdown); + html = (String) engine.eval("marked(content)"); + result.setHtml(html); + result.setParsed(true); + if (LOG.isDebugEnabled()) { + Date end = new Date(); + LOG.debug("Parse time (marked.js): " + (end.getTime() - start.getTime()) + " [ms]"); + } + } catch (Exception e) { + LOG.error("Markdown parse error.", e); + } + } + + +} diff --git a/src/main/java/org/support/project/knowledge/logic/NotifyLogic.java b/src/main/java/org/support/project/knowledge/logic/NotifyLogic.java index 37e934e86..4760e78c6 100644 --- a/src/main/java/org/support/project/knowledge/logic/NotifyLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/NotifyLogic.java @@ -7,7 +7,10 @@ import org.support.project.common.config.Resources; import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; +import org.support.project.common.util.NumberUtils; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.dao.KnowledgeGroupsDao; import org.support.project.knowledge.dao.KnowledgeUsersDao; import org.support.project.knowledge.dao.KnowledgesDao; @@ -26,6 +29,7 @@ import org.support.project.web.bean.MessageResult; import org.support.project.web.entity.GroupsEntity; +@DI(instance=Instance.Singleton) public class NotifyLogic { /** ログ */ private static Log LOG = LogFactory.getLog(NotifyLogic.class); @@ -42,7 +46,26 @@ private void notify(Notify notify) { // Mail通知 NotifyQueuesDao notifyQueuesDao = NotifyQueuesDao.get(); NotifyQueuesEntity notifyQueuesEntity = notify.getQueue(); - notifyQueuesDao.insert(notifyQueuesEntity); + // 重複チェックし + if (NumberUtils.is(notifyQueuesEntity.getType(), Notify.TYPE_KNOWLEDGE_INSERT)) { + // ナレッジの新規登録は必ず通知のキューに入れる + notifyQueuesDao.insert(notifyQueuesEntity); + } else if (NumberUtils.is(notifyQueuesEntity.getType(), Notify.TYPE_KNOWLEDGE_UPDATE)) { + // ナレッジが更新された場合、キューに「登録通知」もしくは「更新通知」が存在しているのであれば登録しない + NotifyQueuesEntity exist = notifyQueuesDao.selectOnTypeAndId(notifyQueuesEntity.getType(), notifyQueuesEntity.getId()); + if (exist == null) { + exist = notifyQueuesDao.selectOnTypeAndId(Notify.TYPE_KNOWLEDGE_INSERT, notifyQueuesEntity.getId()); + if (exist == null) { + notifyQueuesDao.insert(notifyQueuesEntity); + } + } + } else if (NumberUtils.is(notifyQueuesEntity.getType(), Notify.TYPE_KNOWLEDGE_LIKE) + || NumberUtils.is(notifyQueuesEntity.getType(), Notify.TYPE_KNOWLEDGE_COMMENT)) { + NotifyQueuesEntity exist = notifyQueuesDao.selectOnTypeAndId(notifyQueuesEntity.getType(), notifyQueuesEntity.getId()); + if (exist == null) { + notifyQueuesDao.insert(notifyQueuesEntity); + } + } // Desktop通知 NotifyAction notifyAction = Container.getComp(NotifyAction.class); diff --git a/src/main/java/org/support/project/knowledge/logic/PasswordInitializationLogic.java b/src/main/java/org/support/project/knowledge/logic/PasswordInitializationLogic.java index 31b4d444a..5dfd61c1f 100644 --- a/src/main/java/org/support/project/knowledge/logic/PasswordInitializationLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/PasswordInitializationLogic.java @@ -1,31 +1,21 @@ package org.support.project.knowledge.logic; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; import java.util.Locale; -import java.util.UUID; import org.support.project.aop.Aspect; import org.support.project.common.bean.ValidateError; -import org.support.project.common.config.LocaleConfigLoader; import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.common.util.RandomUtil; import org.support.project.di.Container; -import org.support.project.knowledge.bat.MailSendBat; -import org.support.project.knowledge.config.AppConfig; -import org.support.project.knowledge.config.MailConfig; -import org.support.project.knowledge.config.SystemConfig; -import org.support.project.web.dao.MailsDao; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.web.dao.PasswordResetsDao; -import org.support.project.web.dao.SystemConfigsDao; import org.support.project.web.dao.UsersDao; -import org.support.project.web.entity.MailsEntity; import org.support.project.web.entity.PasswordResetsEntity; -import org.support.project.web.entity.SystemConfigsEntity; import org.support.project.web.entity.UsersEntity; +@DI(instance=Instance.Singleton) public class PasswordInitializationLogic { /** ログ */ private static Log LOG = LogFactory.getLog(PasswordInitializationLogic.class); diff --git a/src/main/java/org/support/project/knowledge/logic/SystemConfigLogic.java b/src/main/java/org/support/project/knowledge/logic/SystemConfigLogic.java index e00e9519e..49e8ad3b4 100644 --- a/src/main/java/org/support/project/knowledge/logic/SystemConfigLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/SystemConfigLogic.java @@ -3,15 +3,22 @@ import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.config.AppConfig; import org.support.project.knowledge.config.SystemConfig; +import org.support.project.web.dao.LdapConfigsDao; import org.support.project.web.dao.SystemConfigsDao; +import org.support.project.web.entity.LdapConfigsEntity; import org.support.project.web.entity.SystemConfigsEntity; +@DI(instance=Instance.Singleton) public class SystemConfigLogic { /** ログ */ private static Log LOG = LogFactory.getLog(SystemConfigLogic.class); - + + private boolean close = false; + public static SystemConfigLogic get() { return Container.getComp(SystemConfigLogic.class); } @@ -22,15 +29,35 @@ public static SystemConfigLogic get() { */ public boolean isUserAddAble() { SystemConfigsDao systemConfigsDao = SystemConfigsDao.get(); - SystemConfigsEntity userAddType = systemConfigsDao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.SYSTEM_NAME); + SystemConfigsEntity userAddType = systemConfigsDao.selectOnKey(SystemConfig.USER_ADD_TYPE, AppConfig.get().getSystemName()); if (userAddType == null) { return false; } if (userAddType.getConfigValue().equals(SystemConfig.USER_ADD_TYPE_VALUE_ADMIN)) { return false; } + + LdapConfigsDao ldapConfigsDao = LdapConfigsDao.get(); + LdapConfigsEntity ldapConfigsEntity = ldapConfigsDao.selectOnKey(AppConfig.get().getSystemName()); + if (ldapConfigsEntity != null && ldapConfigsEntity.getAuthType().intValue() == LdapConfigsEntity.AUTH_TYPE_LDAP) { + return false; // Ldapでのみ認証するので、新規ユーザの追加はできない + } return true; } + + /** + * @return the close + */ + public boolean isClose() { + return close; + } + + /** + * @param close the close to set + */ + public void setClose(boolean close) { + this.close = close; + } diff --git a/src/main/java/org/support/project/knowledge/logic/TagLogic.java b/src/main/java/org/support/project/knowledge/logic/TagLogic.java index 57f1d7aa5..756055a2c 100644 --- a/src/main/java/org/support/project/knowledge/logic/TagLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/TagLogic.java @@ -6,11 +6,14 @@ import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.dao.TagsDao; import org.support.project.knowledge.entity.TagsEntity; import org.support.project.web.bean.LoginedUser; import org.support.project.web.entity.GroupsEntity; +@DI(instance=Instance.Singleton) public class TagLogic { /** ログ */ private static Log LOG = LogFactory.getLog(TagLogic.class); @@ -19,8 +22,6 @@ public static TagLogic get() { return Container.getComp(TagLogic.class); } - private TagsDao tagsDao = TagsDao.get(); - /** * タグの一覧を取得 * 同時に、ナレッジの件数も取得する diff --git a/src/main/java/org/support/project/knowledge/logic/TargetLogic.java b/src/main/java/org/support/project/knowledge/logic/TargetLogic.java index b8abe9da9..7719dea96 100644 --- a/src/main/java/org/support/project/knowledge/logic/TargetLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/TargetLogic.java @@ -7,6 +7,8 @@ import org.support.project.common.log.LogFactory; import org.support.project.common.util.StringUtils; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.dao.TargetsDao; import org.support.project.web.bean.LabelValue; import org.support.project.web.bean.LoginedUser; @@ -15,15 +17,16 @@ import org.support.project.web.entity.GroupsEntity; import org.support.project.web.entity.UsersEntity; +@DI(instance=Instance.Singleton) public class TargetLogic { /** ログ */ private static Log LOG = LogFactory.getLog(TargetLogic.class); - private static final String ID_PREFIX_GROUP = "G-"; - private static final String ID_PREFIX_USER = "U-"; + public static final String ID_PREFIX_GROUP = "G-"; + public static final String ID_PREFIX_USER = "U-"; - private static final String NAME_PREFIX_GROUP = "[GROUP] "; - private static final String NAME_PREFIX_USER = "[USER] "; + public static final String NAME_PREFIX_GROUP = "[GROUP] "; + public static final String NAME_PREFIX_USER = "[USER] "; public static TargetLogic get() { return Container.getComp(TargetLogic.class); @@ -165,5 +168,18 @@ public Integer getUserId(String str) { return Integer.MIN_VALUE; } + public List selectUsersOnKeyword(String keyword, LoginedUser loginedUser, int offset, int limit) { + UsersDao usersDao = UsersDao.get(); + List users = usersDao.selectOnKeyword(offset, limit, keyword); + List list = new ArrayList<>(); + for (UsersEntity user : users) { + LabelValue labelValue = new LabelValue(); + labelValue.setValue(ID_PREFIX_USER + user.getUserId()); + labelValue.setLabel(NAME_PREFIX_USER + user.getUserName()); + list.add(labelValue); + } + return list; + } + } diff --git a/src/main/java/org/support/project/knowledge/logic/UploadedFileLogic.java b/src/main/java/org/support/project/knowledge/logic/UploadedFileLogic.java index ea893f409..a2a18f52b 100644 --- a/src/main/java/org/support/project/knowledge/logic/UploadedFileLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/UploadedFileLogic.java @@ -12,12 +12,15 @@ import org.support.project.common.log.Log; import org.support.project.common.log.LogFactory; import org.support.project.di.Container; +import org.support.project.di.DI; +import org.support.project.di.Instance; import org.support.project.knowledge.dao.KnowledgeFilesDao; import org.support.project.knowledge.entity.KnowledgeFilesEntity; import org.support.project.knowledge.entity.KnowledgesEntity; import org.support.project.knowledge.vo.UploadFile; import org.support.project.web.bean.LoginedUser; +@DI(instance=Instance.Singleton) public class UploadedFileLogic { /** ログ */ private static Log LOG = LogFactory.getLog(UploadedFileLogic.class); diff --git a/src/main/java/org/support/project/knowledge/logic/UserLogic.java b/src/main/java/org/support/project/knowledge/logic/UserLogic.java index 3a9383b89..af8257d04 100644 --- a/src/main/java/org/support/project/knowledge/logic/UserLogic.java +++ b/src/main/java/org/support/project/knowledge/logic/UserLogic.java @@ -1,183 +1,31 @@ package org.support.project.knowledge.logic; -import java.util.HashMap; -import java.util.List; import java.util.Locale; -import java.util.Map; -import org.support.project.aop.Aspect; -import org.support.project.common.config.INT_FLAG; -import org.support.project.common.config.Resources; -import org.support.project.common.log.Log; -import org.support.project.common.log.LogFactory; -import org.support.project.common.util.RandomUtil; import org.support.project.di.Container; -import org.support.project.knowledge.config.SystemConfig; -import org.support.project.web.bean.LoginedUser; -import org.support.project.web.dao.ProvisionalRegistrationsDao; -import org.support.project.web.dao.RolesDao; -import org.support.project.web.dao.UserRolesDao; -import org.support.project.web.dao.UsersDao; -import org.support.project.web.entity.ProvisionalRegistrationsEntity; -import org.support.project.web.entity.RolesEntity; -import org.support.project.web.entity.UserRolesEntity; -import org.support.project.web.entity.UsersEntity; +import org.support.project.di.DI; +import org.support.project.di.Instance; -public class UserLogic { - /** ログ */ - private static Log LOG = LogFactory.getLog(UserLogic.class); +@DI(instance=Instance.Singleton) +public class UserLogic extends org.support.project.web.logic.UserLogic { - private UsersDao usersDao = UsersDao.get(); - private RolesDao rolesDao = RolesDao.get(); - private UserRolesDao userRolesDao = UserRolesDao.get(); - public static UserLogic get() { return Container.getComp(UserLogic.class); } - - /** - * ユーザを新規登録 - * @param user - * @param roles - * @param loginedUser - * @return - */ - @Aspect(advice=org.support.project.ormapping.transaction.Transaction.class) - public UsersEntity insert(UsersEntity user, String[] roles, LoginedUser loginedUser) { - LOG.trace("insert"); - - user.setEncrypted(false); - user = usersDao.insert(user); - user.setPassword(""); - - // ロールをセット - insertRoles(user, roles); - - return user; - } - - - /** - * 仮登録から、本登録 - * @param user - * @param roles - * @param loginedUser - * @return - */ - @Aspect(advice=org.support.project.ormapping.transaction.Transaction.class) - public UsersEntity activate(ProvisionalRegistrationsEntity entity) { - LOG.trace("activate"); - - if (usersDao.selectOnUserKey(entity.getUserKey()) != null) { - // 仮登録のユーザが既に存在している - ProvisionalRegistrationsDao provisionalRegistrationsDao = ProvisionalRegistrationsDao.get(); - provisionalRegistrationsDao.deleteOnUserKey(entity.getUserKey()); - return null; - } - - UsersEntity user = new UsersEntity(); - user.setUserKey(entity.getUserKey()); - user.setUserName(entity.getUserName()); - user.setPassword(entity.getPassword()); - user.setSalt(entity.getSalt()); - user.setEncrypted(true); - String[] roles = {SystemConfig.ROLE_USER}; - - user = usersDao.insert(user); - user.setPassword(""); - - // ロールをセット - insertRoles(user, roles); - - // 仮登録の削除 - ProvisionalRegistrationsDao provisionalRegistrationsDao = ProvisionalRegistrationsDao.get(); - provisionalRegistrationsDao.deleteOnUserKey(entity.getUserKey()); - - return user; - } - /** - * ユーザ情報更新 - * @param user - * @param roles - * @param loginedUser - * @return - */ - @Aspect(advice=org.support.project.ormapping.transaction.Transaction.class) - public UsersEntity update(UsersEntity user, String[] roles, LoginedUser loginedUser) { - LOG.trace("update"); - - user = usersDao.update(user); - user.setPassword(""); - - // ロールをセット - insertRoles(user, roles); - - return user; - } - - /** - * ユーザのロールを登録 - * (デリートインサート - * @param user - * @param roles 設定されているID - * @param loginedUser - */ - private void insertRoles(UsersEntity user, String[] roles) { - if (LOG.isTraceEnabled()) { - LOG.trace(roles); - } - - // ユーザに紐づくロールを削除 - userRolesDao.deleteOnUser(user.getUserId()); - - // システムに登録されているロールを全て取得 - RolesDao rolesDao = RolesDao.get(); - List rolesEntities = rolesDao.selectAll(); - Map map = new HashMap(); - for (RolesEntity role : rolesEntities) { - map.put(role.getRoleKey(), role); - } - - // ユーザのロールを登録 - if (roles != null) { - for (String role : roles) { - RolesEntity entity = map.get(role); - if (entity != null) { - UserRolesEntity userRolesEntity = new UserRolesEntity(entity.getRoleId(), user.getUserId()); - userRolesDao.insert(userRolesEntity); - } - } - } - } - /** * 退会 * @param loginUserId * @param knowledgeRemove - * @param locale - * @throws Exception + * @param locale + * @throws Exception */ - @Aspect(advice=org.support.project.ormapping.transaction.Transaction.class) public void withdrawal(Integer loginUserId, boolean knowledgeRemove, Locale locale) throws Exception { - // アカウント削除 - UsersDao usersDao = UsersDao.get(); - UsersEntity user = usersDao.selectOnKey(loginUserId); - if (user != null) { - user.setPassword(RandomUtil.randamGen(32)); - user.setUserKey(RandomUtil.randamGen(32)); - Resources resources = Resources.getInstance(locale); - user.setUserName(resources.getResource("knowledge.withdrawal.label.name")); - user.setDeleteFlag(INT_FLAG.ON.getValue()); - usersDao.update(user); - usersDao.delete(loginUserId); - } - + super.withdrawal(loginUserId, locale); if (knowledgeRemove) { // ナレッジを削除 KnowledgeLogic.get().deleteOnUser(loginUserId); } } - } diff --git a/src/main/java/org/support/project/knowledge/vo/MarkDown.java b/src/main/java/org/support/project/knowledge/vo/MarkDown.java new file mode 100644 index 000000000..13315bea5 --- /dev/null +++ b/src/main/java/org/support/project/knowledge/vo/MarkDown.java @@ -0,0 +1,53 @@ +package org.support.project.knowledge.vo; + +public class MarkDown { + + private String markdown; + + private String html; + + private boolean parsed = false; + + /** + * @return the markdown + */ + public String getMarkdown() { + return markdown; + } + + /** + * @param markdown the markdown to set + */ + public void setMarkdown(String markdown) { + this.markdown = markdown; + } + + /** + * @return the html + */ + public String getHtml() { + return html; + } + + /** + * @param html the html to set + */ + public void setHtml(String html) { + this.html = html; + } + + /** + * @return the parsed + */ + public boolean isParsed() { + return parsed; + } + + /** + * @param parsed the parsed to set + */ + public void setParsed(boolean parsed) { + this.parsed = parsed; + } + +} diff --git a/src/main/resources/appconfig.xml b/src/main/resources/appconfig.xml index 6761467aa..74d0bb925 100644 --- a/src/main/resources/appconfig.xml +++ b/src/main/resources/appconfig.xml @@ -1,5 +1,6 @@ + knowledge Asia/Tokyo {user.home}/.knowledge {base.path}/index/ diff --git a/src/main/resources/appresource.properties b/src/main/resources/appresource.properties index b6c595e62..86893ffdf 100644 --- a/src/main/resources/appresource.properties +++ b/src/main/resources/appresource.properties @@ -53,7 +53,7 @@ message.allready.updated=Allready updated. message.allready.started=Allready started. # Common Label -label.version=0.5.2 +label.version=0.5.3 label.login=Sign in label.previous = Previous label.next=Next @@ -88,6 +88,7 @@ label.back=Back label.start=Start label.end=End label.stop=Stop +label.required=(required) label.public.view= [Public] label.protect.view= [Protection] @@ -191,6 +192,8 @@ knowledge.view.comment.with.login=Add Comment(Sign in) knowledge.view.like=Like! knowledge.search.title=Search Knowledge knowledge.search.placeholder=Search keyword +knowledge.search.keyword=Keyword +knowledge.search.tags=Tags knowledge.add.title=Add Knowledge knowledge.add.label.title=Title knowledge.add.label.content=Content @@ -248,6 +251,10 @@ knowledge.account.changekey.title=Change E-mail knowledge.account.label.email=Mail address after change (A mail for change confirmation is sent to the address of the designation.) knowledge.account.changekey.request=A request of mail address change was accepted. A mail for confirmation was sent to the new mail address, so receive a mail, and please complete mail address change processing. knowledge.account.changekey.complete=Mail address change has been completed. +knowledge.account.id=ID +knowledge.account.id.info1=In the case of registration by the administrator, ID can be set freely. +knowledge.account.id.info2=However, in the case of not in the e-mail address format ID, can not e-mail notification. +knowledge.account.mail=E-mail knowledge.withdrawal.title=Withdrawal knowledge.withdrawal.msg=You unsubscribe from Knowledge of service.
How do you the knowledge that you have registered up to now?
knowledge.withdrawal.label.remove=Remove @@ -286,6 +293,9 @@ knowledge.config.mail.smtppass.require=If you want to authentication, SMTP passw knowledge.config.mail=Mail transmission settings knowledge.config.system.title=System Config knowledge.config.system.label.url=Service URL +knowledge.config.system.open.title=Publishing Settings +knowledge.config.system.open=No login is required +knowledge.config.system.close=Login is required knowledge.accept.title=List of users awaiting approval knowledge.accept.label.list.empty=There is no user waiting for approval @@ -311,9 +321,9 @@ knowledge.group.view.label.subscribe.protect=Give the affiliation of the request knowledge.group.view.label.unsubscribe=I quit the belongs of groups knowledge.group.view.label.mygroup=MyGroups knowledge.group.view.label.list=Group list -knowledge.group.view.label.public= [Public] (it will appear in the list of groups. Anyone can join free.) -knowledge.group.view.label.protect= [Protection] (it will be displayed in the list of groups. In order to participate you will need the approval of the administrator of the group.) -knowledge.group.view.label.private= [Private] (it does not appear in the list of groups. Newly to add a user to a group, the administrator of the group will perform) +knowledge.group.view.label.public= [Public] (Anyone can join free.) +knowledge.group.view.label.protect= [Protection] (In order to participate you will need the approval of the administrator of the group.) +knowledge.group.view.label.private= [Private] (Newly to add a user to a group, the administrator of the group will perform) knowledge.group.view.label.change.admin=I want this user to the administrator of the group knowledge.group.view.label.change.member=I make this user a member of the group knowledge.group.view.label.change.none=I expulsion this user from a group @@ -326,11 +336,12 @@ knowledge.group.mylist.label.member= - You are group member - knowledge.group.mylist.label.wait= - It is in affiliation request (it does not yet belong) - knowledge.group.list.title=Group list knowledge.group.list.label.mylist=MyGroups +knowledge.group.list.empty=Empty knowledge.group.add.title=Add Group knowledge.group.edit.title=Edit Group -knowledge.group.edit.label.public=[Public] (it will appear in the list of groups. Anyone can join free.) -knowledge.group.edit.label.protect=[Protection] (it will be displayed in the list of groups. In order to participate you will need the approval of the administrator of the group.) -knowledge.group.edit.label.private=[Private] (it does not appear in the list of groups. Newly to add a user to a group, the administrator of the group will perform) +knowledge.group.edit.label.public=[Public] (Anyone can join free.) +knowledge.group.edit.label.protect=[Protection] (In order to participate you will need the approval of the administrator of the group.) +knowledge.group.edit.label.private=[Private] (Newly to add a user to a group, the administrator of the group will perform) knowledge.data.msg=You can perform management of data services (backup and restoration) knowledge.data.label.backup=Backup (data download) @@ -449,5 +460,36 @@ knowledge.sample.markdown.501=#### More info knowledge.sample.markdown.502=- [GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown/) knowledge.sample.markdown.preview=Preview this sample - +knowledge.ldap.title=Ldap config +knowledge.ldap.label.host=Host +knowledge.ldap.label.port=Port +knowledge.ldap.label.security=Security +knowledge.ldap.label.plain=Plain +knowledge.ldap.label.usessl=SSL +knowledge.ldap.label.usetls=TLS +knowledge.ldap.label.binddn=Bind DN +knowledge.ldap.label.bindpass=Bind Password +knowledge.ldap.label.basedn=Base DN +knowledge.ldap.label.filter=Filter +knowledge.ldap.label.idattr=Id Attribute +knowledge.ldap.label.nameattr=Name Attribute +knowledge.ldap.label.mailattr=Mail Address Attribute +knowledge.ldap.label.testid=ID +knowledge.ldap.label.testpass=Password +knowledge.ldap.label.adminid=Admin ID +knowledge.ldap.label.authtype=Auth type +knowledge.ldap.label.authtype.db=Log in with a user of the database +knowledge.ldap.label.authtype.ldap=Log in with a user of the Ldap +knowledge.ldap.label.authtype.both=Log in with a user of the database and ldap +knowledge.ldap.label.dotest=connect test +knowledge.ldap.msg.ldap=When you enable login using Ldap, to register the user to Knowledge for the first time the logged in timing. +knowledge.ldap.msg.adminid1=In this case, when you log in as a user that is specified in the "admin ID", to register as an administrator authority. +knowledge.ldap.msg.adminid2=When you log in as a user that has not been specified, registered in the general user privileges. +knowledge.ldap.msg.adminid3=If you have only to Ldap login, please specify at least one person a user to become administrator. (If the administrator does not have, you will not be able to change the settings) +knowledge.ldap.msg.adminid4=Even a user that is registered as a general user, by the administrator, you can change from the list of users to the administrative privileges. +knowledge.ldap.msg.connect.error=It can not be connected. LDAP configuration, or connection confirmation ID / password is incorrect. +knowledge.ldap.msg.connect.success=I was able to connect. [id] {1} [name] {2} [mail] {3} [admin] {4} +knowledge.ldap.msg.save.error=Can not be saved because the connection can not be confirmed. LDAP configuration, or connection confirmation ID / password is incorrect. +knowledge.ldap.msg.save.success=Saved. +knowledge.ldap.confirm.delete=Delete. is it OK? diff --git a/src/main/resources/appresource_ja.properties b/src/main/resources/appresource_ja.properties index 1ced54da7..24b696e2a 100644 --- a/src/main/resources/appresource_ja.properties +++ b/src/main/resources/appresource_ja.properties @@ -53,7 +53,7 @@ message.allready.updated=すでに更新されています message.allready.started=すでに開始済です # Common Label -label.version=0.5.2 +label.version=0.5.3 label.login=サインイン label.previous = 前へ label.next = 次へ @@ -88,6 +88,7 @@ label.back=戻る label.start=開始 label.end=終了 label.stop=停止 +label.required=(必須) label.public.view= [公開] label.protect.view= [保護] @@ -191,6 +192,8 @@ knowledge.view.comment.with.login=コメントを追加(サインイン) knowledge.view.like=参考になった! knowledge.search.title=ナレッジ検索 knowledge.search.placeholder=キーワードでナレッジを検索 +knowledge.search.keyword=検索キーワード +knowledge.search.tags=検索するタグを指定(OR条件) knowledge.add.title=ナレッジを新規に登録 knowledge.add.label.title=タイトル knowledge.add.label.content=コンテンツ @@ -248,6 +251,10 @@ knowledge.account.changekey.title=メールアドレス変更 knowledge.account.label.email=変更したいメールアドレス(指定のアドレスに変更確認のためのメールを送ります) knowledge.account.changekey.request=メールアドレス変更のリクエストを受け付けました。新しいメールアドレスに確認用のメールを送りましたので、メールを受信して、メールアドレス変更処理を完了してください。 knowledge.account.changekey.complete=メールアドレス変更が完了しました。 +knowledge.account.id=ログイン用のID(ログイン時のIDになります/公開されることはありません) +knowledge.account.id.info1=管理者による登録の場合、IDは自由に設定できます。 +knowledge.account.id.info2=ただし、メールアドレス形式で無いIDの場合、メール通知ができません。 +knowledge.account.mail=メールアドレス(DB Userの場合、基本的にはユーザのログインIDと同じになります) knowledge.withdrawal.title=退会 knowledge.withdrawal.msg=Knowledgeのサービスから退会します。
今まで登録したナレッジをどうしますか?
knowledge.withdrawal.label.remove=削除する @@ -286,6 +293,9 @@ knowledge.config.mail.smtppass.require=認証する場合、SMTP パスワード knowledge.config.mail=メール送信設定 knowledge.config.system.title=システム設定 knowledge.config.system.label.url=サービスのURL +knowledge.config.system.open.title=システムの公開設定 +knowledge.config.system.open=公開情報などには、ログインしなくてもアクセス可能 +knowledge.config.system.close=全ての機能には、ログインしないとアクセス不可 knowledge.accept.title=承認待ちのユーザの一覧 knowledge.accept.label.list.empty=承認待ちのユーザはいません @@ -311,9 +321,9 @@ knowledge.group.view.label.subscribe.protect=所属のリクエストを出す knowledge.group.view.label.unsubscribe=グループの所属をやめる knowledge.group.view.label.mygroup=自分が所属しているグループを表示する knowledge.group.view.label.list=グループの一覧を表示する -knowledge.group.view.label.public= [公開](グループの一覧に表示されます。誰でも自由に参加できます。) -knowledge.group.view.label.protect= [保護](グループの一覧に表示されます。参加するためにはグループの管理者の承認が必要になります。) -knowledge.group.view.label.private= [非公開](グループの一覧に表示されません。新たにユーザをグループに追加するのは、グループの管理者が行ないます) +knowledge.group.view.label.public= [公開](誰でも自由に参加できます。) +knowledge.group.view.label.protect= [保護](参加するためにはグループの管理者の承認が必要になります。) +knowledge.group.view.label.private= [非公開](新たにユーザをグループに追加するのは、グループの管理者が行ないます) knowledge.group.view.label.change.admin=このユーザをグループの管理者にする knowledge.group.view.label.change.member=このユーザをグループのメンバーにする knowledge.group.view.label.change.none=このユーザをグループから除籍する @@ -326,11 +336,12 @@ knowledge.group.mylist.label.member= - あなたは[グループのメンバー] knowledge.group.mylist.label.wait= - 所属のリクエスト中です(まだ所属していません) - knowledge.group.list.title=グループの一覧 knowledge.group.list.label.mylist=自分が所属しているグループを表示する +knowledge.group.list.empty=データが存在しません。ページを切り替えてください。 knowledge.group.add.title=新たにグループを作成 knowledge.group.edit.title=グループを更新する -knowledge.group.edit.label.public=[公開](グループの一覧に表示されます。誰でも自由に参加できます。) -knowledge.group.edit.label.protect=[保護](グループの一覧に表示されます。参加するためにはグループの管理者の承認が必要になります。) -knowledge.group.edit.label.private=[非公開](グループの一覧に表示されません。新たにユーザをグループに追加するのは、グループの管理者が行ないます) +knowledge.group.edit.label.public=[公開](誰でも自由に参加できます。) +knowledge.group.edit.label.protect=[保護](参加するためにはグループの管理者の承認が必要になります。) +knowledge.group.edit.label.private=[非公開](新たにユーザをグループに追加するのは、グループの管理者が行ないます) knowledge.data.msg=サービスのデータの管理(バックアップ・復元)を実行します knowledge.data.label.backup=バックアップ(データダウンロード) @@ -449,3 +460,36 @@ knowledge.sample.markdown.501=#### さらに詳しく knowledge.sample.markdown.502=- [GitHub Flavored Markdown](https://help.github.com/articles/github-flavored-markdown/) が参考になります knowledge.sample.markdown.preview=Sampleで確認 +knowledge.ldap.title=Ldap 設定 +knowledge.ldap.label.host=Host +knowledge.ldap.label.port=Port +knowledge.ldap.label.security=Security +knowledge.ldap.label.plain=Plain +knowledge.ldap.label.usessl=SSL +knowledge.ldap.label.usetls=TLS +knowledge.ldap.label.binddn=Bind DN +knowledge.ldap.label.bindpass=Bind Password +knowledge.ldap.label.basedn=Base DN +knowledge.ldap.label.filter=Filter +knowledge.ldap.label.idattr=Id Attribute +knowledge.ldap.label.nameattr=Name Attribute +knowledge.ldap.label.mailattr=Mail Address Attribute +knowledge.ldap.label.testid=接続確認用ID +knowledge.ldap.label.testpass=接続確認用Password +knowledge.ldap.label.adminid=管理者ID +knowledge.ldap.label.authtype=サインイン設定 +knowledge.ldap.label.authtype.db=KnowledgeのDBに登録されているユーザでサインインします +knowledge.ldap.label.authtype.ldap=Ldapに登録されているユーザでサインインします(DBのユーザではサインインできなくなります) +knowledge.ldap.label.authtype.both=DBとLdapのどちらかに登録されていればサインインします +knowledge.ldap.label.dotest=接続確認用IDとPasswordで接続確認 +knowledge.ldap.msg.ldap=Ldapを使ったログインを有効にすると、初めてログインしたタイミングでKnowledgeにユーザを登録します。 +knowledge.ldap.msg.adminid1=この際、[管理者ID]に指定されているユーザでログインすると、管理者権限として登録します。 +knowledge.ldap.msg.adminid2=また、指定されていないユーザでログインすると、一般ユーザ権限で登録します。 +knowledge.ldap.msg.adminid3=Ldapログインのみにした場合、管理者になるユーザを少なくとも一人指定してください。(管理者がいないと、設定を変更できなくなります) +knowledge.ldap.msg.adminid4=一般ユーザとして登録したユーザであっても、管理者により、ユーザの一覧から管理者権限に変更する事が出来ます。 +knowledge.ldap.msg.connect.error=接続できません。LDAP設定、もしくは接続確認用ID/パスワードが間違っています。 +knowledge.ldap.msg.connect.success=接続できました。[id]{1} [name]{2} [mail]{3} [admin]{4} +knowledge.ldap.msg.save.error=接続が確認できないため保存できません。LDAP設定、もしくは接続確認用ID/パスワードが間違っています。 +knowledge.ldap.msg.save.success=保存しました。 +knowledge.ldap.confirm.delete=削除します。よろしいですか? + diff --git a/src/main/resources/log4j.xml b/src/main/resources/log4j.xml index ef68b9e3c..f7fc043fa 100644 --- a/src/main/resources/log4j.xml +++ b/src/main/resources/log4j.xml @@ -13,11 +13,11 @@ - + - + @@ -38,15 +38,6 @@ - - - - - - - - - @@ -58,11 +49,11 @@ - + diff --git a/src/main/resources/org/support/project/knowledge/dao/sql/ExUsersDao/selectGroupUser.sql b/src/main/resources/org/support/project/knowledge/dao/sql/ExUsersDao/selectGroupUser.sql index 14b0798d9..e838439eb 100644 --- a/src/main/resources/org/support/project/knowledge/dao/sql/ExUsersDao/selectGroupUser.sql +++ b/src/main/resources/org/support/project/knowledge/dao/sql/ExUsersDao/selectGroupUser.sql @@ -1,15 +1,5 @@ SELECT - USERS.USER_ID - ,USERS.USER_KEY - ,USERS.USER_NAME - ,USERS.PASSWORD - ,USERS.SALT - ,USERS.ROW_ID - ,USERS.INSERT_USER - ,USERS.INSERT_DATETIME - ,USERS.UPDATE_USER - ,USERS.UPDATE_DATETIME - ,USERS.DELETE_FLAG + USERS.* ,USER_GROUPS.GROUP_ROLE FROM USERS INNER JOIN USER_GROUPS diff --git a/src/main/resources/org/support/project/knowledge/dao/sql/ExUsersDao/selectNotifyPublicUsers.sql b/src/main/resources/org/support/project/knowledge/dao/sql/ExUsersDao/selectNotifyPublicUsers.sql index d742ff30e..2ae9270f6 100644 --- a/src/main/resources/org/support/project/knowledge/dao/sql/ExUsersDao/selectNotifyPublicUsers.sql +++ b/src/main/resources/org/support/project/knowledge/dao/sql/ExUsersDao/selectNotifyPublicUsers.sql @@ -1,4 +1,4 @@ -SELECT USERS.USER_ID, USERS.USER_KEY, USERS.USER_NAME +SELECT USERS.* FROM USERS INNER JOIN NOTIFY_CONFIGS ON (USERS.USER_ID = NOTIFY_CONFIGS.USER_ID) WHERE NOTIFY_CONFIGS.NOTIFY_MAIL = 1 diff --git a/src/main/resources/org/support/project/knowledge/dao/sql/TagsDao/TagsDao_selectWithKnowledgeCountOnTagName.sql b/src/main/resources/org/support/project/knowledge/dao/sql/TagsDao/TagsDao_selectWithKnowledgeCountOnTagName.sql new file mode 100644 index 000000000..fa91656ab --- /dev/null +++ b/src/main/resources/org/support/project/knowledge/dao/sql/TagsDao/TagsDao_selectWithKnowledgeCountOnTagName.sql @@ -0,0 +1,13 @@ +SELECT TAGS.*, COUNT(KNOWLEDGE_TAGS.KNOWLEDGE_ID) AS KNOWLEDGE_COUNT FROM TAGS +INNER JOIN KNOWLEDGE_TAGS ON (TAGS.TAG_ID = KNOWLEDGE_TAGS.TAG_ID) +WHERE EXISTS ( + SELECT KNOWLEDGES.KNOWLEDGE_ID FROM KNOWLEDGES + INNER JOIN KNOWLEDGE_USERS ON (KNOWLEDGES.KNOWLEDGE_ID = KNOWLEDGE_USERS.KNOWLEDGE_ID) + WHERE KNOWLEDGE_TAGS.KNOWLEDGE_ID = KNOWLEDGES.KNOWLEDGE_ID + AND KNOWLEDGES.DELETE_FLAG = 0 +) +AND TAGS.TAG_NAME LIKE ? +AND TAGS.DELETE_FLAG = 0 +GROUP BY TAGS.TAG_ID +ORDER BY KNOWLEDGE_COUNT DESC, TAG_NAME +LIMIT ? OFFSET ? diff --git a/src/main/resources/org/support/project/knowledge/database/init_datas.sql b/src/main/resources/org/support/project/knowledge/database/init_datas.sql new file mode 100644 index 000000000..b0f9475a5 --- /dev/null +++ b/src/main/resources/org/support/project/knowledge/database/init_datas.sql @@ -0,0 +1,6 @@ +INSERT INTO GROUPS +( GROUP_ID, GROUP_KEY, GROUP_NAME, DESCRIPTION, PARENT_GROUP_KEY, GROUP_CLASS, ROW_ID, + INSERT_USER, INSERT_DATETIME, UPDATE_USER, UPDATE_DATETIME, DELETE_FLAG ) + VALUES + (0,'g-all','ALL USERS','全てのユーザが所属するグループ',null,0,'g-all',0,'2015-07-04 00:00:00',null,null,0); + \ No newline at end of file diff --git a/src/main/resources/org/support/project/knowledge/deploy/v0_5_3pre2/migrate.sql b/src/main/resources/org/support/project/knowledge/deploy/v0_5_3pre2/migrate.sql new file mode 100644 index 000000000..b299cbc8b --- /dev/null +++ b/src/main/resources/org/support/project/knowledge/deploy/v0_5_3pre2/migrate.sql @@ -0,0 +1,69 @@ +INSERT INTO GROUPS +( GROUP_ID, GROUP_KEY, GROUP_NAME, DESCRIPTION, PARENT_GROUP_KEY, GROUP_CLASS, ROW_ID, + INSERT_USER, INSERT_DATETIME, UPDATE_USER, UPDATE_DATETIME, DELETE_FLAG ) + VALUES + (0,'g-all','ALL USERS','全てのユーザが所属するグループ',null,0,'g-all',0,'2015-07-04 00:00:00',null,null,0); + +ALTER TABLE USERS DROP COLUMN IF EXISTS MAIL_ADDRESS; +ALTER TABLE USERS DROP COLUMN IF EXISTS AUTH_LDAP; +ALTER TABLE PROVISIONAL_REGISTRATIONS DROP COLUMN IF EXISTS MAIL_ADDRESS; +ALTER TABLE USERS ADD COLUMN MAIL_ADDRESS character varying(256); +ALTER TABLE USERS ADD COLUMN AUTH_LDAP integer; +ALTER TABLE PROVISIONAL_REGISTRATIONS ADD COLUMN MAIL_ADDRESS character varying(256); + +comment on column USERS.MAIL_ADDRESS is 'メールアドレス'; +comment on column PROVISIONAL_REGISTRATIONS.MAIL_ADDRESS is 'メールアドレス'; +comment on column USERS.AUTH_LDAP is 'LDAP認証ユーザかどうか'; + +-- LDAP認証設定 +drop table if exists LDAP_CONFIGS cascade; + +create table LDAP_CONFIGS ( + SYSTEM_NAME character varying(64) not null + , HOST character varying(256) not null + , PORT integer not null + , USE_SSL integer + , USE_TLS integer + , BIND_DN character varying(256) + , BIND_PASSWORD character varying(1048) + , SALT character varying(1048) + , BASE_DN character varying(256) not null + , FILTER character varying(256) + , ID_ATTR character varying(256) not null + , NAME_ATTR character varying(256) + , MAIL_ATTR character varying(256) + , ADMIN_CHECK_FILTER character varying(256) + , AUTH_TYPE integer not null + , ROW_ID character varying(64) + , INSERT_USER integer + , INSERT_DATETIME timestamp + , UPDATE_USER integer + , UPDATE_DATETIME timestamp + , DELETE_FLAG integer + , constraint LDAP_CONFIGS_PKC primary key (SYSTEM_NAME) +) ; + +comment on table LDAP_CONFIGS is 'LDAP認証設定'; +comment on column LDAP_CONFIGS.SYSTEM_NAME is 'システム名'; +comment on column LDAP_CONFIGS.HOST is 'HOST'; +comment on column LDAP_CONFIGS.PORT is 'PORT'; +comment on column LDAP_CONFIGS.USE_SSL is 'USE_SSL'; +comment on column LDAP_CONFIGS.USE_TLS is 'USE_TLS'; +comment on column LDAP_CONFIGS.BIND_DN is 'BIND_DN'; +comment on column LDAP_CONFIGS.BIND_PASSWORD is 'BIND_PASSWORD'; +comment on column LDAP_CONFIGS.SALT is 'SALT'; +comment on column LDAP_CONFIGS.BASE_DN is 'BASE_DN'; +comment on column LDAP_CONFIGS.FILTER is 'FILTER'; +comment on column LDAP_CONFIGS.ID_ATTR is 'ID_ATTR'; +comment on column LDAP_CONFIGS.NAME_ATTR is 'NAME_ATTR'; +comment on column LDAP_CONFIGS.MAIL_ATTR is 'MAIL_ATTR'; +comment on column LDAP_CONFIGS.ADMIN_CHECK_FILTER is 'ADMIN_CHECK_FILTER'; +comment on column LDAP_CONFIGS.AUTH_TYPE is 'AUTH_TYPE 0:DB認証,1:LDAP認証,2:DB認証+LDAP認証(LDAP優先)'; +comment on column LDAP_CONFIGS.ROW_ID is '行ID'; +comment on column LDAP_CONFIGS.INSERT_USER is '登録ユーザ'; +comment on column LDAP_CONFIGS.INSERT_DATETIME is '登録日時'; +comment on column LDAP_CONFIGS.UPDATE_USER is '更新ユーザ'; +comment on column LDAP_CONFIGS.UPDATE_DATETIME is '更新日時'; +comment on column LDAP_CONFIGS.DELETE_FLAG is '削除フラグ'; + + diff --git a/src/main/resources/org/support/project/knowledge/logic/marked.js b/src/main/resources/org/support/project/knowledge/logic/marked.js new file mode 100644 index 000000000..e2f08c998 --- /dev/null +++ b/src/main/resources/org/support/project/knowledge/logic/marked.js @@ -0,0 +1,1266 @@ +/** + * marked - a markdown parser + * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed) + * https://github.com/chjj/marked + */ + +;(function() { + +/** + * Block-Level Grammar + */ + +var block = { + newline: /^\n+/, + code: /^( {4}[^\n]+\n*)+/, + fences: noop, + hr: /^( *[-*_]){3,} *(?:\n+|$)/, + heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/, + nptable: noop, + lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/, + blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/, + list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/, + html: /^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/, + def: /^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/, + table: noop, + paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/, + text: /^[^\n]+/ +}; + +block.bullet = /(?:[*+-]|\d+\.)/; +block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/; +block.item = replace(block.item, 'gm') + (/bull/g, block.bullet) + (); + +block.list = replace(block.list) + (/bull/g, block.bullet) + ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))') + ('def', '\\n+(?=' + block.def.source + ')') + (); + +block.blockquote = replace(block.blockquote) + ('def', block.def) + (); + +block._tag = '(?!(?:' + + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code' + + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo' + + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b'; + +block.html = replace(block.html) + ('comment', //) + ('closed', /<(tag)[\s\S]+?<\/\1>/) + ('closing', /])*?>/) + (/tag/g, block._tag) + (); + +block.paragraph = replace(block.paragraph) + ('hr', block.hr) + ('heading', block.heading) + ('lheading', block.lheading) + ('blockquote', block.blockquote) + ('tag', '<' + block._tag) + ('def', block.def) + (); + +/** + * Normal Block Grammar + */ + +block.normal = merge({}, block); + +/** + * GFM Block Grammar + */ + +block.gfm = merge({}, block.normal, { + fences: /^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/, + paragraph: /^/ +}); + +block.gfm.paragraph = replace(block.paragraph) + ('(?!', '(?!' + + block.gfm.fences.source.replace('\\1', '\\2') + '|' + + block.list.source.replace('\\1', '\\3') + '|') + (); + +/** + * GFM + Tables Block Grammar + */ + +block.tables = merge({}, block.gfm, { + nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/, + table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/ +}); + +/** + * Block Lexer + */ + +function Lexer(options) { + this.tokens = []; + this.tokens.links = {}; + this.options = options || marked.defaults; + this.rules = block.normal; + + if (this.options.gfm) { + if (this.options.tables) { + this.rules = block.tables; + } else { + this.rules = block.gfm; + } + } +} + +/** + * Expose Block Rules + */ + +Lexer.rules = block; + +/** + * Static Lex Method + */ + +Lexer.lex = function(src, options) { + var lexer = new Lexer(options); + return lexer.lex(src); +}; + +/** + * Preprocessing + */ + +Lexer.prototype.lex = function(src) { + src = src + .replace(/\r\n|\r/g, '\n') + .replace(/\t/g, ' ') + .replace(/\u00a0/g, ' ') + .replace(/\u2424/g, '\n'); + + return this.token(src, true); +}; + +/** + * Lexing + */ + +Lexer.prototype.token = function(src, top, bq) { + var src = src.replace(/^ +$/gm, '') + , next + , loose + , cap + , bull + , b + , item + , space + , i + , l; + + while (src) { + // newline + if (cap = this.rules.newline.exec(src)) { + src = src.substring(cap[0].length); + if (cap[0].length > 1) { + this.tokens.push({ + type: 'space' + }); + } + } + + // code + if (cap = this.rules.code.exec(src)) { + src = src.substring(cap[0].length); + cap = cap[0].replace(/^ {4}/gm, ''); + this.tokens.push({ + type: 'code', + text: !this.options.pedantic + ? cap.replace(/\n+$/, '') + : cap + }); + continue; + } + + // fences (gfm) + if (cap = this.rules.fences.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'code', + lang: cap[2], + text: cap[3] + }); + continue; + } + + // heading + if (cap = this.rules.heading.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'heading', + depth: cap[1].length, + text: cap[2] + }); + continue; + } + + // table no leading pipe (gfm) + if (top && (cap = this.rules.nptable.exec(src))) { + src = src.substring(cap[0].length); + + item = { + type: 'table', + header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + cells: cap[3].replace(/\n$/, '').split('\n') + }; + + for (i = 0; i < item.align.length; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = item.cells[i].split(/ *\| */); + } + + this.tokens.push(item); + + continue; + } + + // lheading + if (cap = this.rules.lheading.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'heading', + depth: cap[2] === '=' ? 1 : 2, + text: cap[1] + }); + continue; + } + + // hr + if (cap = this.rules.hr.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'hr' + }); + continue; + } + + // blockquote + if (cap = this.rules.blockquote.exec(src)) { + src = src.substring(cap[0].length); + + this.tokens.push({ + type: 'blockquote_start' + }); + + cap = cap[0].replace(/^ *> ?/gm, ''); + + // Pass `top` to keep the current + // "toplevel" state. This is exactly + // how markdown.pl works. + this.token(cap, top, true); + + this.tokens.push({ + type: 'blockquote_end' + }); + + continue; + } + + // list + if (cap = this.rules.list.exec(src)) { + src = src.substring(cap[0].length); + bull = cap[2]; + + this.tokens.push({ + type: 'list_start', + ordered: bull.length > 1 + }); + + // Get each top-level item. + cap = cap[0].match(this.rules.item); + + next = false; + l = cap.length; + i = 0; + + for (; i < l; i++) { + item = cap[i]; + + // Remove the list item's bullet + // so it is seen as the next token. + space = item.length; + item = item.replace(/^ *([*+-]|\d+\.) +/, ''); + + // Outdent whatever the + // list item contains. Hacky. + if (~item.indexOf('\n ')) { + space -= item.length; + item = !this.options.pedantic + ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '') + : item.replace(/^ {1,4}/gm, ''); + } + + // Determine whether the next list item belongs here. + // Backpedal if it does not belong in this list. + if (this.options.smartLists && i !== l - 1) { + b = block.bullet.exec(cap[i + 1])[0]; + if (bull !== b && !(bull.length > 1 && b.length > 1)) { + src = cap.slice(i + 1).join('\n') + src; + i = l - 1; + } + } + + // Determine whether item is loose or not. + // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/ + // for discount behavior. + loose = next || /\n\n(?!\s*$)/.test(item); + if (i !== l - 1) { + next = item.charAt(item.length - 1) === '\n'; + if (!loose) loose = next; + } + + this.tokens.push({ + type: loose + ? 'loose_item_start' + : 'list_item_start' + }); + + // Recurse. + this.token(item, false, bq); + + this.tokens.push({ + type: 'list_item_end' + }); + } + + this.tokens.push({ + type: 'list_end' + }); + + continue; + } + + // html + if (cap = this.rules.html.exec(src)) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: this.options.sanitize + ? 'paragraph' + : 'html', + pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style', + text: cap[0] + }); + continue; + } + + // def + if ((!bq && top) && (cap = this.rules.def.exec(src))) { + src = src.substring(cap[0].length); + this.tokens.links[cap[1].toLowerCase()] = { + href: cap[2], + title: cap[3] + }; + continue; + } + + // table (gfm) + if (top && (cap = this.rules.table.exec(src))) { + src = src.substring(cap[0].length); + + item = { + type: 'table', + header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */), + align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */), + cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n') + }; + + for (i = 0; i < item.align.length; i++) { + if (/^ *-+: *$/.test(item.align[i])) { + item.align[i] = 'right'; + } else if (/^ *:-+: *$/.test(item.align[i])) { + item.align[i] = 'center'; + } else if (/^ *:-+ *$/.test(item.align[i])) { + item.align[i] = 'left'; + } else { + item.align[i] = null; + } + } + + for (i = 0; i < item.cells.length; i++) { + item.cells[i] = item.cells[i] + .replace(/^ *\| *| *\| *$/g, '') + .split(/ *\| */); + } + + this.tokens.push(item); + + continue; + } + + // top-level paragraph + if (top && (cap = this.rules.paragraph.exec(src))) { + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'paragraph', + text: cap[1].charAt(cap[1].length - 1) === '\n' + ? cap[1].slice(0, -1) + : cap[1] + }); + continue; + } + + // text + if (cap = this.rules.text.exec(src)) { + // Top-level should never reach here. + src = src.substring(cap[0].length); + this.tokens.push({ + type: 'text', + text: cap[0] + }); + continue; + } + + if (src) { + throw new + Error('Infinite loop on byte: ' + src.charCodeAt(0)); + } + } + + return this.tokens; +}; + +/** + * Inline-Level Grammar + */ + +var inline = { + escape: /^\\([\\`*{}\[\]()#+\-.!_>])/, + autolink: /^<([^ >]+(@|:\/)[^ >]+)>/, + url: noop, + tag: /^|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/, + link: /^!?\[(inside)\]\(href\)/, + reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/, + nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/, + strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/, + em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, + code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/, + br: /^ {2,}\n(?!\s*$)/, + del: noop, + text: /^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/; + +inline.link = replace(inline.link) + ('inside', inline._inside) + ('href', inline._href) + (); + +inline.reflink = replace(inline.reflink) + ('inside', inline._inside) + (); + +/** + * Normal Inline Grammar + */ + +inline.normal = merge({}, inline); + +/** + * Pedantic Inline Grammar + */ + +inline.pedantic = merge({}, inline.normal, { + strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, + em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/ +}); + +/** + * GFM Inline Grammar + */ + +inline.gfm = merge({}, inline.normal, { + escape: replace(inline.escape)('])', '~|])')(), + url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/, + del: /^~~(?=\S)([\s\S]*?\S)~~/, + text: replace(inline.text) + (']|', '~]|') + ('|', '|https?://|') + () +}); + +/** + * GFM + Line Breaks Inline Grammar + */ + +inline.breaks = merge({}, inline.gfm, { + br: replace(inline.br)('{2,}', '*')(), + text: replace(inline.gfm.text)('{2,}', '*')() +}); + +/** + * Inline Lexer & Compiler + */ + +function InlineLexer(links, options) { + this.options = options || marked.defaults; + this.links = links; + this.rules = inline.normal; + this.renderer = this.options.renderer || new Renderer; + this.renderer.options = this.options; + + if (!this.links) { + throw new + Error('Tokens array requires a `links` property.'); + } + + if (this.options.gfm) { + if (this.options.breaks) { + this.rules = inline.breaks; + } else { + this.rules = inline.gfm; + } + } else if (this.options.pedantic) { + this.rules = inline.pedantic; + } +} + +/** + * Expose Inline Rules + */ + +InlineLexer.rules = inline; + +/** + * Static Lexing/Compiling Method + */ + +InlineLexer.output = function(src, links, options) { + var inline = new InlineLexer(links, options); + return inline.output(src); +}; + +/** + * Lexing/Compiling + */ + +InlineLexer.prototype.output = function(src) { + var out = '' + , link + , text + , href + , cap; + + while (src) { + // escape + if (cap = this.rules.escape.exec(src)) { + src = src.substring(cap[0].length); + out += cap[1]; + continue; + } + + // autolink + if (cap = this.rules.autolink.exec(src)) { + src = src.substring(cap[0].length); + if (cap[2] === '@') { + text = cap[1].charAt(6) === ':' + ? this.mangle(cap[1].substring(7)) + : this.mangle(cap[1]); + href = this.mangle('mailto:') + text; + } else { + text = escape(cap[1]); + href = text; + } + out += this.renderer.link(href, null, text); + continue; + } + + // url (gfm) + if (!this.inLink && (cap = this.rules.url.exec(src))) { + src = src.substring(cap[0].length); + text = escape(cap[1]); + href = text; + out += this.renderer.link(href, null, text); + continue; + } + + // tag + if (cap = this.rules.tag.exec(src)) { + if (!this.inLink && /^/i.test(cap[0])) { + this.inLink = false; + } + src = src.substring(cap[0].length); + out += this.options.sanitize + ? escape(cap[0]) + : cap[0]; + continue; + } + + // link + if (cap = this.rules.link.exec(src)) { + src = src.substring(cap[0].length); + this.inLink = true; + out += this.outputLink(cap, { + href: cap[2], + title: cap[3] + }); + this.inLink = false; + continue; + } + + // reflink, nolink + if ((cap = this.rules.reflink.exec(src)) + || (cap = this.rules.nolink.exec(src))) { + src = src.substring(cap[0].length); + link = (cap[2] || cap[1]).replace(/\s+/g, ' '); + link = this.links[link.toLowerCase()]; + if (!link || !link.href) { + out += cap[0].charAt(0); + src = cap[0].substring(1) + src; + continue; + } + this.inLink = true; + out += this.outputLink(cap, link); + this.inLink = false; + continue; + } + + // strong + if (cap = this.rules.strong.exec(src)) { + src = src.substring(cap[0].length); + out += this.renderer.strong(this.output(cap[2] || cap[1])); + continue; + } + + // em + if (cap = this.rules.em.exec(src)) { + src = src.substring(cap[0].length); + out += this.renderer.em(this.output(cap[2] || cap[1])); + continue; + } + + // code + if (cap = this.rules.code.exec(src)) { + src = src.substring(cap[0].length); + out += this.renderer.codespan(escape(cap[2], true)); + continue; + } + + // br + if (cap = this.rules.br.exec(src)) { + src = src.substring(cap[0].length); + out += this.renderer.br(); + continue; + } + + // del (gfm) + if (cap = this.rules.del.exec(src)) { + src = src.substring(cap[0].length); + out += this.renderer.del(this.output(cap[1])); + continue; + } + + // text + if (cap = this.rules.text.exec(src)) { + src = src.substring(cap[0].length); + out += escape(this.smartypants(cap[0])); + continue; + } + + if (src) { + throw new + Error('Infinite loop on byte: ' + src.charCodeAt(0)); + } + } + + return out; +}; + +/** + * Compile Link + */ + +InlineLexer.prototype.outputLink = function(cap, link) { + var href = escape(link.href) + , title = link.title ? escape(link.title) : null; + + return cap[0].charAt(0) !== '!' + ? this.renderer.link(href, title, this.output(cap[1])) + : this.renderer.image(href, title, escape(cap[1])); +}; + +/** + * Smartypants Transformations + */ + +InlineLexer.prototype.smartypants = function(text) { + if (!this.options.smartypants) return text; + return text + // em-dashes + .replace(/--/g, '\u2014') + // opening singles + .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018') + // closing singles & apostrophes + .replace(/'/g, '\u2019') + // opening doubles + .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c') + // closing doubles + .replace(/"/g, '\u201d') + // ellipses + .replace(/\.{3}/g, '\u2026'); +}; + +/** + * Mangle Links + */ + +InlineLexer.prototype.mangle = function(text) { + var out = '' + , l = text.length + , i = 0 + , ch; + + for (; i < l; i++) { + ch = text.charCodeAt(i); + if (Math.random() > 0.5) { + ch = 'x' + ch.toString(16); + } + out += '&#' + ch + ';'; + } + + return out; +}; + +/** + * Renderer + */ + +function Renderer(options) { + this.options = options || {}; +} + +Renderer.prototype.code = function(code, lang, escaped) { + if (this.options.highlight) { + var out = this.options.highlight(code, lang); + if (out != null && out !== code) { + escaped = true; + code = out; + } + } + + if (!lang) { + return '
'
+      + (escaped ? code : escape(code, true))
+      + '\n
'; + } + + return '
'
+    + (escaped ? code : escape(code, true))
+    + '\n
\n'; +}; + +Renderer.prototype.blockquote = function(quote) { + return '
\n' + quote + '
\n'; +}; + +Renderer.prototype.html = function(html) { + return html; +}; + +Renderer.prototype.heading = function(text, level, raw) { + return '' + + text + + '\n'; +}; + +Renderer.prototype.hr = function() { + return this.options.xhtml ? '
\n' : '
\n'; +}; + +Renderer.prototype.list = function(body, ordered) { + var type = ordered ? 'ol' : 'ul'; + return '<' + type + '>\n' + body + '\n'; +}; + +Renderer.prototype.listitem = function(text) { + return '
  • ' + text + '
  • \n'; +}; + +Renderer.prototype.paragraph = function(text) { + return '

    ' + text + '

    \n'; +}; + +Renderer.prototype.table = function(header, body) { + return '\n' + + '\n' + + header + + '\n' + + '\n' + + body + + '\n' + + '
    \n'; +}; + +Renderer.prototype.tablerow = function(content) { + return '\n' + content + '\n'; +}; + +Renderer.prototype.tablecell = function(content, flags) { + var type = flags.header ? 'th' : 'td'; + var tag = flags.align + ? '<' + type + ' style="text-align:' + flags.align + '">' + : '<' + type + '>'; + return tag + content + '\n'; +}; + +// span level renderer +Renderer.prototype.strong = function(text) { + return '' + text + ''; +}; + +Renderer.prototype.em = function(text) { + return '' + text + ''; +}; + +Renderer.prototype.codespan = function(text) { + return '' + text + ''; +}; + +Renderer.prototype.br = function() { + return this.options.xhtml ? '
    ' : '
    '; +}; + +Renderer.prototype.del = function(text) { + return '' + text + ''; +}; + +Renderer.prototype.link = function(href, title, text) { + if (this.options.sanitize) { + try { + var prot = decodeURIComponent(unescape(href)) + .replace(/[^\w:]/g, '') + .toLowerCase(); + } catch (e) { + return ''; + } + if (prot.indexOf('javascript:') === 0) { + return ''; + } + } + var out = '
    '; + return out; +}; + +Renderer.prototype.image = function(href, title, text) { + var out = '' + text + '' : '>'; + return out; +}; + +/** + * Parsing & Compiling + */ + +function Parser(options) { + this.tokens = []; + this.token = null; + this.options = options || marked.defaults; + this.options.renderer = this.options.renderer || new Renderer; + this.renderer = this.options.renderer; + this.renderer.options = this.options; +} + +/** + * Static Parse Method + */ + +Parser.parse = function(src, options, renderer) { + var parser = new Parser(options, renderer); + return parser.parse(src); +}; + +/** + * Parse Loop + */ + +Parser.prototype.parse = function(src) { + this.inline = new InlineLexer(src.links, this.options, this.renderer); + this.tokens = src.reverse(); + + var out = ''; + while (this.next()) { + out += this.tok(); + } + + return out; +}; + +/** + * Next Token + */ + +Parser.prototype.next = function() { + return this.token = this.tokens.pop(); +}; + +/** + * Preview Next Token + */ + +Parser.prototype.peek = function() { + return this.tokens[this.tokens.length - 1] || 0; +}; + +/** + * Parse Text Tokens + */ + +Parser.prototype.parseText = function() { + var body = this.token.text; + + while (this.peek().type === 'text') { + body += '\n' + this.next().text; + } + + return this.inline.output(body); +}; + +/** + * Parse Current Token + */ + +Parser.prototype.tok = function() { + switch (this.token.type) { + case 'space': { + return ''; + } + case 'hr': { + return this.renderer.hr(); + } + case 'heading': { + return this.renderer.heading( + this.inline.output(this.token.text), + this.token.depth, + this.token.text); + } + case 'code': { + return this.renderer.code(this.token.text, + this.token.lang, + this.token.escaped); + } + case 'table': { + var header = '' + , body = '' + , i + , row + , cell + , flags + , j; + + // header + cell = ''; + for (i = 0; i < this.token.header.length; i++) { + flags = { header: true, align: this.token.align[i] }; + cell += this.renderer.tablecell( + this.inline.output(this.token.header[i]), + { header: true, align: this.token.align[i] } + ); + } + header += this.renderer.tablerow(cell); + + for (i = 0; i < this.token.cells.length; i++) { + row = this.token.cells[i]; + + cell = ''; + for (j = 0; j < row.length; j++) { + cell += this.renderer.tablecell( + this.inline.output(row[j]), + { header: false, align: this.token.align[j] } + ); + } + + body += this.renderer.tablerow(cell); + } + return this.renderer.table(header, body); + } + case 'blockquote_start': { + var body = ''; + + while (this.next().type !== 'blockquote_end') { + body += this.tok(); + } + + return this.renderer.blockquote(body); + } + case 'list_start': { + var body = '' + , ordered = this.token.ordered; + + while (this.next().type !== 'list_end') { + body += this.tok(); + } + + return this.renderer.list(body, ordered); + } + case 'list_item_start': { + var body = ''; + + while (this.next().type !== 'list_item_end') { + body += this.token.type === 'text' + ? this.parseText() + : this.tok(); + } + + return this.renderer.listitem(body); + } + case 'loose_item_start': { + var body = ''; + + while (this.next().type !== 'list_item_end') { + body += this.tok(); + } + + return this.renderer.listitem(body); + } + case 'html': { + var html = !this.token.pre && !this.options.pedantic + ? this.inline.output(this.token.text) + : this.token.text; + return this.renderer.html(html); + } + case 'paragraph': { + return this.renderer.paragraph(this.inline.output(this.token.text)); + } + case 'text': { + return this.renderer.paragraph(this.parseText()); + } + } +}; + +/** + * Helpers + */ + +function escape(html, encode) { + return html + .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + +function unescape(html) { + return html.replace(/&([#\w]+);/g, function(_, n) { + n = n.toLowerCase(); + if (n === 'colon') return ':'; + if (n.charAt(0) === '#') { + return n.charAt(1) === 'x' + ? String.fromCharCode(parseInt(n.substring(2), 16)) + : String.fromCharCode(+n.substring(1)); + } + return ''; + }); +} + +function replace(regex, opt) { + regex = regex.source; + opt = opt || ''; + return function self(name, val) { + if (!name) return new RegExp(regex, opt); + val = val.source || val; + val = val.replace(/(^|[^\[])\^/g, '$1'); + regex = regex.replace(name, val); + return self; + }; +} + +function noop() {} +noop.exec = noop; + +function merge(obj) { + var i = 1 + , target + , key; + + for (; i < arguments.length; i++) { + target = arguments[i]; + for (key in target) { + if (Object.prototype.hasOwnProperty.call(target, key)) { + obj[key] = target[key]; + } + } + } + + return obj; +} + + +/** + * Marked + */ + +function marked(src, opt, callback) { + if (callback || typeof opt === 'function') { + if (!callback) { + callback = opt; + opt = null; + } + + opt = merge({}, marked.defaults, opt || {}); + + var highlight = opt.highlight + , tokens + , pending + , i = 0; + + try { + tokens = Lexer.lex(src, opt) + } catch (e) { + return callback(e); + } + + pending = tokens.length; + + var done = function() { + var out, err; + + try { + out = Parser.parse(tokens, opt); + } catch (e) { + err = e; + } + + opt.highlight = highlight; + + return err + ? callback(err) + : callback(null, out); + }; + + if (!highlight || highlight.length < 3) { + return done(); + } + + delete opt.highlight; + + if (!pending) return done(); + + for (; i < tokens.length; i++) { + (function(token) { + if (token.type !== 'code') { + return --pending || done(); + } + return highlight(token.text, token.lang, function(err, code) { + if (code == null || code === token.text) { + return --pending || done(); + } + token.text = code; + token.escaped = true; + --pending || done(); + }); + })(tokens[i]); + } + + return; + } + try { + if (opt) opt = merge({}, marked.defaults, opt); + return Parser.parse(Lexer.lex(src, opt), opt); + } catch (e) { + e.message += '\nPlease report this to https://github.com/chjj/marked.'; + if ((opt || marked.defaults).silent) { + return '

    An error occured:

    '
    +        + escape(e.message + '', true)
    +        + '
    '; + } + throw e; + } +} + +/** + * Options + */ + +marked.options = +marked.setOptions = function(opt) { + merge(marked.defaults, opt); + return marked; +}; + +marked.defaults = { + gfm: true, + tables: true, + breaks: false, + pedantic: false, + sanitize: false, + smartLists: false, + silent: false, + highlight: null, + langPrefix: 'lang-', + smartypants: false, + headerPrefix: '', + renderer: new Renderer, + xhtml: false +}; + +/** + * Expose + */ + +marked.Parser = Parser; +marked.parser = Parser.parse; + +marked.Renderer = Renderer; + +marked.Lexer = Lexer; +marked.lexer = Lexer.lex; + +marked.InlineLexer = InlineLexer; +marked.inlineLexer = InlineLexer.output; + +marked.parse = marked; + +if (typeof exports === 'object') { + module.exports = marked; +} else if (typeof define === 'function' && define.amd) { + define(function() { return marked; }); +} else { + this.marked = marked; +} + +}).call(function() { + return this || (typeof window !== 'undefined' ? window : global); +}()); diff --git a/src/main/webapp/WEB-INF/views/admin/config/config.jsp b/src/main/webapp/WEB-INF/views/admin/config/config.jsp index 2a5f40ec3..0ea21de17 100644 --- a/src/main/webapp/WEB-INF/views/admin/config/config.jsp +++ b/src/main/webapp/WEB-INF/views/admin/config/config.jsp @@ -28,6 +28,30 @@

    <%= jspUtil.label("knowledge.config.title") %>

    +<% if(jspUtil.is(0, "authType")) { %> + +<% } %> +<% if(jspUtil.is(1, "authType")) { %> + +<% } %> +<% if(jspUtil.is(2, "authType")) { %> + +<% } %> + +
    diff --git a/src/main/webapp/WEB-INF/views/admin/config/system.jsp b/src/main/webapp/WEB-INF/views/admin/config/system.jsp index 9b1aabc21..cd104d2d9 100644 --- a/src/main/webapp/WEB-INF/views/admin/config/system.jsp +++ b/src/main/webapp/WEB-INF/views/admin/config/system.jsp @@ -12,6 +12,11 @@ + @@ -29,6 +34,21 @@
    +
    +
    + +
    + +
    +
    diff --git a/src/main/webapp/WEB-INF/views/admin/ldap/config.jsp b/src/main/webapp/WEB-INF/views/admin/ldap/config.jsp new file mode 100644 index 000000000..a18386f3c --- /dev/null +++ b/src/main/webapp/WEB-INF/views/admin/ldap/config.jsp @@ -0,0 +1,141 @@ +<%@page import="org.support.project.common.config.INT_FLAG"%> +<%@page import="org.support.project.knowledge.vo.Roles"%> +<%@page import="org.support.project.web.util.JspUtil"%> +<%@page pageEncoding="UTF-8" isELIgnored="false" session="false" errorPage="/WEB-INF/views/commons/errors/jsp_error.jsp"%> +<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> +<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> + +<% JspUtil jspUtil = new JspUtil(request, pageContext); %> + + + + + + + + + + + + + + +

    <%= jspUtil.label("knowledge.ldap.title") %>

    + + + +
    + +
    +
    +
    +
    + +
    + +
    + + " /> +
    +
    + + " /> +
    + +
    +
    + + + +
    + +
    + + " /> +
    +
    + + " /> +
    +
    + + " /> +
    +
    + + " /> +
    + + +
    + + " /> +
    +
    + + " /> +
    +
    + + " value="<%= jspUtil.out("adminCheckFilter") %>" /> +
    + + " /> + + + + +
    + + +
    + +
    + diff --git a/src/main/webapp/WEB-INF/views/admin/users/list.jsp b/src/main/webapp/WEB-INF/views/admin/users/list.jsp index 3b93579f2..b682d7a38 100644 --- a/src/main/webapp/WEB-INF/views/admin/users/list.jsp +++ b/src/main/webapp/WEB-INF/views/admin/users/list.jsp @@ -46,6 +46,11 @@ <%= jspUtil.label("label.regist.datetime") %> / <%= jspUtil.label("label.update.datetime") %>  <%= jspUtil.date("user.insertDatetime")%> /  <%= jspUtil.date("user.updateDatetime")%> + <% if (jspUtil.is(1, "user.authLdap")) { %> + [LDAP USER] + <% } else { %> + [DB USER] + <% } %>

    diff --git a/src/main/webapp/WEB-INF/views/admin/users/view_add.jsp b/src/main/webapp/WEB-INF/views/admin/users/view_add.jsp index 6e34d71ea..8df8ff255 100644 --- a/src/main/webapp/WEB-INF/views/admin/users/view_add.jsp +++ b/src/main/webapp/WEB-INF/views/admin/users/view_add.jsp @@ -22,6 +22,13 @@

    <%= jspUtil.label("knowledge.user.add.title") %>

    + +
    diff --git a/src/main/webapp/WEB-INF/views/admin/users/view_edit.jsp b/src/main/webapp/WEB-INF/views/admin/users/view_edit.jsp index 3a5c70f76..40fd787a9 100644 --- a/src/main/webapp/WEB-INF/views/admin/users/view_edit.jsp +++ b/src/main/webapp/WEB-INF/views/admin/users/view_edit.jsp @@ -30,13 +30,38 @@ function deleteUser() {

    <%= jspUtil.label("knowledge.user.edit.title") %>

    +<% if(jspUtil.is(1, "authLdap")) { %> + +<% } %> +<% if(jspUtil.is(1, "authLdap")) { %> +
    + + " readonly="readonly" /> +
    +
    + + " readonly="readonly" /> +
    +
    + + " readonly="readonly" /> +
    +<% } else { %>
    - + " />
    +
    + + " readonly="readonly" /> +
    " /> @@ -50,6 +75,7 @@ function deleteUser() { " />
    +<% } %>

    diff --git a/src/main/webapp/WEB-INF/views/commons/layout/commonNavbar.jsp b/src/main/webapp/WEB-INF/views/commons/layout/commonNavbar.jsp index 9f6c5e6f4..27a18e14b 100644 --- a/src/main/webapp/WEB-INF/views/commons/layout/commonNavbar.jsp +++ b/src/main/webapp/WEB-INF/views/commons/layout/commonNavbar.jsp @@ -133,6 +133,11 @@  <%= jspUtil.label("knowledge.navbar.config.system.mail") %> +
  • + +  <%= jspUtil.label("knowledge.ldap.title") %> + +
  • diff --git a/src/main/webapp/WEB-INF/views/open/emoji/nature.jsp b/src/main/webapp/WEB-INF/views/open/emoji/nature.jsp index 70fcb4732..0be0db75e 100644 --- a/src/main/webapp/WEB-INF/views/open/emoji/nature.jsp +++ b/src/main/webapp/WEB-INF/views/open/emoji/nature.jsp @@ -936,9 +936,9 @@
  • -
    - \ No newline at end of file + + diff --git a/src/main/webapp/WEB-INF/views/open/emoji/objects.jsp b/src/main/webapp/WEB-INF/views/open/emoji/objects.jsp index 8500f4c35..d2c680eee 100644 --- a/src/main/webapp/WEB-INF/views/open/emoji/objects.jsp +++ b/src/main/webapp/WEB-INF/views/open/emoji/objects.jsp @@ -2097,10 +2097,9 @@ - - - \ No newline at end of file + + diff --git a/src/main/webapp/WEB-INF/views/open/emoji/people.jsp b/src/main/webapp/WEB-INF/views/open/emoji/people.jsp index b821f568e..1702c7a4c 100644 --- a/src/main/webapp/WEB-INF/views/open/emoji/people.jsp +++ b/src/main/webapp/WEB-INF/views/open/emoji/people.jsp @@ -1554,8 +1554,6 @@ - - - - \ No newline at end of file + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/open/emoji/symbols.jsp b/src/main/webapp/WEB-INF/views/open/emoji/symbols.jsp index 7cf050d26..d8b778a80 100644 --- a/src/main/webapp/WEB-INF/views/open/emoji/symbols.jsp +++ b/src/main/webapp/WEB-INF/views/open/emoji/symbols.jsp @@ -1441,9 +1441,9 @@ - - \ No newline at end of file + + diff --git a/src/main/webapp/WEB-INF/views/open/knowledge/list.jsp b/src/main/webapp/WEB-INF/views/open/knowledge/list.jsp index 9454ed42f..0188da273 100644 --- a/src/main/webapp/WEB-INF/views/open/knowledge/list.jsp +++ b/src/main/webapp/WEB-INF/views/open/knowledge/list.jsp @@ -53,6 +53,22 @@ + + + @@ -120,7 +136,7 @@

    <%-- --%> - <%= jspUtil.out("knowledge.content", JspUtil.ESCAPE_CLEAR, 200) %> + <%= jspUtil.out("knowledge.content", JspUtil.ESCAPE_CLEAR, 300) %>

    diff --git a/src/main/webapp/WEB-INF/views/open/knowledge/search.jsp b/src/main/webapp/WEB-INF/views/open/knowledge/search.jsp index 3d3c65ac9..3ceedd3d5 100644 --- a/src/main/webapp/WEB-INF/views/open/knowledge/search.jsp +++ b/src/main/webapp/WEB-INF/views/open/knowledge/search.jsp @@ -14,37 +14,67 @@ - - - - - - - -

    <%= jspUtil.label("knowledge.view.title") %>

    - -
    -
    -
    - -
    -
    - " - name="keyword" id="keyword" value="<%=jspUtil.out("keyword")%>" /> -
    -
    -
    -
    - - <%= jspUtil.out("params") %>" - class="btn btn-success" role="button"> <%= jspUtil.label("label.backlist") %> - -
    + + +" /> + + + + + + + + + + + + + + +

    <%= jspUtil.label("knowledge.search.title") %>

    + +
    + + +
    + + " + name="keyword" id="keyword" value="<%=jspUtil.out("keyword")%>" />
    - +
    + +

    + " value="<%= jspUtil.out("tagNames") %>" /> +

    +
    + + + <%= jspUtil.out("params") %>" + class="btn btn-success" role="button"> <%= jspUtil.label("label.backlist") %> +
    + + + + + +
    diff --git a/src/main/webapp/WEB-INF/views/open/knowledge/view.jsp b/src/main/webapp/WEB-INF/views/open/knowledge/view.jsp index 569ed7ed2..9a73bb815 100644 --- a/src/main/webapp/WEB-INF/views/open/knowledge/view.jsp +++ b/src/main/webapp/WEB-INF/views/open/knowledge/view.jsp @@ -30,19 +30,18 @@ var LABEL_LIKE = '<%= jspUtil.label("knowledge.view.like") %>'; + +Knowledge - [<%= jspUtil.out("knowledgeId") %>] <%= jspUtil.out("title") %> + -

    <%= jspUtil.label("knowledge.view.title") %>

    - +<%--

    <%= jspUtil.label("knowledge.view.title") %>

    --%> +

    [<%= jspUtil.out("knowledgeId") %>] <%= jspUtil.out("title") %>

    -

    - [<%= jspUtil.out("knowledgeId") %>] <%= jspUtil.out("title") %> -

    -

    -

    +

    [<%= jspUtil.label("label.registration") %>]
    @@ -96,9 +95,9 @@ var LABEL_LIKE = '<%= jspUtil.label("knowledge.view.like") %>'; ">  <%= jspUtil.date("insertDatetime")%> -

    +
    -

    +

    [<%= jspUtil.label("label.update") %>]
    @@ -112,20 +111,21 @@ var LABEL_LIKE = '<%= jspUtil.label("knowledge.view.like") %>'; ">  <%= jspUtil.date("updateDatetime")%> -

    +
    -

    +

    -

    -

    +
    + <%= jspUtil.out("content", JspUtil.ESCAPE_NONE) %> +
    @@ -169,7 +169,7 @@ var LABEL_LIKE = '<%= jspUtil.label("knowledge.view.like") %>'; alt="icon" width="64" height="64"/>
    - <%= jspUtil.out("comment.comment", JspUtil.ESCAPE_CLEAR) %> + <%= jspUtil.out("comment.comment", JspUtil.ESCAPE_NONE) %>
    <% } else { %> @@ -185,7 +185,7 @@ var LABEL_LIKE = '<%= jspUtil.label("knowledge.view.like") %>'; alt="icon" width="64" height="64"/>
    - <%= jspUtil.out("comment.comment", JspUtil.ESCAPE_CLEAR) %> + <%= jspUtil.out("comment.comment", JspUtil.ESCAPE_NONE) %>
    <% } %> @@ -227,10 +227,6 @@ var LABEL_LIKE = '<%= jspUtil.label("knowledge.view.like") %>'; - - diff --git a/src/main/webapp/WEB-INF/views/open/license/index.jsp b/src/main/webapp/WEB-INF/views/open/license/index.jsp index 7fc51a2a9..6ba15250f 100644 --- a/src/main/webapp/WEB-INF/views/open/license/index.jsp +++ b/src/main/webapp/WEB-INF/views/open/license/index.jsp @@ -73,13 +73,34 @@ $(document).ready(function(){ - License: [Creative Commons Attribution-ShareAlike 3.0 license] http://creativecommons.org/licenses/by-sa/3.0/ - project-url: https://www.owasp.org/index.php/Category:OWASP_AntiSamy_Project +- OWASP/java-html-sanitizer + - License: [Apache License, Version 2.0] http://www.apache.org/licenses/LICENSE-2.0 + - project-url: https://github.com/owasp/java-html-sanitizer + - Apache Lucene - License: [Apache License, Version 2.0] http://www.apache.org/licenses/LICENSE-2.0 - project-url: http://lucene.apache.org/ -- Apache Tika +- Apache Directory + - License: [Apache License, Version 2.0] http://www.apache.org/licenses/LICENSE-2.0 + - project-url: https://directory.apache.org/ + +- Apache Directory + - License: [Apache License, Version 2.0] http://www.apache.org/licenses/LICENSE-2.0 + - project-url: https://directory.apache.org/ + +- PostgreSQL JDBC + - License: [BSD License] https://jdbc.postgresql.org/about/license.html + - project-url: http://www.postgresql.org/ + +- java-diff-utils - License: [Apache License, Version 2.0] http://www.apache.org/licenses/LICENSE-2.0 - - project-url: http://tika.apache.org/ + - project-url: https://code.google.com/p/java-diff-utils/ + +- pegdown + - License: [Apache License, Version 2.0] http://www.apache.org/licenses/LICENSE-2.0 + - project-url: https://github.com/sirthias/pegdown + #### Front end Library - jQuery @@ -122,7 +143,17 @@ $(document).ready(function(){ - License: [MIT] https://github.com/teambox/Free-file-icons/blob/master/LICENSE - project-url: https://github.com/teambox/Free-file-icons - +- echojs + - License: [MIT] http://opensource.org/licenses/mit-license.php + - project-url: https://github.com/toddmotto/echo + +- notify.js + - License: [MIT] https://github.com/alexgibson/notify.js/blob/master/LICENSE.md + - project-url: https://github.com/alexgibson/notify.js + +- emoji-parser + - License: [MIT] https://github.com/frissdiegurke/emoji-parser/blob/master/LICENSE.md + - project-url: https://github.com/frissdiegurke/emoji-parser diff --git a/src/main/webapp/WEB-INF/views/open/tag/dialog.jsp b/src/main/webapp/WEB-INF/views/open/tag/dialog.jsp new file mode 100644 index 000000000..90c89e319 --- /dev/null +++ b/src/main/webapp/WEB-INF/views/open/tag/dialog.jsp @@ -0,0 +1,69 @@ +<%@page import="org.support.project.web.util.JspUtil"%> +<%@page pageEncoding="UTF-8" isELIgnored="false" session="false" + errorPage="/WEB-INF/views/commons/errors/jsp_error.jsp"%> + +<% JspUtil jspUtil = new JspUtil(request, pageContext); %> + + + + diff --git a/src/main/webapp/WEB-INF/views/protect/account/index.jsp b/src/main/webapp/WEB-INF/views/protect/account/index.jsp index acbbeaeca..ca6122ea8 100644 --- a/src/main/webapp/WEB-INF/views/protect/account/index.jsp +++ b/src/main/webapp/WEB-INF/views/protect/account/index.jsp @@ -26,6 +26,14 @@

    <%= jspUtil.label("knowledge.account.title") %>

    +<% if(jspUtil.is(1, "authLdap")) { %> + +<% } %> +
    @@ -55,6 +63,23 @@
    +<% if(jspUtil.is(1, "authLdap")) { %> +
    + + " readonly="readonly" /> +
    +
    + + " readonly="readonly" /> +
    +
    + + " readonly="readonly" /> +
    +<% } else { %>
    " @@ -77,6 +102,9 @@ " />
    +<% } %> + +
    @@ -86,8 +114,9 @@

    - +<% if (!jspUtil.is(1, "authLdap")) { %> +<% } %>  <%= jspUtil.label("label.withdrawal")%> diff --git a/src/main/webapp/WEB-INF/views/protect/group/add_group.jsp b/src/main/webapp/WEB-INF/views/protect/group/add_group.jsp index 80c74ab58..108ebe777 100644 --- a/src/main/webapp/WEB-INF/views/protect/group/add_group.jsp +++ b/src/main/webapp/WEB-INF/views/protect/group/add_group.jsp @@ -45,13 +45,11 @@  <%= jspUtil.label("knowledge.group.edit.label.protect") %>
    - <%-- - --%>
    diff --git a/src/main/webapp/WEB-INF/views/protect/group/edit_group.jsp b/src/main/webapp/WEB-INF/views/protect/group/edit_group.jsp index 21650696d..6f264c58e 100644 --- a/src/main/webapp/WEB-INF/views/protect/group/edit_group.jsp +++ b/src/main/webapp/WEB-INF/views/protect/group/edit_group.jsp @@ -45,13 +45,11 @@  <%= jspUtil.label("knowledge.group.edit.label.protect") %>
    - <%-- - --%>
    "> diff --git a/src/main/webapp/WEB-INF/views/protect/group/view_group.jsp b/src/main/webapp/WEB-INF/views/protect/group/view_group.jsp index aba05e2a9..70fb46762 100644 --- a/src/main/webapp/WEB-INF/views/protect/group/view_group.jsp +++ b/src/main/webapp/WEB-INF/views/protect/group/view_group.jsp @@ -55,11 +55,14 @@ var _CONFIRM_DELETE = '<%= jspUtil.label("knowledge.group.view.label.confirm.del
    - "> + " id="groupId"> "> -

    <%= jspUtil.label("knowledge.group.view.label.member") %>

    +

    + <%= jspUtil.label("knowledge.group.view.label.member") %> + page[<%= jspUtil.getValue("offset", Integer.class) + 1 %>] +

    <% if(jspUtil.is(CommonWebParameter.GROUP_CLASS_PROTECT, "groupClass")) { %> @@ -84,27 +87,57 @@ var _CONFIRM_DELETE = '<%= jspUtil.label("knowledge.group.view.label.confirm.del +<% if(!jspUtil.is(CommonWebParameter.GROUP_CLASS_PRIVATE, "groupClass")) { %> " class="btn btn-danger" role="button"> <%= jspUtil.label("knowledge.group.view.label.unsubscribe") %> +<% } %> + +<% if(jspUtil.is(CommonWebParameter.GROUP_CLASS_PRIVATE, "groupClass") && jspUtil.is(Boolean.TRUE, "editAble")) { %> +<%-- 非公開グループのメンバー選択 --%> + +  メンバー選択 + +<% } %>

    +

    + + -<%= jspUtil.label("knowledge.accept.label.list.empty") %> +<%= jspUtil.label("knowledge.group.list.empty") %>
    -

    <%= jspUtil.out("user.userName") %>

    +

    + <%= jspUtil.out("user.userName") %> + +      + <%= jspUtil.label("label.status") %>: + <%= jspUtil.is(CommonWebParameter.GROUP_ROLE_WAIT, "user.groupRole", jspUtil.label("knowledge.group.view.label.role.wait")) %> + <%= jspUtil.is(CommonWebParameter.GROUP_ROLE_ADMIN, "user.groupRole", jspUtil.label("knowledge.group.view.label.role.admin")) %> + <%= jspUtil.is(CommonWebParameter.GROUP_ROLE_MEMBER, "user.groupRole", jspUtil.label("knowledge.group.view.label.role.member")) %> + + +

    - <%= jspUtil.label("label.status") %>: - <%= jspUtil.is(CommonWebParameter.GROUP_ROLE_WAIT, "user.groupRole", jspUtil.label("knowledge.group.view.label.role.wait")) %> - <%= jspUtil.is(CommonWebParameter.GROUP_ROLE_ADMIN, "user.groupRole", jspUtil.label("knowledge.group.view.label.role.admin")) %> - <%= jspUtil.is(CommonWebParameter.GROUP_ROLE_MEMBER, "user.groupRole", jspUtil.label("knowledge.group.view.label.role.member")) %> - -      + <% if (jspUtil.is(Boolean.TRUE, "editAble")) { %> <% if(jspUtil.is(CommonWebParameter.GROUP_ROLE_WAIT, "user.groupRole")) { %> ?userId=<%= jspUtil.out("user.userId") %>" class="btn btn-primary"> @@ -129,6 +162,22 @@ var _CONFIRM_DELETE = '<%= jspUtil.label("knowledge.group.view.label.confirm.del

    + + +
    @@ -137,7 +186,63 @@ var _CONFIRM_DELETE = '<%= jspUtil.label("knowledge.group.view.label.confirm.del  <%= jspUtil.label("knowledge.group.view.label.list") %> - + + + + +<%-- Targets --%> + + + + diff --git a/src/main/webapp/WEB-INF/views/protect/knowledge/view_add.jsp b/src/main/webapp/WEB-INF/views/protect/knowledge/view_add.jsp index 617f144d2..825abc5a5 100644 --- a/src/main/webapp/WEB-INF/views/protect/knowledge/view_add.jsp +++ b/src/main/webapp/WEB-INF/views/protect/knowledge/view_add.jsp @@ -19,10 +19,12 @@ + + @@ -140,9 +147,14 @@ selectedEditors.push({label: '<%= jspUtil.out("editor.label") %>', value: '<%= j
    - +

    - " value="<%= jspUtil.out("tagNames") %>" />

    @@ -282,6 +294,7 @@ selectedEditors.push({label: '<%= jspUtil.out("editor.label") %>', value: '<%= j +
    diff --git a/src/main/webapp/WEB-INF/views/protect/knowledge/view_edit.jsp b/src/main/webapp/WEB-INF/views/protect/knowledge/view_edit.jsp index cf8478ae4..3252f93ce 100644 --- a/src/main/webapp/WEB-INF/views/protect/knowledge/view_edit.jsp +++ b/src/main/webapp/WEB-INF/views/protect/knowledge/view_edit.jsp @@ -19,10 +19,12 @@ + + @@ -142,9 +149,14 @@ selectedEditors.push({label: '<%= jspUtil.out("editor.label") %>', value: '<%= j
    - +

    - " value="<%= jspUtil.out("tagNames") %>" />

    @@ -285,6 +297,7 @@ selectedEditors.push({label: '<%= jspUtil.out("editor.label") %>', value: '<%= j +
    diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 48d65c4f9..30672ff44 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -44,11 +44,15 @@ AuthenticationFilter - org.support.project.web.filter.AuthenticationFilter + org.support.project.knowledge.listener.CloseAbleAuthenticationFilter ignore-regular-expression ^/index|^/open|^/template|^/bower|^/images|^/css|^/js|^/favicon.ico|^/lang|css$|js$|jpg$|jpeg$|gif$|png$|ico$|html$ + + close-ignore-regular-expression + ^/index|^/template|^/bower|^/images|^/css|^/js|^/favicon.ico|^/lang|css$|js$|jpg$|jpeg$|gif$|png$|ico$|html$|^/open.signup|^/open.PasswordInitialization + login-page /WEB-INF/views/auth/form.jsp diff --git a/src/main/webapp/css/knowledge-edit.css b/src/main/webapp/css/knowledge-edit.css index b8d68fce3..00ecf7fd2 100644 --- a/src/main/webapp/css/knowledge-edit.css +++ b/src/main/webapp/css/knowledge-edit.css @@ -3,11 +3,11 @@ margin-top: 50px; } -.insert_info { - border-bottom: 1px solid #cccccc; -} .bootstrap-tagsinput { width: 100%; } +.bootstrap-tagsinput input { + min-width: 300px; +} .filediv { @@ -74,3 +74,10 @@ .sampleMarkdownText { word-wrap: break-word; } + +#tagDatas .name { + cursor: pointer; + border-bottom: 1px solid gray; +} + + diff --git a/src/main/webapp/css/knowledge-view.css b/src/main/webapp/css/knowledge-view.css index 09f392f7a..2b6c5f3d2 100644 --- a/src/main/webapp/css/knowledge-view.css +++ b/src/main/webapp/css/knowledge-view.css @@ -25,7 +25,18 @@ vertical-align: middle; } +.insert_info { + margin-top: 5px; + border-bottom: 1px solid #cccccc; +} + +.downloadfile { + margin-top: 5px; +} +#content { + margin-top: 20px; +} /*============================================================ @@ -68,7 +79,7 @@ Comments .arrow_answer:before, .arrow_question:after, .arrow_question:before { - top: 50%; + top: 30px; border: solid transparent; content: " "; height: 0; diff --git a/src/main/webapp/js/group.js b/src/main/webapp/js/group.js index 96878ae2f..7b524a44a 100644 --- a/src/main/webapp/js/group.js +++ b/src/main/webapp/js/group.js @@ -7,5 +7,108 @@ function deleteGroup() { }); }; +var slectedUser = []; +var slectedUserName = []; +$(document).ready(function() { + // targets + var keyword = $('#groupKeyword').val(); + var offset = 0; + $('#groupSelectModal').on('show.bs.modal', function (event) { + getGroups(keyword, offset); + }); + $('#groupSearchButton').click(function() { + keyword = $('#groupKeyword').val(); + offset = 0; + getGroups(keyword, offset); + }); + $('#groupSearchPrevious').click(function() { + keyword = $('#groupKeyword').val(); + offset--; + if (offset < 0){ + offset = 0; + } + getGroups(keyword, offset); + }); + $('#groupSearchNext').click(function() { + keyword = $('#groupKeyword').val(); + offset++; + getGroups(keyword, offset); + }); + $('#groupDecision').click(function() { + $('#groupSelectModal').modal('hide') + }); + $('#clearSelectedGroup').click(function() { + slectedUser = []; + slectedUserName = []; + $('#selectedList').text(slectedUserName.join(',')); + }); + $('#groupAdd').click(function() { + $('#loading').html(''); + + // 選択されているユーザをグループに追加 + $.post(_CONTEXT + '/protect.group/addusers', { + group : $('#groupId').val(), + users : slectedUser.join(',') + }, function(data) { + console.log(data); + //再読み込みすれば追加したメンバーを表示 + window.location.reload(); + //$('#groupSelectModal').modal('hide'); + }); + }); +}); + + +var getGroups = function(keyword, offset, listId, pageId, selectFunc) { + if (!listId) { + listId = '#groupList'; + pageId = '#groupPage'; + selectFunc = 'selectGroup'; + } + $(listId).html('Now loading...'); + var url = _CONTEXT + '/protect.target/typeahead' + var params = { + keyword : keyword, + offset: offset, + filter: 'user' + }; + + $.get(url, params, function(result){ + groups = result; + editors = result; + var html = ''; + if (result.length == 0) { + html += 'empty'; + } else { + html+= '
    '; + for (var int = 0; int < result.length; int++) { + html += ''; + html += result[int].label; + html += ''; + } + html += '
    '; + } + $(listId).html(html); + $(pageId).text('- page:' + (offset + 1) + ' -'); + }); +}; + + +var selectGroup = function(idx) { + var exist = false; + for (var i = 0; i < slectedUser.length; i++) { + var item = slectedUser[i]; + if (item == groups[idx].value) { + exist = true; + break; + } + } + if (!exist) { + console.log(groups[idx]); + slectedUser.push(groups[idx].value); + slectedUserName.push(groups[idx].label); + $('#selectedList').text(slectedUserName.join(',')); + } +}; diff --git a/src/main/webapp/js/knowledge-edit.js b/src/main/webapp/js/knowledge-edit.js index b378e5dec..dabc4413c 100644 --- a/src/main/webapp/js/knowledge-edit.js +++ b/src/main/webapp/js/knowledge-edit.js @@ -80,7 +80,27 @@ $(document).ready(function() { }).prop('disabled', !$.support.fileInput).parent().addClass($.support.fileInput ? undefined : 'disabled'); var elt= $('#input_tags'); - elt.tagsinput(); + elt.tagsinput({ + typeahead: { + source: _TAGS, + displayText: function(item) { + if (item) { + return item.name || item; + } + return ''; + } + }, + freeInput: true + }); + elt.on('typeahead:selected', function(event, datum) { + console.log(datum); + }); + /* + $('#input_tags').on('itemAdded', function(event) { + console.log(event); + $('#input_tags').tagsinput('refresh'); + }); + */ dispChangeGroupArea($('input[name="publicFlag"]:checked').val()); $('input[name="publicFlag"]:radio').change( function() { @@ -176,6 +196,7 @@ $(document).ready(function() { $('html,body').animate({ scrollTop: p }, 'fast'); }); + setUpTagSelect(); }); var getGroups = function(keyword, offset, listId, pageId, selectFunc) { @@ -319,12 +340,10 @@ var setImagePath = function(url, name) { var emoji = window.emojiParser; var preview = function() { - $.post(_CONTEXT + '/open.knowledge/escape', { + $.post(_CONTEXT + '/open.knowledge/marked', { title : $('#input_title').val(), content : $('#content').val() }, function(data) { - $('#content_text').html(data.content); - var html = '
    '; html += '
    '; html += '
    '; @@ -334,7 +353,7 @@ var preview = function() { html += data.title; html += '
    '; html += '

    '; - var content = marked($('#content_text').html()); + var content = data.content; html += content; html += '

    '; html += '
    '; diff --git a/src/main/webapp/js/knowledge-view.js b/src/main/webapp/js/knowledge-view.js index ace8b9851..5440c2d08 100644 --- a/src/main/webapp/js/knowledge-view.js +++ b/src/main/webapp/js/knowledge-view.js @@ -8,12 +8,14 @@ $(document).ready(function(){ } }); var emoji = window.emojiParser; - $('#content').html(marked($('#content_text').text())); - $('#content pre code').each(function(i, block) { + $('#content').find('pre code').each(function(i, block) { hljs.highlightBlock(block); }); - var content = emoji($('#content').html(), _CONTEXT + '/bower/emoji-parser/emoji', {classes: 'emoji-img'}); - $('#content').html(content); + + console.log($('#content').html()); + var html = emoji($('#content').html(), _CONTEXT + '/bower/emoji-parser/emoji', {classes: 'emoji-img'}); + $('#content').html(html); + console.log($('#content').html()); echo.init(); @@ -32,8 +34,8 @@ $(document).ready(function(){ }); $('.arrow_question').each(function(i, block) { - var content = $(this).text().trim(); - content = marked(content); + var content = $(this).html().trim(); + //content = marked(content); $(this).html(content); $(this).find('pre code').each(function(i, block) { hljs.highlightBlock(block); @@ -43,8 +45,8 @@ $(document).ready(function(){ $(this).html(content); }); $('.arrow_answer').each(function(i, block) { - var content = $(this).text().trim(); - content = marked(content); + var content = $(this).html().trim(); + //content = marked(content); $(this).html(content); $(this).find('pre code').each(function(i, block) { hljs.highlightBlock(block); @@ -116,11 +118,10 @@ var viewProtect = function(knowledgeId) { var preview = function() { - $.post(_CONTEXT + '/open.knowledge/escape', { + $.post(_CONTEXT + '/open.knowledge/marked', { title : '', content : $('#comment').val() }, function(data) { - $('#comment_text').html(data.content); var html = '
    '; html += '
    '; html += ' list = new ArrayList(); + String s; + while((s = reader.readLine())!=null){ + list.add(s); + } + return list.toArray(new String[0]); + } finally { + if (reader != null) { + reader.close(); + } + } + + } + + @Test + @Order(order= 1) + public void test1() throws Exception { + String markdown = FileUtil.read(getClass().getResourceAsStream("markdown/markdown-1.md")); + String html = FileUtil.read(getClass().getResourceAsStream("markdown/result-1.txt")); + String result = MarkdownLogic.get().markdownToHtml(markdown).getHtml(); + try { + org.junit.Assert.assertArrayEquals(read(html), read(result)); + } catch (AssertionError e) { + LOG.info("test1"); + LOG.info("[Markdown] : " + markdown); + LOG.info("[Html] : " + html); + LOG.info("[Parsed] : " + result); + LOG.info("[Indent] : " + SanitizingLogic.get().indent(result)); + throw e; + } + } + + @Test + @Order(order= 2) + public void test2() throws UnsupportedEncodingException, IOException, ParseException, TransformerFactoryConfigurationError, TransformerException { + String markdown = FileUtil.read(getClass().getResourceAsStream("markdown/markdown-2.md")); + String html = FileUtil.read(getClass().getResourceAsStream("markdown/result-2.txt")); + String result = MarkdownLogic.get().markdownToHtml(markdown).getHtml(); + try { + org.junit.Assert.assertArrayEquals(read(html), read(result)); + } catch (AssertionError e) { + LOG.info("test2"); + LOG.info("[Markdown] : " + markdown); + LOG.info("[Html] : " + html); + LOG.info("[Parsed] : " + result); + LOG.info("[Indent] : " + SanitizingLogic.get().indent(result)); + throw e; + } + } + + @Test + @Order(order= 3) + public void test3() throws ParseException, UnsupportedEncodingException, IOException, TransformerFactoryConfigurationError, TransformerException { + String markdown = FileUtil.read(getClass().getResourceAsStream("markdown/markdown-3.md")); + String html = FileUtil.read(getClass().getResourceAsStream("markdown/result-3.txt")); + String result = MarkdownLogic.get().markdownToHtml(markdown).getHtml(); + try { + org.junit.Assert.assertArrayEquals(read(html), read(result)); + } catch (AssertionError e) { + LOG.info("test3"); + LOG.info("[Markdown] : " + markdown); + LOG.info("[Html] : " + html); + LOG.info("[Parsed] : " + result); + LOG.info("[Indent] : " + SanitizingLogic.get().indent(result)); + throw e; + } + } + + @Test + @Order(order= 4) + public void test4() throws ParseException, UnsupportedEncodingException, IOException, TransformerFactoryConfigurationError, TransformerException { + String markdown = FileUtil.read(getClass().getResourceAsStream("markdown/markdown-4.md")); + String html = FileUtil.read(getClass().getResourceAsStream("markdown/result-4.txt")); + String result = MarkdownLogic.get().markdownToHtml(markdown).getHtml(); + try { + org.junit.Assert.assertArrayEquals(read(html), read(result)); + } catch (AssertionError e) { + LOG.info("test4"); + LOG.info("[Markdown] : " + markdown); + LOG.info("[Html] : " + html); + LOG.info("[Parsed] : " + result); + LOG.info("[Indent] : " + SanitizingLogic.get().indent(result)); + throw e; + } + } + + @Test + @Order(order= 5) + public void test5() throws ParseException, UnsupportedEncodingException, IOException, TransformerFactoryConfigurationError, TransformerException { + String markdown = FileUtil.read(getClass().getResourceAsStream("markdown/markdown-5.md")); + String html = FileUtil.read(getClass().getResourceAsStream("markdown/result-5.txt")); + String result = MarkdownLogic.get().markdownToHtml(markdown).getHtml(); + try { + org.junit.Assert.assertArrayEquals(read(html), read(result)); + } catch (AssertionError e) { + LOG.info("test5"); + LOG.info("[Markdown] : " + markdown); + LOG.info("[Html] : " + html); + LOG.info("[Parsed] : " + result); + LOG.info("[Indent] : " + SanitizingLogic.get().indent(result)); + throw e; + } + } + + + @Test + @Order(order= 6) + public void test6() throws ParseException, UnsupportedEncodingException, IOException, TransformerFactoryConfigurationError, TransformerException { + String markdown = FileUtil.read(getClass().getResourceAsStream("markdown/markdown-6.md")); + String html = FileUtil.read(getClass().getResourceAsStream("markdown/result-6.txt")); + String result = MarkdownLogic.get().markdownToHtml(markdown, MarkdownLogic.ENGINE_MARKEDJS).getHtml(); + try { + org.junit.Assert.assertArrayEquals(read(html), read(result)); + } catch (AssertionError e) { + LOG.info("test5"); + LOG.info("[Markdown] : " + markdown); + LOG.info("[Html] : " + html); + LOG.info("[Parsed] : " + result); + LOG.info("[Indent] : " + SanitizingLogic.get().indent(result)); + throw e; + } + + markdown = FileUtil.read(getClass().getResourceAsStream("markdown/markdown-6-2.md")); + html = FileUtil.read(getClass().getResourceAsStream("markdown/result-6-2.txt")); + result = MarkdownLogic.get().markdownToHtml(markdown, MarkdownLogic.ENGINE_MARKEDJS).getHtml(); + try { + org.junit.Assert.assertArrayEquals(read(html), read(result)); + } catch (AssertionError e) { + LOG.info("test5"); + LOG.info("[Markdown] : " + markdown); + LOG.info("[Html] : " + html); + LOG.info("[Parsed] : " + result); + LOG.info("[Indent] : " + SanitizingLogic.get().indent(result)); + throw e; + } + markdown = FileUtil.read(getClass().getResourceAsStream("markdown/markdown-6-2.md")); + html = FileUtil.read(getClass().getResourceAsStream("markdown/result-6-2.txt")); + result = MarkdownLogic.get().markdownToHtml(markdown, MarkdownLogic.ENGINE_MARKEDJS).getHtml(); + try { + org.junit.Assert.assertArrayEquals(read(html), read(result)); + } catch (AssertionError e) { + LOG.info("test5"); + LOG.info("[Markdown] : " + markdown); + LOG.info("[Html] : " + html); + LOG.info("[Parsed] : " + result); + LOG.info("[Indent] : " + SanitizingLogic.get().indent(result)); + throw e; + } + } + + + +} diff --git a/src/test/java/org/support/project/knowledge/sample/ApacheLdapSample.java b/src/test/java/org/support/project/knowledge/sample/ApacheLdapSample.java new file mode 100644 index 000000000..9e923e506 --- /dev/null +++ b/src/test/java/org/support/project/knowledge/sample/ApacheLdapSample.java @@ -0,0 +1,78 @@ +package org.support.project.knowledge.sample; + +import org.apache.directory.api.ldap.model.cursor.Cursor; +import org.apache.directory.api.ldap.model.cursor.CursorException; +import org.apache.directory.api.ldap.model.entry.Entry; +import org.apache.directory.api.ldap.model.exception.LdapException; +import org.apache.directory.api.ldap.model.message.SearchScope; +import org.apache.directory.ldap.client.api.LdapConnection; +import org.apache.directory.ldap.client.api.LdapConnectionConfig; +import org.apache.directory.ldap.client.api.LdapNetworkConnection; + +public class ApacheLdapSample { + + public static void main(String[] args) throws Exception { + LdapConnectionConfig sslConfig=new LdapConnectionConfig(); + sslConfig.setLdapHost("localhost"); // LDAP Host +// sslConfig.setUseSsl(true); // Use SSL +// sslConfig.setUseTls(true); // USE TLS + sslConfig.setLdapPort(10389); // LDAP Port + + LdapConnection conn = new LdapNetworkConnection(sslConfig); + Cursor cursor = null; + try { + conn.bind( "uid=admin,ou=system", "secret" ); // Bind DN //Bind Password (接続確認用) + + String base = "dc=example,dc=com"; //Base DN + String filter = "(uid=user1)"; // filter (user idから) + //User id attribute + //User name attribute + //Mail address attribute + //Additional filter condition + //Enable TLS + //Enable SSL + + SearchScope scope = SearchScope.SUBTREE; + + cursor = conn.search(base, filter, scope); + while (cursor.next()) { + Entry entry = cursor.get(); + System.out.println(entry.get("uid").toString()); + System.out.println(entry.get("cn").toString()); + if (entry.get("mail") != null) { + System.out.println(entry.get("mail").toString()); + } + } + cursor.close(); + conn.unBind(); + + //ユーザーで認証 + conn.bind( "uid=user1,dc=example,dc=com", "test1234" ); // Bind DN //Bind Password + + System.out.println("OK"); + + cursor = conn.search(base, filter, scope); + while (cursor.next()) { + Entry entry = cursor.get(); + System.out.println(entry.get("uid").toString()); + System.out.println(entry.get("cn").toString()); + if (entry.get("mail") != null) { + System.out.println(entry.get("mail").toString()); + } + } + + + + } catch (CursorException | LdapException e) { + e.printStackTrace(); + } finally { + if (cursor != null) { + cursor.close(); + } + conn.unBind(); + conn.close(); + } + + } + +} diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-1.md b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-1.md new file mode 100644 index 000000000..dd978d493 --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-1.md @@ -0,0 +1,3 @@ +# テスト +- 簡単なmarkdown +- 箇条書き diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-2.md b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-2.md new file mode 100644 index 000000000..bf4b22fe7 --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-2.md @@ -0,0 +1,10 @@ +# テスト +- 簡単なmarkdown +- HTMLのタグを使える? + - インデント + - 少しだけ複雑 +- どうなるか? + +## 見出し2 +- Javascriptで簡単にパースしていたけど、Java側で実行した方が制御しやすいね + diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-3.md b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-3.md new file mode 100644 index 000000000..a1115316c --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-3.md @@ -0,0 +1,18 @@ +# テスト +- 簡単なmarkdown +- HTMLのタグを使える? + - インデント + - 少しだけ複雑 +- どうなるか? + +## 見出し2 +- Javascriptで簡単にパースしていたけど、Java側で実行した方が制御しやすいね +- 危険な + +### Script + + +- PegDownProcessorだけだと、そのまま出力する(XSSでやばそう) +- + + diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-4.md b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-4.md new file mode 100644 index 000000000..0dfd95a4b --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-4.md @@ -0,0 +1,33 @@ +# テスト +- 簡単なmarkdown +- HTMLのタグを使える? + - インデント + - 少しだけ複雑 +- どうなるか? + +## 見出し2 +- Javascriptで簡単にパースしていたけど、Java側で実行した方が制御しやすいね +- 危険な + +### Script + +これ通る? +

    通らない

    + +- PegDownProcessorだけだと、そのまま出力する(XSSでやばそう) +- サニタイジングする + +```ruby:qiita.rb +puts 'The best way to log and share programmers knowledge.' +``` + +```html + +``` + +```java +private List params = new ArrayList<>(); +``` + + + diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-5.md b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-5.md new file mode 100644 index 000000000..0dfd95a4b --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-5.md @@ -0,0 +1,33 @@ +# テスト +- 簡単なmarkdown +- HTMLのタグを使える? + - インデント + - 少しだけ複雑 +- どうなるか? + +## 見出し2 +- Javascriptで簡単にパースしていたけど、Java側で実行した方が制御しやすいね +- 危険な + +### Script + +これ通る? +

    通らない

    + +- PegDownProcessorだけだと、そのまま出力する(XSSでやばそう) +- サニタイジングする + +```ruby:qiita.rb +puts 'The best way to log and share programmers knowledge.' +``` + +```html + +``` + +```java +private List params = new ArrayList<>(); +``` + + + diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-6-2.md b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-6-2.md new file mode 100644 index 000000000..addfbd463 --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-6-2.md @@ -0,0 +1,40 @@ +# テスト +- 簡単なmarkdown +- HTMLのタグを使える? + - インデント + - 少しだけ複雑 +- どうなるか? + +## 見出し2 +- Javascriptで簡単にパースしていたけど、Java側で実行した方が制御しやすいね +- 危険な + +1. テスト +2. ほげ + 1. テスト + 2. 階層 +3. 数値 + + +### Script + +これ通る? +

    通らない

    + +- PegDownProcessorだけだと、そのまま出力する(XSSでやばそう) +- サニタイジングする + +```ruby:qiita.rb +puts 'The best way to log and share programmers knowledge.' +``` + +```html + +``` + +```java +private List params = new ArrayList<>(); +``` + + + diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-6.md b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-6.md new file mode 100644 index 000000000..0dfd95a4b --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/markdown-6.md @@ -0,0 +1,33 @@ +# テスト +- 簡単なmarkdown +- HTMLのタグを使える? + - インデント + - 少しだけ複雑 +- どうなるか? + +## 見出し2 +- Javascriptで簡単にパースしていたけど、Java側で実行した方が制御しやすいね +- 危険な + +### Script + +これ通る? +

    通らない

    + +- PegDownProcessorだけだと、そのまま出力する(XSSでやばそう) +- サニタイジングする + +```ruby:qiita.rb +puts 'The best way to log and share programmers knowledge.' +``` + +```html + +``` + +```java +private List params = new ArrayList<>(); +``` + + + diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/result-1.txt b/src/test/resources/org/support/project/knowledge/logic/markdown/result-1.txt new file mode 100644 index 000000000..ca1bbca90 --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/result-1.txt @@ -0,0 +1,2 @@ +

    テスト

    +
    • 簡単なmarkdown
    • 箇条書き
    \ No newline at end of file diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/result-2.txt b/src/test/resources/org/support/project/knowledge/logic/markdown/result-2.txt new file mode 100644 index 000000000..148165f5d --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/result-2.txt @@ -0,0 +1,3 @@ +

    テスト

    +
    • 簡単なmarkdown
    • HTMLのタグを使える?
    • インデント
    • 少しだけ複雑
    • どうなるか?

    見出し2

    +
    • Javascriptで簡単にパースしていたけど、Java側で実行した方が制御しやすいね
    \ No newline at end of file diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/result-3.txt b/src/test/resources/org/support/project/knowledge/logic/markdown/result-3.txt new file mode 100644 index 000000000..d5638f33f --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/result-3.txt @@ -0,0 +1,5 @@ +

    テスト

    +
    • 簡単なmarkdown
    • HTMLのタグを使える?
    • インデント
    • 少しだけ複雑
    • どうなるか?

    見出し2

    +
    • Javascriptで簡単にパースしていたけど、Java側で実行した方が制御しやすいね
    • 危険な

    Script

    + +
    • PegDownProcessorだけだと、そのまま出力する(XSSでやばそう)
    \ No newline at end of file diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/result-4.txt b/src/test/resources/org/support/project/knowledge/logic/markdown/result-4.txt new file mode 100644 index 000000000..2922bb20d --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/result-4.txt @@ -0,0 +1,11 @@ +

    テスト

    +
    • 簡単なmarkdown
    • HTMLのタグを使える?
    • インデント
    • 少しだけ複雑
    • どうなるか?

    見出し2

    +
    • Javascriptで簡単にパースしていたけど、Java側で実行した方が制御しやすいね
    • 危険な

    Script

    +

    これ通る?

    通らない

    +
    • PegDownProcessorだけだと、そのまま出力する(XSSでやばそう)
    • サニタイジングする
    +
    puts 'The best way to log and share programmers knowledge.'
    +
    +
    <button>hogehoge</button>
    +
    +
    private List<Object> params = new ArrayList<>();
    +
    \ No newline at end of file diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/result-5.txt b/src/test/resources/org/support/project/knowledge/logic/markdown/result-5.txt new file mode 100644 index 000000000..2922bb20d --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/result-5.txt @@ -0,0 +1,11 @@ +

    テスト

    +
    • 簡単なmarkdown
    • HTMLのタグを使える?
    • インデント
    • 少しだけ複雑
    • どうなるか?

    見出し2

    +
    • Javascriptで簡単にパースしていたけど、Java側で実行した方が制御しやすいね
    • 危険な

    Script

    +

    これ通る?

    通らない

    +
    • PegDownProcessorだけだと、そのまま出力する(XSSでやばそう)
    • サニタイジングする
    +
    puts 'The best way to log and share programmers knowledge.'
    +
    +
    <button>hogehoge</button>
    +
    +
    private List<Object> params = new ArrayList<>();
    +
    \ No newline at end of file diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/result-6-2.txt b/src/test/resources/org/support/project/knowledge/logic/markdown/result-6-2.txt new file mode 100644 index 000000000..eb392cbe1 --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/result-6-2.txt @@ -0,0 +1,21 @@ +

    テスト

    +
    • 簡単なmarkdown
    • HTMLのタグを使える?
      • インデント
        • 少しだけ複雑
        +
      +
    • どうなるか?
    +

    見出し2

    +
    • Javascriptで簡単にパースしていたけど、Java側で実行した方が制御しやすいね
    • 危険な

      +
    • テスト

      +
    • ほげ
      1. テスト
        1. 階層
        +
      +
    • 数値
    +

    Script

    +

    +これ通る?

    +

    通らない

    +
    • PegDownProcessorだけだと、そのまま出力する(XSSでやばそう)
    • サニタイジングする
    +
    puts 'The best way to log and share programmers knowledge.'
    +
    +
    <button>hogehoge</button>
    +
    +
    private List<Object> params = new ArrayList<>();
    +
    diff --git a/src/test/resources/org/support/project/knowledge/logic/markdown/result-6.txt b/src/test/resources/org/support/project/knowledge/logic/markdown/result-6.txt new file mode 100644 index 000000000..47c5955d8 --- /dev/null +++ b/src/test/resources/org/support/project/knowledge/logic/markdown/result-6.txt @@ -0,0 +1,17 @@ +

    テスト

    +
    • 簡単なmarkdown
    • HTMLのタグを使える?
      • インデント
        • 少しだけ複雑
        +
      +
    • どうなるか?
    +

    見出し2

    +
    • Javascriptで簡単にパースしていたけど、Java側で実行した方が制御しやすいね
    • 危険な
    +

    Script

    +

    +これ通る?

    +

    通らない

    +
    • PegDownProcessorだけだと、そのまま出力する(XSSでやばそう)
    • サニタイジングする
    +
    puts 'The best way to log and share programmers knowledge.'
    +
    +
    <button>hogehoge</button>
    +
    +
    private List<Object> params = new ArrayList<>();
    +
    \ No newline at end of file