diff --git a/bubble-server/src/main/java/bubble/dao/SessionDAO.java b/bubble-server/src/main/java/bubble/dao/SessionDAO.java index 19600753..9f99051a 100644 --- a/bubble-server/src/main/java/bubble/dao/SessionDAO.java +++ b/bubble-server/src/main/java/bubble/dao/SessionDAO.java @@ -17,9 +17,4 @@ public class SessionDAO extends AbstractSessionDAO { @Override protected boolean canStartSession(Account account) { return !account.suspended(); } - @Override public String create(Account account) { - account.setFirstAdmin(account.getUuid().equals(accountDAO.getFirstAdmin().getUuid())); - return super.create(account); - } - } diff --git a/bubble-server/src/main/java/bubble/dao/account/AccountDAO.java b/bubble-server/src/main/java/bubble/dao/account/AccountDAO.java index ed2f2ea3..45746fe0 100644 --- a/bubble-server/src/main/java/bubble/dao/account/AccountDAO.java +++ b/bubble-server/src/main/java/bubble/dao/account/AccountDAO.java @@ -470,6 +470,8 @@ public class AccountDAO extends AbstractCRUDDAO implements SqlViewSearc private final Refreshable firstAdmin = new Refreshable<>("firstAdmin", FIRST_ADMIN_CACHE_MILLIS, this::findFirstAdmin); public Account getFirstAdmin() { return firstAdmin.get(); } + public boolean isFirstAdmin(Account account) { return getFirstAdmin().getUuid().equals(account.getUuid()); } + public Account findFirstAdmin() { final List admins = findByField("admin", true); if (admins.isEmpty()) return null; diff --git a/bubble-server/src/main/java/bubble/resources/account/AuthResource.java b/bubble-server/src/main/java/bubble/resources/account/AuthResource.java index d1092d89..c05de6e9 100644 --- a/bubble-server/src/main/java/bubble/resources/account/AuthResource.java +++ b/bubble-server/src/main/java/bubble/resources/account/AuthResource.java @@ -113,11 +113,13 @@ public class AuthResource { return accountDAO.update(account.setLastLogin()); } - public String newLoginSession(Account account) { return newLoginSession(account, accountDAO, sessionDAO); } + public Account newLoginSession(Account account) { return newLoginSession(account, accountDAO, sessionDAO); } - public static String newLoginSession(Account account, AccountDAO accountDAO, SessionDAO sessionDAO) { - if (account.getLastLogin() == null) account.setFirstLogin(true); - return sessionDAO.create(updateLastLogin(account, accountDAO)); + public static Account newLoginSession(Account account, AccountDAO accountDAO, SessionDAO sessionDAO) { + return account + .setToken(sessionDAO.create(updateLastLogin(account, accountDAO))) + .setFirstLogin(account.getLastLogin() == null ? true : null) + .setFirstAdmin(accountDAO.isFirstAdmin(account)); } @GET @Path(EP_CONFIGS) @@ -175,7 +177,7 @@ public class AuthResource { final Account account = accountDAO.create(new Account(request).setRemoteHost(getRemoteHost(req))); activationService.bootstrapThisNode(account, request); - return ok(account.setToken(newLoginSession(account))); + return ok(newLoginSession(account)); } @Autowired private NotificationService notificationService; @@ -344,10 +346,9 @@ public class AuthResource { } } account.getAccountInitializer().setCanSendAccountMessages(); - return ok(account + return ok(newLoginSession(account .waitForAccountInit() - .setPromoError(promoEx == null ? null : promoEx.getMessageTemplate()) - .setToken(newLoginSession(account))); + .setPromoError(promoEx == null ? null : promoEx.getMessageTemplate()))); } @POST @Path(EP_LOGIN) @@ -419,8 +420,7 @@ public class AuthResource { } } - if (!account.hasToken()) account.setToken(newLoginSession(account)); - return ok(account); + return ok(account.hasToken() ? account : newLoginSession(account)); } @POST @Path(EP_APP_LOGIN+"/{session}") @@ -610,7 +610,7 @@ public class AuthResource { if (approval.getMessageType() == AccountMessageType.confirmation) { if (account == null) return invalid("err.approvalToken.invalid"); if (approval.getAction() == AccountAction.login || approval.getAction() == AccountAction.password) { - return ok(account.setToken(newLoginSession(account))); + return ok(newLoginSession(account)); } else { return ok_empty(); } diff --git a/bubble-server/src/main/java/bubble/resources/account/TrustedAuthResource.java b/bubble-server/src/main/java/bubble/resources/account/TrustedAuthResource.java index d04347ea..219149c0 100644 --- a/bubble-server/src/main/java/bubble/resources/account/TrustedAuthResource.java +++ b/bubble-server/src/main/java/bubble/resources/account/TrustedAuthResource.java @@ -84,7 +84,7 @@ public class TrustedAuthResource { final TrustedClient trusted = findTrustedClient(account, request); log.info("loginTrustedClient: logging in trusted: "+account.getName()); - return ok(account.setToken(newLoginSession(account, accountDAO, sessionDAO))); + return ok(newLoginSession(account, accountDAO, sessionDAO)); } @DELETE @Path(EP_DELETE+"/{device}") diff --git a/bubble-server/src/main/resources/messages b/bubble-server/src/main/resources/messages index 85fdd6f7..3b532dc0 160000 --- a/bubble-server/src/main/resources/messages +++ b/bubble-server/src/main/resources/messages @@ -1 +1 @@ -Subproject commit 85fdd6f72a2434ecfe75883ae14cd0ea000bbf22 +Subproject commit 3b532dc0f4956aeff74d0b178f2cf4a43fea29ef diff --git a/bubble-server/src/main/resources/packer/roles/bubble/files/init_bubble_db.sh b/bubble-server/src/main/resources/packer/roles/bubble/files/init_bubble_db.sh index a70251ad..b79bf8dc 100644 --- a/bubble-server/src/main/resources/packer/roles/bubble/files/init_bubble_db.sh +++ b/bubble-server/src/main/resources/packer/roles/bubble/files/init_bubble_db.sh @@ -13,7 +13,7 @@ function die { } function log { - echo "${1}" >> ${LOG} + echo "$(date): ${1}" >> ${LOG} } export LANG="en_US.UTF-8" diff --git a/bubble-server/src/main/resources/packer/roles/bubble/files/log_manager.sh b/bubble-server/src/main/resources/packer/roles/bubble/files/log_manager.sh index 7003ed0f..2f18f7a8 100755 --- a/bubble-server/src/main/resources/packer/roles/bubble/files/log_manager.sh +++ b/bubble-server/src/main/resources/packer/roles/bubble/files/log_manager.sh @@ -2,23 +2,52 @@ # # Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ # +LOG=/var/log/bubble/log_manager.log + +function log { + echo "$(date): ${1}" >> ${LOG} +} + BUBBLE_LOGS_FOLDER=/var/log/bubble +POSTGRES_LOGS_FOLDER=$(readlink -f "${BUBBLE_LOGS_FOLDER}"/postgresql) REDIS_LOG_FLAG_KEY="bubble.StandardSelfNodeService.bubble_server_logs_enabled" REDIS_LOG_FLAG_VALUE=$(echo "get ${REDIS_LOG_FLAG_KEY}" | redis-cli | xargs echo | tr '[:upper:]' '[:lower:]') +log "starting log manager with REDIS_LOG_FLAG_VALUE=${REDIS_LOG_FLAG_VALUE}" if [[ ${REDIS_LOG_FLAG_VALUE} == true ]]; then is_reload_needed=false - for logFile in $(find "${BUBBLE_LOGS_FOLDER}"/* -type l); do + is_psql_restart_needed=false + # Cannot use -L option in find here as links are actually find's target: + for logFile in $(find "${BUBBLE_LOGS_FOLDER}"/* -type l ! -name postgresql); do + log "recreating real bubble log file: ${logFile}" rm "${logFile}" touch "${logFile}" + if [[ "${logFile}" == "${LOG}" ]]; then + log "...starting fresh log after activation..." + fi is_reload_needed=true done + for psqlLogFile in $(find "${POSTGRES_LOGS_FOLDER}"/* -type l); do + log "removing postgres link log file making room for a real one: ${logFile}" + rm "${psqlLogFile}" + is_psql_restart_needed=true + done + + if [[ ${is_psql_restart_needed} == true ]]; then + log "restarting postgres service" + service postgresql restart + fi if [[ ${is_reload_needed} == true ]]; then + log "reloading supervisor" supervisorctl reload fi else - for logFile in $(find "${BUBBLE_LOGS_FOLDER}"/* -type f); do + # following dir link with -L option, so no need for special postgres for loop in this case: + for logFile in $(find -L "${BUBBLE_LOGS_FOLDER}"/* -type f); do + log "force-creating link to /dev/null instead of log file ${logFile}" ln -sf /dev/null "${logFile}" done fi + +log "ending log manager" diff --git a/bubble-server/src/main/resources/packer/roles/bubble/tasks/main.yml b/bubble-server/src/main/resources/packer/roles/bubble/tasks/main.yml index 2a8235bb..e870a4dc 100644 --- a/bubble-server/src/main/resources/packer/roles/bubble/tasks/main.yml +++ b/bubble-server/src/main/resources/packer/roles/bubble/tasks/main.yml @@ -120,7 +120,7 @@ name: "Log flag check and manager" minute: "*/5" user: "root" - job: "log_manager.sh" + job: "bash -c \"/usr/local/sbin/log_manager.sh >>/var/log/bubble/log_manager.log 2>&1\"" - name: Install packer for sage node shell: su - bubble bash -c install_packer.sh diff --git a/bubble-server/src/main/resources/packer/roles/bubble/tasks/postgresql.yml b/bubble-server/src/main/resources/packer/roles/bubble/tasks/postgresql.yml index 19e33b4d..d2b8e486 100644 --- a/bubble-server/src/main/resources/packer/roles/bubble/tasks/postgresql.yml +++ b/bubble-server/src/main/resources/packer/roles/bubble/tasks/postgresql.yml @@ -36,3 +36,11 @@ special_time: "hourly" user: "postgres" job: "HOUR_AGO=$(date -d '1 month ago' +\"%s000\") && psql -d bubble -c \"DELETE FROM sent_notification WHERE mtime < ${HOUR_AGO}\" -c \"DELETE FROM received_notification WHERE mtime < ${HOUR_AGO}\"" + +- name: Link to postgres log dir from bubble's log dir + file: + src: /var/log/postgresql + dest: /var/log/bubble/postgresql + owner: root + group: postgres + state: link diff --git a/bubble-web b/bubble-web index 36279fd8..6b04363c 160000 --- a/bubble-web +++ b/bubble-web @@ -1 +1 @@ -Subproject commit 36279fd83f9653c93dceac4ec7029eb416271c10 +Subproject commit 6b04363c9c0f5b3df22585258e67e2a5436e5f98