You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
jumpserver/apps/users/tasks.py

159 lines
5.3 KiB

# -*- coding: utf-8 -*-
#
import uuid
from datetime import timedelta
8 years ago
from celery import shared_task, current_task
from django.conf import settings
from django.db.models import Q
from django.utils import timezone
from django.utils.translation import gettext_lazy as _, gettext_noop
from audits.const import ActivityChoices
from common.const.crontab import CRONTAB_AT_AM_TEN, CRONTAB_AT_PM_TWO
from common.utils import get_logger
from ops.celery.decorator import after_app_ready_start, register_as_period_task
from ops.celery.utils import create_or_update_celery_periodic_tasks
from orgs.utils import tmp_to_root_org
from users.notifications import PasswordExpirationReminderMsg
from users.notifications import UserExpirationReminderMsg
from .models import User
logger = get_logger(__file__)
8 years ago
@shared_task(
verbose_name=_('Check password expired'),
description=_(
"""Check every day at 10 AM whether the passwords of users in the system are expired,
and send a notification 5 days in advance"""
)
)
def check_password_expired():
fix: fix rbac to dev (#7636) * feat: 添加 RBAC 应用模块 * feat: 添加 RBAC Model、API * feat: 添加 RBAC Model、API 2 * feat: 添加 RBAC Model、API 3 * feat: 添加 RBAC Model、API 4 * feat: RBAC * feat: RBAC * feat: RBAC * feat: RBAC * feat: RBAC * feat: RBAC 整理权限位 * feat: RBAC 整理权限位2 * feat: RBAC 整理权限位2 * feat: RBAC 整理权限位 * feat: RBAC 添加默认角色 * feat: RBAC 添加迁移文件;迁移用户角色->用户角色绑定 * feat: RBAC 添加迁移文件;迁移用户角色->用户角色绑定 * feat: RBAC 修改用户模块API * feat: RBAC 添加组织模块迁移文件 & 修改组织模块API * feat: RBAC 添加组织模块迁移文件 & 修改组织模块API * feat: RBAC 修改用户角色属性的使用 * feat: RBAC No.1 * xxx * perf: 暂存 * perf: ... * perf(rbac): 添加 perms 到 profile serializer 中 * stash * perf: 使用init * perf: 修改migrations * perf: rbac * stash * stash * pref: 修改rbac * stash it * stash: 先去修复其他bug * perf: 修改 role 添加 users * pref: 修改 RBAC Model * feat: 添加权限的 tree api * stash: 暂存一下 * stash: 暂存一下 * perf: 修改 model verbose name * feat: 添加model各种 verbose name * perf: 生成 migrations * perf: 优化权限位 * perf: 添加迁移脚本 * feat: 添加组织角色迁移 * perf: 添加迁移脚本 * stash * perf: 添加migrateion * perf: 暂存一下 * perf: 修改rbac * perf: stash it * fix: 迁移冲突 * fix: 迁移冲突 * perf: 暂存一下 * perf: 修改 rbac 逻辑 * stash: 暂存一下 * perf: 修改内置角色 * perf: 解决 root 组织的问题 * perf: stash it * perf: 优化 rbac * perf: 优化 rolebinding 处理 * perf: 完成用户离开组织的问题 * perf: 暂存一下 * perf: 修改翻译 * perf: 去掉了 IsSuperUser * perf: IsAppUser 去掉完成 * perf: 修改 connection token 的权限 * perf: 去掉导入的问题 * perf: perms define 格式,修改 app 用户 的全新啊 * perf: 修改 permission * perf: 去掉一些 org admin * perf: 去掉部分 org admin * perf: 再去掉点 org admin role * perf: 再去掉部分 org admin * perf: user 角色搜索 * perf: 去掉很多 js * perf: 添加权限位 * perf: 修改权限 * perf: 去掉一个 todo * merge: with dev * fix: 修复冲突 Co-authored-by: Bai <bugatti_it@163.com> Co-authored-by: Michael Bai <baijiangjie@gmail.com> Co-authored-by: ibuler <ibuler@qq.com>
3 years ago
users = User.get_nature_users().filter(source=User.Source.local)
for user in users:
if not user.is_valid:
continue
if not user.password_will_expired:
continue
msg = "The user {} password expires in {} days"
logger.info(msg.format(user, user.password_expired_remain_days))
PasswordExpirationReminderMsg(user).publish_async()
@shared_task(
verbose_name=_('Periodic check password expired'),
description=_(
"""With version iterations, new tasks may be added, or task names and execution times may
be modified. Therefore, upon system startup, it is necessary to register or update the
parameters of the task that checks if passwords have expired"""
)
)
@after_app_ready_start
def check_password_expired_periodic():
tasks = {
'check_password_expired_periodic': {
'task': check_password_expired.name,
'interval': None,
'crontab': CRONTAB_AT_AM_TEN,
'enabled': True,
}
}
create_or_update_celery_periodic_tasks(tasks)
@shared_task(
verbose_name=_('Check user expired'),
description=_(
"""Check every day at 2 p.m whether the users in the system are expired, and send a
notification 5 days in advance"""
)
)
def check_user_expired():
date_expired_lt = timezone.now() + timezone.timedelta(days=User.DATE_EXPIRED_WARNING_DAYS)
users = User.get_nature_users() \
.filter(source=User.Source.local) \
.filter(date_expired__lt=date_expired_lt)
for user in users:
if not user.is_valid:
continue
if not user.will_expired:
continue
msg = "The user {} will expires in {} days"
logger.info(msg.format(user, user.expired_remain_days))
UserExpirationReminderMsg(user).publish_async()
@shared_task(
verbose_name=_('Periodic check user expired'),
description=_(
"""With version iterations, new tasks may be added, or task names and execution times may
be modified. Therefore, upon system startup, it is necessary to register or update the
parameters of the task that checks if users have expired"""
)
)
@after_app_ready_start
def check_user_expired_periodic():
tasks = {
'check_user_expired_periodic': {
'task': check_user_expired.name,
'interval': None,
'crontab': CRONTAB_AT_PM_TWO,
'enabled': True,
}
}
create_or_update_celery_periodic_tasks(tasks)
@shared_task(
verbose_name=_('Check unused users'),
description=_(
"""At 2 p.m. every day, according to the configuration in "System Settings - Security -
Auth security - Auto disable threshold" users who have not logged in or whose API keys
have not been used for a long time will be disabled"""
)
)
@register_as_period_task(crontab=CRONTAB_AT_PM_TWO)
@tmp_to_root_org()
def check_unused_users():
uncommon_users_ttl = settings.SECURITY_UNCOMMON_USERS_TTL
if not uncommon_users_ttl:
return
uncommon_users_ttl = int(uncommon_users_ttl)
if uncommon_users_ttl <= 0 or uncommon_users_ttl >= 999:
return
seconds_to_subtract = uncommon_users_ttl * 24 * 60 * 60
t = timezone.now() - timedelta(seconds=seconds_to_subtract)
last_login_q = Q(last_login__lte=t) | (Q(last_login__isnull=True) & Q(date_joined__lte=t))
api_key_q = Q(date_api_key_last_used__lte=t) | (
Q(date_api_key_last_used__isnull=True) & Q(date_joined__lte=t))
users = User.objects \
.filter(date_joined__lt=t) \
.filter(is_active=True) \
.filter(last_login_q) \
.filter(api_key_q) \
.exclude(username='admin')
if not users:
return
print("Some users are not used for a long time, and they will be disabled.")
resource_ids = []
for user in users:
resource_ids.append(user.id)
print(' - {}'.format(user.name))
users.update(is_active=False)
from audits.signal_handlers import create_activities
if current_task:
task_id = current_task.request.id
else:
task_id = str(uuid.uuid4())
detail = gettext_noop('The user has not logged in recently and has been disabled.')
create_activities(resource_ids, detail, task_id, action=ActivityChoices.task, org_id='')