Skip to content

Commit

Permalink
show last access time on admin users page (haiwen#4795)
Browse files Browse the repository at this point in the history
Co-authored-by: lian <lian@seafile.com>
  • Loading branch information
imwhatiam and lian authored Jan 22, 2021
1 parent 7994faf commit cbf12f9
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 19 deletions.
1 change: 1 addition & 0 deletions frontend/src/models/sysadmin-admin-user.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class SysAdminAdminUser {
this.contact_email = object.contact_email;
this.login_id = object.login_id;
this.last_login = object.last_login;
this.last_access_time = object.last_access_time;
this.create_time = object.create_time;
this.is_active = object.is_active;
this.is_staff = object.is_staff;
Expand Down
1 change: 1 addition & 0 deletions frontend/src/models/sysadmin-user.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class SysAdminUser {
this.contact_email = object.contact_email;
this.login_id = object.login_id;
this.last_login = object.last_login;
this.last_access_time = object.last_access_time;
this.create_time = object.create_time;
this.is_active = object.is_active;
this.is_staff = object.is_staff;
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/pages/sys-admin/users/users-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class Content extends Component {
const colSpaceText = <Fragment>{spaceEl}{` / ${gettext('Quota')}`}</Fragment>;

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) {
columns.push(
{width: '20%', text: colNameText},
Expand Down Expand Up @@ -422,6 +422,8 @@ class Item extends Component {
{`${item.create_time ? moment(item.create_time).format('YYYY-MM-DD HH:mm') : '--'} /`}
<br />
{`${item.last_login ? moment(item.last_login).fromNow() : '--'}`}
<br />
{`${item.last_access_time ? moment(item.last_access_time).fromNow() : '--'}`}
</td>
<td>
{(item.email != username && isOpIconShown) &&
Expand Down
120 changes: 102 additions & 18 deletions seahub/api2/endpoints/admin/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from seahub.api2.authentication import TokenAuthentication
from seahub.api2.throttling import UserRateThrottle
from seahub.api2.utils import api_error, to_python_boolean
from seahub.api2.models import TokenV2

import seahub.settings as settings
from seahub.settings import SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER, INIT_PASSWD, \
Expand All @@ -33,9 +34,12 @@
from seahub.utils import is_valid_username2, is_org_context, \
is_pro_version, normalize_cache_key, is_valid_email, \
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.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.repo import normalize_repo_status_code
from seahub.constants import DEFAULT_ADMIN
Expand All @@ -57,6 +61,43 @@
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):
data = {}

Expand Down Expand Up @@ -204,6 +245,7 @@ def update_user_info(request, user, password, is_active, is_staff, role,
logger.error(e)
seafile_api.set_user_quota(email, -1)


def get_user_info(email):

user = User.objects.get(email=email)
Expand Down Expand Up @@ -297,8 +339,15 @@ def get(self, request):
user_info['quota_total'] = -1

user_info['create_time'] = timestamp_to_isoformat_timestr(user.ctime)

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:
admin_role = AdminRole.objects.get_admin_role(user.email)
Expand All @@ -312,6 +361,7 @@ def get(self, request):
}
return Response(result)


class AdminUsers(APIView):

authentication_classes = (TokenAuthentication, SessionAuthentication)
Expand Down Expand Up @@ -363,7 +413,13 @@ def get_info_of_users_order_by_quota_usage(self, source, direction,
info['quota_total'] = seafile_api.get_user_quota(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)

Expand Down Expand Up @@ -423,8 +479,10 @@ def get(self, request):
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

try:
data = self.get_info_of_users_order_by_quota_usage(source, direction,
page, per_page)
data = self.get_info_of_users_order_by_quota_usage(source,
direction,
page,
per_page)
except Exception as e:
logger.error(e)
error_msg = 'Internal Server Error'
Expand All @@ -448,8 +506,10 @@ def get(self, request):
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)

try:
data = self.get_info_of_users_order_by_quota_usage(source, direction,
page, per_page)
data = self.get_info_of_users_order_by_quota_usage(source,
direction,
page,
per_page)
except Exception as e:
logger.error(e)
error_msg = 'Internal Server Error'
Expand Down Expand Up @@ -489,10 +549,19 @@ def get(self, request):
info['quota_usage'] = -1
info['quota_total'] = -1

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)
info['last_login'] = datetime_to_isoformat_timestr(last_login_obj.last_login) if last_login_obj else ''
info['role'] = get_user_role(user)
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):
info['institution'] = profile.institution if profile else ''

Expand Down Expand Up @@ -569,8 +638,7 @@ def post(self, request):

if is_org_context(request):
org_id = request.user.org.org_id
org_quota_mb = seafile_api.get_org_quota(org_id) / \
get_file_size_unit('MB')
org_quota_mb = seafile_api.get_org_quota(org_id) / get_file_size_unit('MB')

if quota_total_mb > org_quota_mb:
error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb
Expand Down Expand Up @@ -611,6 +679,7 @@ def post(self, request):
c,
None,
[email2contact_email(email)])

add_user_tip = _('Successfully added user %(user)s. An email notification has been sent.') % {'user': email}
except Exception as e:
logger.error(str(e))
Expand Down Expand Up @@ -669,8 +738,16 @@ def get(self, request):
info['quota_total'] = seafile_api.get_user_quota(user.email)
info['quota_usage'] = seafile_api.get_user_self_usage(user.email)
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 ''
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)

result = {'ldap_user_list': data, 'has_next_page': has_next_page}
Expand Down Expand Up @@ -763,8 +840,16 @@ def get(self, request):
info['quota_total'] = seafile_api.get_user_quota(user.email)

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 ''
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)

if getattr(settings, 'MULTI_INSTITUTION', False):
Expand Down Expand Up @@ -885,8 +970,7 @@ def put(self, request, email):

if is_org_context(request):
org_id = request.user.org.org_id
org_quota_mb = seafile_api.get_org_quota(org_id) / \
get_file_size_unit('MB')
org_quota_mb = seafile_api.get_org_quota(org_id) / get_file_size_unit('MB')

if quota_total_mb > org_quota_mb:
error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb
Expand Down Expand Up @@ -1016,7 +1100,7 @@ def put(self, request, email):
contact_email = Profile.objects.get_contact_email_by_user(email)
try:
send_html_email(_(u'Password has been reset on %s') % get_site_name(),
'sysadmin/user_reset_email.html', c, None, [contact_email])
'sysadmin/user_reset_email.html', c, None, [contact_email])
reset_tip = _('Successfully reset password to %(passwd)s, an email has been sent to %(user)s.') % \
{'passwd': new_password, 'user': contact_email}
except Exception as e:
Expand Down Expand Up @@ -1200,7 +1284,7 @@ def get(self, request, email):
if email not in nickname_dict:
if '@seafile_group' in email:
group_id = get_group_id_by_repo_owner(email)
group_name= group_id_to_name(group_id)
group_name = group_id_to_name(group_id)
nickname_dict[email] = group_name
else:
nickname_dict[email] = email2nickname(email)
Expand Down

0 comments on commit cbf12f9

Please sign in to comment.