1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-17 15:53:28 +00:00

show last access time on admin users page (#4795)

Co-authored-by: lian <lian@seafile.com>
This commit is contained in:
lian
2021-01-22 10:41:58 +08:00
committed by GitHub
parent 7994fafd90
commit cbf12f9ed9
4 changed files with 108 additions and 20 deletions

View File

@@ -6,6 +6,7 @@ class SysAdminAdminUser {
this.contact_email = object.contact_email; this.contact_email = object.contact_email;
this.login_id = object.login_id; this.login_id = object.login_id;
this.last_login = object.last_login; this.last_login = object.last_login;
this.last_access_time = object.last_access_time;
this.create_time = object.create_time; this.create_time = object.create_time;
this.is_active = object.is_active; this.is_active = object.is_active;
this.is_staff = object.is_staff; this.is_staff = object.is_staff;

View File

@@ -5,6 +5,7 @@ class SysAdminUser {
this.contact_email = object.contact_email; this.contact_email = object.contact_email;
this.login_id = object.login_id; this.login_id = object.login_id;
this.last_login = object.last_login; this.last_login = object.last_login;
this.last_access_time = object.last_access_time;
this.create_time = object.create_time; this.create_time = object.create_time;
this.is_active = object.is_active; this.is_active = object.is_active;
this.is_staff = object.is_staff; this.is_staff = object.is_staff;

View File

@@ -83,7 +83,7 @@ class Content extends Component {
const colSpaceText = <Fragment>{spaceEl}{` / ${gettext('Quota')}`}</Fragment>; const colSpaceText = <Fragment>{spaceEl}{` / ${gettext('Quota')}`}</Fragment>;
const colNameText = `${gettext('Name')} / ${gettext('Contact Email')}`; const colNameText = `${gettext('Name')} / ${gettext('Contact Email')}`;
const colCreatedText = `${gettext('Created At')} / ${gettext('Last Login')}`; const colCreatedText = `${gettext('Created At')} / ${gettext('Last Login')} / ${gettext('Last Access')}`;
if (isPro) { if (isPro) {
columns.push( columns.push(
{width: '20%', text: colNameText}, {width: '20%', text: colNameText},
@@ -422,6 +422,8 @@ class Item extends Component {
{`${item.create_time ? moment(item.create_time).format('YYYY-MM-DD HH:mm') : '--'} /`} {`${item.create_time ? moment(item.create_time).format('YYYY-MM-DD HH:mm') : '--'} /`}
<br /> <br />
{`${item.last_login ? moment(item.last_login).fromNow() : '--'}`} {`${item.last_login ? moment(item.last_login).fromNow() : '--'}`}
<br />
{`${item.last_access_time ? moment(item.last_access_time).fromNow() : '--'}`}
</td> </td>
<td> <td>
{(item.email != username && isOpIconShown) && {(item.email != username && isOpIconShown) &&

View File

@@ -19,6 +19,7 @@ from seaserv import seafile_api, ccnet_api
from seahub.api2.authentication import TokenAuthentication from seahub.api2.authentication import TokenAuthentication
from seahub.api2.throttling import UserRateThrottle from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error, to_python_boolean from seahub.api2.utils import api_error, to_python_boolean
from seahub.api2.models import TokenV2
import seahub.settings as settings import seahub.settings as settings
from seahub.settings import SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER, INIT_PASSWD, \ from seahub.settings import SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER, INIT_PASSWD, \
@@ -33,9 +34,12 @@ from seahub.profile.settings import CONTACT_CACHE_TIMEOUT, CONTACT_CACHE_PREFIX,
from seahub.utils import is_valid_username2, is_org_context, \ from seahub.utils import is_valid_username2, is_org_context, \
is_pro_version, normalize_cache_key, is_valid_email, \ is_pro_version, normalize_cache_key, is_valid_email, \
IS_EMAIL_CONFIGURED, send_html_email, get_site_name, \ IS_EMAIL_CONFIGURED, send_html_email, get_site_name, \
gen_shared_link, gen_shared_upload_link gen_shared_link, gen_shared_upload_link, \
get_file_audit_events, get_file_update_events
from seahub.utils.file_size import get_file_size_unit from seahub.utils.file_size import get_file_size_unit
from seahub.utils.timeutils import timestamp_to_isoformat_timestr, datetime_to_isoformat_timestr from seahub.utils.timeutils import timestamp_to_isoformat_timestr, \
datetime_to_isoformat_timestr, utc_to_local
from seahub.utils.user_permissions import get_user_role from seahub.utils.user_permissions import get_user_role
from seahub.utils.repo import normalize_repo_status_code from seahub.utils.repo import normalize_repo_status_code
from seahub.constants import DEFAULT_ADMIN from seahub.constants import DEFAULT_ADMIN
@@ -57,6 +61,43 @@ logger = logging.getLogger(__name__)
json_content_type = 'application/json; charset=utf-8' json_content_type = 'application/json; charset=utf-8'
def get_user_last_access_time(email, last_login_time):
device_last_access = ''
audit_last_access = ''
update_last_access = ''
devices = TokenV2.objects.filter(user=email).order_by('-last_accessed')
if devices:
device_last_access = devices[0].last_accessed
audit_events = get_file_audit_events(email, 0, None, 0, 1) or []
if audit_events:
audit_last_access = audit_events[0].timestamp
update_events = get_file_update_events(email, 0, None, 0, 1) or []
if update_events:
update_last_access = update_events[0].timestamp
last_access_time_list = []
if last_login_time:
last_access_time_list.append(last_login_time)
if device_last_access:
last_access_time_list.append(device_last_access)
if audit_last_access:
last_access_time_list.append(utc_to_local(audit_last_access))
if update_last_access:
last_access_time_list.append(utc_to_local(update_last_access))
if not last_access_time_list:
return ''
else:
return datetime_to_isoformat_timestr(sorted(last_access_time_list)[-1])
def get_user_upload_link_info(uls): def get_user_upload_link_info(uls):
data = {} data = {}
@@ -204,6 +245,7 @@ def update_user_info(request, user, password, is_active, is_staff, role,
logger.error(e) logger.error(e)
seafile_api.set_user_quota(email, -1) seafile_api.set_user_quota(email, -1)
def get_user_info(email): def get_user_info(email):
user = User.objects.get(email=email) user = User.objects.get(email=email)
@@ -297,8 +339,15 @@ class AdminAdminUsers(APIView):
user_info['quota_total'] = -1 user_info['quota_total'] = -1
user_info['create_time'] = timestamp_to_isoformat_timestr(user.ctime) user_info['create_time'] = timestamp_to_isoformat_timestr(user.ctime)
last_login_obj = UserLastLogin.objects.get_by_username(user.email) last_login_obj = UserLastLogin.objects.get_by_username(user.email)
user_info['last_login'] = datetime_to_isoformat_timestr(last_login_obj.last_login) if last_login_obj else '' if last_login_obj:
user_info['last_login'] = datetime_to_isoformat_timestr(last_login_obj.last_login)
user_info['last_access_time'] = get_user_last_access_time(user.email,
last_login_obj.last_login)
else:
user_info['last_login'] = ''
user_info['last_access_time'] = get_user_last_access_time(user.email, '')
try: try:
admin_role = AdminRole.objects.get_admin_role(user.email) admin_role = AdminRole.objects.get_admin_role(user.email)
@@ -312,6 +361,7 @@ class AdminAdminUsers(APIView):
} }
return Response(result) return Response(result)
class AdminUsers(APIView): class AdminUsers(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication) authentication_classes = (TokenAuthentication, SessionAuthentication)
@@ -363,7 +413,13 @@ class AdminUsers(APIView):
info['quota_total'] = seafile_api.get_user_quota(user.email) info['quota_total'] = seafile_api.get_user_quota(user.email)
last_login_obj = UserLastLogin.objects.get_by_username(user.email) last_login_obj = UserLastLogin.objects.get_by_username(user.email)
info['last_login'] = datetime_to_isoformat_timestr(last_login_obj.last_login) if last_login_obj else '' if last_login_obj:
info['last_login'] = datetime_to_isoformat_timestr(last_login_obj.last_login)
info['last_access_time'] = get_user_last_access_time(user.email,
last_login_obj.last_login)
else:
info['last_login'] = ''
info['last_access_time'] = get_user_last_access_time(user.email, '')
info['role'] = get_user_role(user) info['role'] = get_user_role(user)
@@ -423,8 +479,10 @@ class AdminUsers(APIView):
return api_error(status.HTTP_400_BAD_REQUEST, error_msg) return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
try: try:
data = self.get_info_of_users_order_by_quota_usage(source, direction, data = self.get_info_of_users_order_by_quota_usage(source,
page, per_page) direction,
page,
per_page)
except Exception as e: except Exception as e:
logger.error(e) logger.error(e)
error_msg = 'Internal Server Error' error_msg = 'Internal Server Error'
@@ -448,8 +506,10 @@ class AdminUsers(APIView):
return api_error(status.HTTP_400_BAD_REQUEST, error_msg) return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
try: try:
data = self.get_info_of_users_order_by_quota_usage(source, direction, data = self.get_info_of_users_order_by_quota_usage(source,
page, per_page) direction,
page,
per_page)
except Exception as e: except Exception as e:
logger.error(e) logger.error(e)
error_msg = 'Internal Server Error' error_msg = 'Internal Server Error'
@@ -489,10 +549,19 @@ class AdminUsers(APIView):
info['quota_usage'] = -1 info['quota_usage'] = -1
info['quota_total'] = -1 info['quota_total'] = -1
info['create_time'] = timestamp_to_isoformat_timestr(user.ctime)
last_login_obj = UserLastLogin.objects.get_by_username(user.email)
info['last_login'] = datetime_to_isoformat_timestr(last_login_obj.last_login) if last_login_obj else ''
info['role'] = get_user_role(user) info['role'] = get_user_role(user)
info['create_time'] = timestamp_to_isoformat_timestr(user.ctime)
last_login_obj = UserLastLogin.objects.get_by_username(user.email)
if last_login_obj:
info['last_login'] = datetime_to_isoformat_timestr(last_login_obj.last_login)
info['last_access_time'] = get_user_last_access_time(user.email,
last_login_obj.last_login)
else:
info['last_login'] = ''
info['last_access_time'] = get_user_last_access_time(user.email, '')
if getattr(settings, 'MULTI_INSTITUTION', False): if getattr(settings, 'MULTI_INSTITUTION', False):
info['institution'] = profile.institution if profile else '' info['institution'] = profile.institution if profile else ''
@@ -569,8 +638,7 @@ class AdminUsers(APIView):
if is_org_context(request): if is_org_context(request):
org_id = request.user.org.org_id org_id = request.user.org.org_id
org_quota_mb = seafile_api.get_org_quota(org_id) / \ org_quota_mb = seafile_api.get_org_quota(org_id) / get_file_size_unit('MB')
get_file_size_unit('MB')
if quota_total_mb > org_quota_mb: if quota_total_mb > org_quota_mb:
error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb
@@ -611,6 +679,7 @@ class AdminUsers(APIView):
c, c,
None, None,
[email2contact_email(email)]) [email2contact_email(email)])
add_user_tip = _('Successfully added user %(user)s. An email notification has been sent.') % {'user': email} add_user_tip = _('Successfully added user %(user)s. An email notification has been sent.') % {'user': email}
except Exception as e: except Exception as e:
logger.error(str(e)) logger.error(str(e))
@@ -669,8 +738,16 @@ class AdminLDAPUsers(APIView):
info['quota_total'] = seafile_api.get_user_quota(user.email) info['quota_total'] = seafile_api.get_user_quota(user.email)
info['quota_usage'] = seafile_api.get_user_self_usage(user.email) info['quota_usage'] = seafile_api.get_user_self_usage(user.email)
info['create_time'] = timestamp_to_isoformat_timestr(user.ctime) info['create_time'] = timestamp_to_isoformat_timestr(user.ctime)
last_login_obj = UserLastLogin.objects.get_by_username(user.email) last_login_obj = UserLastLogin.objects.get_by_username(user.email)
info['last_login'] = datetime_to_isoformat_timestr(last_login_obj.last_login) if last_login_obj else '' if last_login_obj:
info['last_login'] = datetime_to_isoformat_timestr(last_login_obj.last_login)
info['last_access_time'] = get_user_last_access_time(user.email,
last_login_obj.last_login)
else:
info['last_login'] = ''
info['last_access_time'] = get_user_last_access_time(user.email, '')
data.append(info) data.append(info)
result = {'ldap_user_list': data, 'has_next_page': has_next_page} result = {'ldap_user_list': data, 'has_next_page': has_next_page}
@@ -763,8 +840,16 @@ class AdminSearchUser(APIView):
info['quota_total'] = seafile_api.get_user_quota(user.email) info['quota_total'] = seafile_api.get_user_quota(user.email)
info['create_time'] = timestamp_to_isoformat_timestr(user.ctime) info['create_time'] = timestamp_to_isoformat_timestr(user.ctime)
last_login_obj = UserLastLogin.objects.get_by_username(user.email) last_login_obj = UserLastLogin.objects.get_by_username(user.email)
info['last_login'] = datetime_to_isoformat_timestr(last_login_obj.last_login) if last_login_obj else '' if last_login_obj:
info['last_login'] = datetime_to_isoformat_timestr(last_login_obj.last_login)
info['last_access_time'] = get_user_last_access_time(user.email,
last_login_obj.last_login)
else:
info['last_login'] = ''
info['last_access_time'] = get_user_last_access_time(user.email, '')
info['role'] = get_user_role(user) info['role'] = get_user_role(user)
if getattr(settings, 'MULTI_INSTITUTION', False): if getattr(settings, 'MULTI_INSTITUTION', False):
@@ -885,8 +970,7 @@ class AdminUser(APIView):
if is_org_context(request): if is_org_context(request):
org_id = request.user.org.org_id org_id = request.user.org.org_id
org_quota_mb = seafile_api.get_org_quota(org_id) / \ org_quota_mb = seafile_api.get_org_quota(org_id) / get_file_size_unit('MB')
get_file_size_unit('MB')
if quota_total_mb > org_quota_mb: if quota_total_mb > org_quota_mb:
error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb