@@ -17,9 +17,4 @@ public class SessionDAO extends AbstractSessionDAO<Account> { | |||||
@Override protected boolean canStartSession(Account account) { return !account.suspended(); } | @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); | |||||
} | |||||
} | } |
@@ -470,6 +470,8 @@ public class AccountDAO extends AbstractCRUDDAO<Account> implements SqlViewSearc | |||||
private final Refreshable<Account> firstAdmin = new Refreshable<>("firstAdmin", FIRST_ADMIN_CACHE_MILLIS, this::findFirstAdmin); | private final Refreshable<Account> firstAdmin = new Refreshable<>("firstAdmin", FIRST_ADMIN_CACHE_MILLIS, this::findFirstAdmin); | ||||
public Account getFirstAdmin() { return firstAdmin.get(); } | public Account getFirstAdmin() { return firstAdmin.get(); } | ||||
public boolean isFirstAdmin(Account account) { return getFirstAdmin().getUuid().equals(account.getUuid()); } | |||||
public Account findFirstAdmin() { | public Account findFirstAdmin() { | ||||
final List<Account> admins = findByField("admin", true); | final List<Account> admins = findByField("admin", true); | ||||
if (admins.isEmpty()) return null; | if (admins.isEmpty()) return null; | ||||
@@ -113,11 +113,13 @@ public class AuthResource { | |||||
return accountDAO.update(account.setLastLogin()); | 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) | @GET @Path(EP_CONFIGS) | ||||
@@ -175,7 +177,7 @@ public class AuthResource { | |||||
final Account account = accountDAO.create(new Account(request).setRemoteHost(getRemoteHost(req))); | final Account account = accountDAO.create(new Account(request).setRemoteHost(getRemoteHost(req))); | ||||
activationService.bootstrapThisNode(account, request); | activationService.bootstrapThisNode(account, request); | ||||
return ok(account.setToken(newLoginSession(account))); | |||||
return ok(newLoginSession(account)); | |||||
} | } | ||||
@Autowired private NotificationService notificationService; | @Autowired private NotificationService notificationService; | ||||
@@ -344,10 +346,9 @@ public class AuthResource { | |||||
} | } | ||||
} | } | ||||
account.getAccountInitializer().setCanSendAccountMessages(); | account.getAccountInitializer().setCanSendAccountMessages(); | ||||
return ok(account | |||||
return ok(newLoginSession(account | |||||
.waitForAccountInit() | .waitForAccountInit() | ||||
.setPromoError(promoEx == null ? null : promoEx.getMessageTemplate()) | |||||
.setToken(newLoginSession(account))); | |||||
.setPromoError(promoEx == null ? null : promoEx.getMessageTemplate()))); | |||||
} | } | ||||
@POST @Path(EP_LOGIN) | @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}") | @POST @Path(EP_APP_LOGIN+"/{session}") | ||||
@@ -610,7 +610,7 @@ public class AuthResource { | |||||
if (approval.getMessageType() == AccountMessageType.confirmation) { | if (approval.getMessageType() == AccountMessageType.confirmation) { | ||||
if (account == null) return invalid("err.approvalToken.invalid"); | if (account == null) return invalid("err.approvalToken.invalid"); | ||||
if (approval.getAction() == AccountAction.login || approval.getAction() == AccountAction.password) { | if (approval.getAction() == AccountAction.login || approval.getAction() == AccountAction.password) { | ||||
return ok(account.setToken(newLoginSession(account))); | |||||
return ok(newLoginSession(account)); | |||||
} else { | } else { | ||||
return ok_empty(); | return ok_empty(); | ||||
} | } | ||||
@@ -84,7 +84,7 @@ public class TrustedAuthResource { | |||||
final TrustedClient trusted = findTrustedClient(account, request); | final TrustedClient trusted = findTrustedClient(account, request); | ||||
log.info("loginTrustedClient: logging in trusted: "+account.getName()); | 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}") | @DELETE @Path(EP_DELETE+"/{device}") | ||||
@@ -1 +1 @@ | |||||
Subproject commit 85fdd6f72a2434ecfe75883ae14cd0ea000bbf22 | |||||
Subproject commit 3b532dc0f4956aeff74d0b178f2cf4a43fea29ef |
@@ -13,7 +13,7 @@ function die { | |||||
} | } | ||||
function log { | function log { | ||||
echo "${1}" >> ${LOG} | |||||
echo "$(date): ${1}" >> ${LOG} | |||||
} | } | ||||
export LANG="en_US.UTF-8" | export LANG="en_US.UTF-8" | ||||
@@ -2,23 +2,52 @@ | |||||
# | # | ||||
# Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ | # 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 | 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_KEY="bubble.StandardSelfNodeService.bubble_server_logs_enabled" | ||||
REDIS_LOG_FLAG_VALUE=$(echo "get ${REDIS_LOG_FLAG_KEY}" | redis-cli | xargs echo | tr '[:upper:]' '[:lower:]') | 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 | if [[ ${REDIS_LOG_FLAG_VALUE} == true ]]; then | ||||
is_reload_needed=false | 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}" | rm "${logFile}" | ||||
touch "${logFile}" | touch "${logFile}" | ||||
if [[ "${logFile}" == "${LOG}" ]]; then | |||||
log "...starting fresh log after activation..." | |||||
fi | |||||
is_reload_needed=true | is_reload_needed=true | ||||
done | 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 | if [[ ${is_reload_needed} == true ]]; then | ||||
log "reloading supervisor" | |||||
supervisorctl reload | supervisorctl reload | ||||
fi | fi | ||||
else | 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}" | ln -sf /dev/null "${logFile}" | ||||
done | done | ||||
fi | fi | ||||
log "ending log manager" |
@@ -120,7 +120,7 @@ | |||||
name: "Log flag check and manager" | name: "Log flag check and manager" | ||||
minute: "*/5" | minute: "*/5" | ||||
user: "root" | 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 | - name: Install packer for sage node | ||||
shell: su - bubble bash -c install_packer.sh | shell: su - bubble bash -c install_packer.sh | ||||
@@ -36,3 +36,11 @@ | |||||
special_time: "hourly" | special_time: "hourly" | ||||
user: "postgres" | 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}\"" | 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 |
@@ -1 +1 @@ | |||||
Subproject commit 36279fd83f9653c93dceac4ec7029eb416271c10 | |||||
Subproject commit 6b04363c9c0f5b3df22585258e67e2a5436e5f98 |