def save(self, domain_override=None, email_template_name='registration/password_reset_email.html', use_https=False, token_generator=default_token_generator): """ Generates a one-use only link for resetting password and sends to the user """ user = self.users_cache if not domain_override: site_name = get_site_name() else: site_name = domain_override send_to = user.username profile = Profile.objects.get_profile_by_user(user.username) if profile and profile.contact_email: send_to = profile.contact_email c = { 'email': send_to, 'uid': int_to_base36(user.id), 'user': user, 'token': token_generator.make_token(user), } send_html_email(_("Reset Password on %s") % site_name, email_template_name, c, None, [send_to])
def send_email(self, email): # save current language cur_language = translation.get_language() # get and active user language user_language = self.get_user_language(email) translation.activate(user_language) orgs = ccnet_api.get_orgs_by_user(email) if orgs: org_id = orgs[0].org_id quota_usage = seafile_api.get_org_user_quota_usage(org_id, email) quota_total = seafile_api.get_org_user_quota(org_id, email) else: quota_usage = seafile_api.get_user_self_usage(email) quota_total = seafile_api.get_user_quota(email) if IS_EMAIL_CONFIGURED and quota_total > 0 and quota_usage/quota_total > 0.9: data = {'email': email, 'quota_total': quota_total, 'quota_usage': quota_usage} contact_email = Profile.objects.get_contact_email_by_user(email) print('Send email to %s(%s)' % (contact_email, email)) send_html_email(_(u'Your quota is almost full on %s') % get_site_name(), 'user_quota_full.html', data, None, [contact_email]) # restore current language translation.activate(cur_language)
def save(self, domain_override=None, email_template_name='registration/password_reset_email.html', use_https=False, token_generator=default_token_generator): """ Generates a one-use only link for resetting password and sends to the user """ user = self.users_cache if not domain_override: current_site = Site.objects.get_current() site_name = current_site.name else: site_name = domain_override c = { 'email': user.username, 'uid': int_to_base36(user.id), 'user': user, 'token': token_generator.make_token(user), } send_html_email( _("Reset Password on %s") % site_name, email_template_name, c, None, [user.username])
def send_activation_email(self, site): """ Send an activation email to the user associated with this ``RegistrationProfile``. The activation email will make use of two templates: ``registration/activation_email_subject.txt`` This template will be used for the subject line of the email. Because it is used as the subject line of an email, this template's output **must** be only a single line of text; output longer than one line will be forcibly joined into only a single line. ``registration/activation_email.txt`` This template will be used for the body of the email. These templates will each receive the following context variables: ``activation_key`` The activation key for the new account. ``expiration_days`` The number of days remaining during which the account may be activated. ``site`` An object representing the site on which the user registered; depending on whether ``django.contrib.sites`` is installed, this may be an instance of either ``django.contrib.sites.models.Site`` (if the sites application is installed) or ``django.contrib.sites.models.RequestSite`` (if not). Consult the documentation for the Django sites framework for details regarding these objects' interfaces. """ ctx_dict = { 'activation_key': self.activation_key, 'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS, 'site': site, 'SITE_ROOT': settings.SITE_ROOT } subject = render_to_string('registration/activation_email_subject.txt', ctx_dict) # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) try: user = User.objects.get(id=self.emailuser_id) send_to = user.username profile = Profile.objects.get_profile_by_user(user.username) if profile and profile.contact_email: send_to = profile.contact_email send_html_email(subject, 'registration/activation_email.html', ctx_dict, None, [send_to]) except User.DoesNotExist: pass
def email_user_on_activation(user): """Send an email to user when admin activate his/her account. """ c = { 'username': user.email, } send_html_email(_('Your account on %s is activated') % get_site_name(), 'sysadmin/user_activation_email.html', c, None, [user.email])
def email_user_on_activation(user): """Send an email to user when admin activate his/her account. """ c = { 'username': user.email, } send_html_email(_(u'Your account on %s is activated') % SITE_NAME, 'sysadmin/user_activation_email.html', c, None, [user.email])
def send_shared_upload_link(request): """ Handle ajax post request to send shared upload link. """ if not request.method == 'POST': raise Http404 content_type = 'application/json; charset=utf-8' if not IS_EMAIL_CONFIGURED: data = json.dumps({'error':_(u'Sending shared upload link failed. Email service is not properly configured, please contact administrator.')}) return HttpResponse(data, status=500, content_type=content_type) from seahub.settings import SITE_NAME form = UploadLinkShareForm(request.POST) if form.is_valid(): email = form.cleaned_data['email'] shared_upload_link = form.cleaned_data['shared_upload_link'] extra_msg = escape(form.cleaned_data['extra_msg']) to_email_list = string2list(email) for to_email in to_email_list: # Add email to contacts. mail_sended.send(sender=None, user=request.user.username, email=to_email) c = { 'email': request.user.username, 'to_email': to_email, 'shared_upload_link': shared_upload_link, } if extra_msg: c['extra_msg'] = extra_msg if REPLACE_FROM_EMAIL: from_email = request.user.username else: from_email = None # use default from email if ADD_REPLY_TO_HEADER: reply_to = request.user.username else: reply_to = None try: send_html_email(_(u'An upload link is shared to you on %s') % SITE_NAME, 'shared_upload_link_email.html', c, from_email, [to_email], reply_to=reply_to) except Exception, e: logger.error(str(e)) data = json.dumps({'error':_(u'Internal server error. Send failed.')}) return HttpResponse(data, status=500, content_type=content_type) data = json.dumps({"msg": _(u'Successfully sent.')}) return HttpResponse(data, status=200, content_type=content_type)
def post(self, request, repo_id): """ Only used for reset encrypted repo's password, and then send new password to user's mainbox. Permission checking: 1. repo owner. """ if not ENABLE_RESET_ENCRYPTED_REPO_PASSWORD or \ not IS_EMAIL_CONFIGURED: error_msg = _('Feature disabled.') return api_error(status.HTTP_403_FORBIDDEN, error_msg) # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not repo.encrypted: error_msg = 'Library %s is not encrypted.' % repo_id return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # permission check username = request.user.username repo_owner = get_repo_owner(request, repo_id) if '@seafile_group' in repo_owner: group_id = email2nickname(repo_owner) if not ccnet_api.check_group_staff(int(group_id), username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: if username != repo_owner: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) secret_key = RepoSecretKey.objects.get_secret_key(repo_id) if not secret_key: error_msg = _("Can not reset this library's password.") return api_error(HTTP_520_OPERATION_FAILED, error_msg) new_password = get_random_string(10) try: seafile_api.reset_repo_passwd(repo_id, username, secret_key, new_password) content = {'repo_name': repo.name, 'password': new_password} send_html_email( _('New password of library %s') % repo.name, 'snippets/reset_repo_password.html', content, None, [email2contact_email(username)]) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({'success': True})
def send_group_member_add_mail(request, group, from_user, to_user): c = { 'email': from_user, 'to_email': to_user, 'group': group, } subject = _(u'You are invited to join a group on %s') % SITE_NAME send_html_email(subject, 'group/add_member_email.html', c, None, [to_user])
def send_failed_notice(repo_id, transaction_id, timestamp, user_email): BLOXBERG_MSG = [] msg = _( 'The certification has failed, please try again in a few minutes. In case it keeps failing, please contact the Keeper Support.' ) BLOXBERG_MSG.append(msg) UserNotification.objects._add_user_notification( user_email, MSG_TYPE_KEEPER_BLOXBERG_MSG, json.dumps({ 'message': ('; '.join(BLOXBERG_MSG)), 'repo_id': repo_id, 'author_name': email2nickname(user_email), })) c1 = { 'to_user': user_email, 'notice_count': 1, 'message_type': 'certify_snapshot_failed_msg', #message_type for email 'message': ('; '.join(BLOXBERG_MSG)), 'repo_id': repo_id, 'author_name': email2nickname(user_email), 'timestamp': timestamp, } try: send_html_email( _('New notice on %s') % get_site_name(), 'notifications/keeper_email.html', c1, None, [user_email]) logger.info('Successfully sent email to %s' % user_email) except Exception as e: logger.error('Failed to send email to %s, error detail: %s' % (user_email, e)) admin_email = '*****@*****.**' BLOXBERG_MSG.append(f'repo_id: {repo_id}') BLOXBERG_MSG.append(f'transaction_id: {transaction_id}') c2 = { 'to_user': admin_email, 'notice_count': 1, 'message_type': 'certify_snapshot_failed_msg', #message_type for email 'message': ('; '.join(BLOXBERG_MSG)), 'repo_id': repo_id, 'author_name': 'Keeper Admins', 'timestamp': timestamp, } try: send_html_email( _('New notice on %s') % get_site_name(), 'notifications/keeper_email.html', c2, None, [admin_email]) logger.info('Successfully sent email to %s' % admin_email) except Exception as e: logger.error('Failed to send email to %s, error detail: %s' % (admin_email, e))
def send_user_add_mail(request, email, password): """Send email when add new user.""" c = { 'user': request.user.username, 'org': request.user.org, 'email': email, 'password': password, } send_html_email(_('You are invited to join %s') % get_site_name(), 'sysadmin/user_add_email.html', c, None, [email])
def send_user_add_mail(request, email, password): """Send email when add new user.""" c = { 'user': request.user.username, 'org': request.user.org, 'email': email, 'password': password, } send_html_email(_(u'You are invited to join %s') % SITE_NAME, 'sysadmin/user_add_email.html', c, None, [email])
def put(self, request, email): """Reset password for user Permission checking: 1. only admin can perform this action. """ if not request.user.admin_permissions.can_manage_user(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') if not is_valid_username2(email): error_msg = 'email invalid' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: user = User.objects.get(email=email) except User.DoesNotExist as e: logger.error(e) error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if isinstance(INIT_PASSWD, FunctionType): new_password = INIT_PASSWD() else: new_password = INIT_PASSWD user.set_password(new_password) user.save() if config.FORCE_PASSWORD_CHANGE: UserOptions.objects.set_force_passwd_change(user.username) if IS_EMAIL_CONFIGURED: if SEND_EMAIL_ON_RESETTING_USER_PASSWD: c = {'email': email, 'password': new_password} 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]) 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: logger.warning(e) reset_tip = _('Successfully reset password to %(passwd)s, but failed to send email to %(user)s, please check your email configuration.') % \ {'passwd': new_password, 'user': email} else: reset_tip = _('Successfully reset password to %(passwd)s for user %(user)s.') % \ {'passwd': new_password, 'user': email} else: reset_tip = _('Successfully reset password to %(passwd)s for user %(user)s. But email notification can not be sent, because Email service is not properly configured.') % \ {'passwd': new_password, 'user': email} return Response({'new_password': new_password, 'reset_tip': reset_tip})
def send_shared_link(request): """ Handle ajax post request to send file shared link. """ if not request.method == 'POST': raise Http404 content_type = 'application/json; charset=utf-8' if not IS_EMAIL_CONFIGURED: data = json.dumps({'error':_(u'Sending shared link failed. Email service is not properly configured, please contact administrator.')}) return HttpResponse(data, status=500, content_type=content_type) from seahub.settings import SITE_NAME form = FileLinkShareForm(request.POST) if form.is_valid(): email = form.cleaned_data['email'] file_shared_link = form.cleaned_data['file_shared_link'] file_shared_name = form.cleaned_data['file_shared_name'] file_shared_type = form.cleaned_data['file_shared_type'] extra_msg = escape(form.cleaned_data['extra_msg']) to_email_list = string2list(email) for to_email in to_email_list: # Add email to contacts. mail_sended.send(sender=None, user=request.user.username, email=to_email) c = { 'email': request.user.username, 'to_email': to_email, 'file_shared_link': file_shared_link, 'file_shared_name': file_shared_name, } if extra_msg: c['extra_msg'] = extra_msg try: if file_shared_type == 'f': c['file_shared_type'] = "file" send_html_email(_(u'A file is shared to you on %s') % SITE_NAME, 'shared_link_email.html', c, None, [to_email]) else: c['file_shared_type'] = "directory" send_html_email(_(u'A directory is shared to you on %s') % SITE_NAME, 'shared_link_email.html', c, None, [to_email]) except Exception, e: logger.error(str(e)) data = json.dumps({'error':_(u'Internal server error. Send failed.')}) return HttpResponse(data, status=500, content_type=content_type) data = json.dumps({"msg": _(u'Successfully sent.')}) return HttpResponse(data, status=200, content_type=content_type)
def send_user_reset_email(request, email, password): """ Send email when reset user password. """ c = { 'email': email, 'password': password, } send_html_email(_('Password has been reset on %s') % get_site_name(), 'sysadmin/user_reset_email.html', c, None, [email])
def send_user_reset_email(request, email, password): """ Send email when reset user password. """ c = { 'email': email, 'password': password, } send_html_email(_(u'Password has been reset on %s') % SITE_NAME, 'sysadmin/user_reset_email.html', c, None, [email])
def send_activation_email(self, site): """ Send an activation email to the user associated with this ``RegistrationProfile``. The activation email will make use of two templates: ``registration/activation_email_subject.txt`` This template will be used for the subject line of the email. Because it is used as the subject line of an email, this template's output **must** be only a single line of text; output longer than one line will be forcibly joined into only a single line. ``registration/activation_email.txt`` This template will be used for the body of the email. These templates will each receive the following context variables: ``activation_key`` The activation key for the new account. ``expiration_days`` The number of days remaining during which the account may be activated. ``site`` An object representing the site on which the user registered; depending on whether ``django.contrib.sites`` is installed, this may be an instance of either ``django.contrib.sites.models.Site`` (if the sites application is installed) or ``django.contrib.sites.models.RequestSite`` (if not). Consult the documentation for the Django sites framework for details regarding these objects' interfaces. """ ctx_dict = { 'activation_key': self.activation_key, 'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS, 'site': site, 'SITE_ROOT': settings.SITE_ROOT } subject = render_to_string('registration/activation_email_subject.txt', ctx_dict) # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) try: user = User.objects.get(id=self.emailuser_id) send_html_email(subject, 'registration/activation_email.html', ctx_dict, None, [user.username]) except User.DoesNotExist: pass
def email_user_on_activation(user): """Send an email to user when admin activate his/her account. """ send_to = user.username profile = Profile.objects.get_profile_by_user(user.username) if profile and profile.contact_email: send_to = profile.contact_email c = { 'username': send_to, } send_html_email(_('Your account on %s is activated') % get_site_name(), 'sysadmin/user_activation_email.html', c, None, [send_to])
def send_shared_link(request): """ Handle ajax post request to send file shared link. """ if not request.is_ajax() and not request.method == 'POST': raise Http404 content_type = 'application/json; charset=utf-8' if not IS_EMAIL_CONFIGURED: data = json.dumps({ 'error': _(u'Sending shared link failed. Email service is not properly configured, please contact administrator.' ) }) return HttpResponse(data, status=500, content_type=content_type) from seahub.settings import SITE_NAME form = FileLinkShareForm(request.POST) if form.is_valid(): email = form.cleaned_data['email'] file_shared_link = form.cleaned_data['file_shared_link'] to_email_list = string2list(email) for to_email in to_email_list: # Add email to contacts. mail_sended.send(sender=None, user=request.user.username, email=to_email) c = { 'email': request.user.username, 'to_email': to_email, 'file_shared_link': file_shared_link, } try: send_html_email( _(u'A file is shared to you on %s') % SITE_NAME, 'shared_link_email.html', c, None, [to_email]) except Exception, e: logger.error(str(e)) data = json.dumps( {'error': _(u'Internal server error. Send failed.')}) return HttpResponse(data, status=500, content_type=content_type) data = json.dumps({"msg": _(u'Successfully sent.')}) return HttpResponse(data, status=200, content_type=content_type)
def send_final_notification(repo_id, path, transaction_id, timestamp, user_email, content_type): BLOXBERG_MSG = [] msg = _('Your data was successfully certified!') msg_transaction = 'Transaction ID: ' + transaction_id file_name = path.rsplit('/', 1)[-1] repo_name = get_repo(repo_id).repo_name BLOXBERG_MSG.append(msg) BLOXBERG_MSG.append(msg_transaction) UserNotification.objects._add_user_notification( user_email, MSG_TYPE_KEEPER_BLOXBERG_MSG, json.dumps({ 'message': ('; '.join(BLOXBERG_MSG)), 'content_type': content_type, 'transaction_id': transaction_id, 'repo_id': repo_id, 'repo_name': repo_name, 'link_to_file': path, 'file_name': file_name, 'author_name': email2nickname(user_email), })) c = { 'to_user': user_email, 'notice_count': 1, 'message_type': 'bloxberg_msg', 'content_type': content_type, 'message': ('; '.join(BLOXBERG_MSG)), 'transaction_id': transaction_id, 'repo_id': repo_id, 'repo_name': repo_name, 'link_to_file': path, 'file_name': file_name, 'author_name': email2nickname(user_email), 'timestamp': timestamp, } try: send_html_email( _('New notice on %s') % get_site_name(), 'notifications/keeper_email.html', c, None, [user_email]) logger.info('Successfully sent email to %s' % user_email) except Exception as e: logger.error('Failed to send email to %s, error detail: %s' % (user_email, e))
def post(self, request, repo_id): """ Only used for reset encrypted repo's password, and then send new password to user's mainbox. Permission checking: 1. repo owner. """ if not ENABLE_RESET_ENCRYPTED_REPO_PASSWORD or \ not IS_EMAIL_CONFIGURED: error_msg = _(u'Feature disabled.') return api_error(status.HTTP_403_FORBIDDEN, error_msg) # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not repo.encrypted: error_msg = 'Library %s is not encrypted.' % repo_id return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # permission check username = request.user.username if not is_repo_owner(request, repo_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) secret_key = RepoSecretKey.objects.get_secret_key(repo_id) if not secret_key: error_msg = _(u"Can not reset this library's password.") return api_error(HTTP_520_OPERATION_FAILED, error_msg) new_password = get_random_string(10) try: seafile_api.reset_repo_passwd(repo_id, username, secret_key, new_password) content = {'repo_name': repo.name, 'password': new_password,} send_html_email(_(u'New password of library %s') % repo.name, 'snippets/reset_repo_password.html', content, None, [email2contact_email(username)]) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({'success': True})
def do_action(self): now = datetime.datetime.now() try: cmd_last_check = CommandsLastCheck.objects.get( command_type=self.label) logger.debug('Last check time is %s' % cmd_last_check.last_check) unseen_notices = UserNotification.objects.get_all_notifications( seen=False, time_since=cmd_last_check.last_check) logger.debug('Update last check time to %s' % now) cmd_last_check.last_check = now cmd_last_check.save() except CommandsLastCheck.DoesNotExist: logger.debug('No last check time found, get all unread notices.') unseen_notices = UserNotification.objects.get_all_notifications( seen=False) logger.debug('Create new last check time: %s' % now) CommandsLastCheck(command_type=self.label, last_check=now).save() email_ctx = {} for notice in unseen_notices: if email_ctx.has_key(notice.to_user): email_ctx[notice.to_user] += 1 else: email_ctx[notice.to_user] = 1 for to_user, count in email_ctx.items(): subject = subjects[1] if count > 1 else subjects[0] c = { 'to_user': to_user, 'notice_count': count, } try: send_html_email(subject, 'notifications/notice_email.html', c, settings.DEFAULT_FROM_EMAIL, [to_user]) logger.info('Successfully sent email to %s' % to_user) except Exception, e: logger.error('Failed to send email to %s, error detail: %s' % (to_user, e))
def send_user_add_mail(request, email, password): """Send email when add new user.""" c = { 'user': request.user.username, 'org': request.user.org, 'email': email, 'password': password, } # KEEPER try: from keeper.utils import get_user_name c['user'] = get_user_name(c['user']) except Exception as e: logger.error(str(e)) send_html_email( _('You are invited to join %s') % get_site_name(), 'sysadmin/user_add_email.html', c, None, [email])
def do_action(self): now = datetime.datetime.now() try: cmd_last_check = CommandsLastCheck.objects.get(command_type=self.label) logger.debug('Last check time is %s' % cmd_last_check.last_check) unseen_notices = UserNotification.objects.get_all_notifications( seen=False, time_since=cmd_last_check.last_check) logger.debug('Update last check time to %s' % now) cmd_last_check.last_check = now cmd_last_check.save() except CommandsLastCheck.DoesNotExist: logger.debug('No last check time found, get all unread notices.') unseen_notices = UserNotification.objects.get_all_notifications( seen=False) logger.debug('Create new last check time: %s' % now) CommandsLastCheck(command_type=self.label, last_check=now).save() email_ctx = {} for notice in unseen_notices: if email_ctx.has_key(notice.to_user): email_ctx[notice.to_user] += 1 else: email_ctx[notice.to_user] = 1 for to_user, count in email_ctx.items(): subject = subjects[1] if count > 1 else subjects[0] c = { 'to_user': to_user, 'notice_count': count, } try: send_html_email(subject, 'notifications/notice_email.html', c, settings.DEFAULT_FROM_EMAIL, [to_user]) logger.info('Successfully sent email to %s' % to_user) except Exception, e: logger.error('Failed to send email to %s, error detail: %s' % (to_user, e))
def save(self, domain_override=None, email_template_name='registration/password_reset_email.html', use_https=False, token_generator=default_token_generator): """ Generates a one-use only link for resetting password and sends to the user """ user = self.users_cache if not domain_override: site_name = get_site_name() else: site_name = domain_override c = { 'email': user.username, 'uid': int_to_base36(user.id), 'user': user, 'token': token_generator.make_token(user), } send_html_email(_("Reset Password on %s") % site_name, email_template_name, c, None, [user.username])
def put(self, request, email): """Reset password for user Permission checking: 1. only admin can perform this action. """ if not is_valid_username(email): error_msg = 'email invalid' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: user = User.objects.get(email=email) except User.DoesNotExist as e: logger.error(e) error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if isinstance(INIT_PASSWD, FunctionType): new_password = INIT_PASSWD() else: new_password = INIT_PASSWD user.set_password(new_password) user.save() if config.FORCE_PASSWORD_CHANGE: UserOptions.objects.set_force_passwd_change(user.username) if IS_EMAIL_CONFIGURED and SEND_EMAIL_ON_RESETTING_USER_PASSWD: c = {'email': email, 'password': new_password} try: send_html_email(_(u'Password has been reset on %s') % get_site_name(), 'sysadmin/user_reset_email.html', c, None, [email]) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return Response({'new_password': new_password})
def send_start_snapshot_notification(repo_id, timestamp, user_email): BLOXBERG_MSG = [] repo_name = get_repo(repo_id).repo_name msg = _( 'Your files with the library %(name)s are currently being certified. We will inform you once the task has successfully finished. This may take a while.' ) % { 'name': repo_name } BLOXBERG_MSG.append(msg) UserNotification.objects._add_user_notification( user_email, MSG_TYPE_KEEPER_BLOXBERG_MSG, json.dumps({ 'message': ('; '.join(BLOXBERG_MSG)), 'repo_id': repo_id, 'author_name': email2nickname(user_email), })) c = { 'to_user': user_email, 'notice_count': 1, 'message_type': 'start_snapshot_msg', #message_type for email 'message': ('; '.join(BLOXBERG_MSG)), 'repo_id': repo_id, 'author_name': email2nickname(user_email), 'timestamp': timestamp, } try: send_html_email( _('New notice on %s') % get_site_name(), 'notifications/keeper_email.html', c, None, [user_email]) logger.info('Successfully sent email to %s' % user_email) except Exception as e: logger.error('Failed to send email to %s, error detail: %s' % (user_email, e))
def do_action(self): now = datetime.datetime.now() try: cmd_last_check = CommandsLastCheck.objects.get( command_type=self.label) logger.debug('Last check time is %s' % cmd_last_check.last_check) unseen_notices = UserNotification.objects.get_all_notifications( seen=False, time_since=cmd_last_check.last_check) logger.debug('Update last check time to %s' % now) cmd_last_check.last_check = now cmd_last_check.save() except CommandsLastCheck.DoesNotExist: logger.debug('No last check time found, get all unread notices.') unseen_notices = UserNotification.objects.get_all_notifications( seen=False) logger.debug('Create new last check time: %s' % now) CommandsLastCheck(command_type=self.label, last_check=now).save() email_ctx = {} for notice in unseen_notices: if notice.to_user in email_ctx: email_ctx[notice.to_user] += 1 else: email_ctx[notice.to_user] = 1 for to_user, count in email_ctx.items(): # save current language cur_language = translation.get_language() # get and active user language user_language = self.get_user_language(to_user) translation.activate(user_language) logger.debug('Set language code to %s for user: %s' % (user_language, to_user)) self.stdout.write('[%s] Set language code to %s' % (str(datetime.datetime.now()), user_language)) notices = [] for notice in unseen_notices: logger.info('Processing unseen notice: [%s]' % (notice)) d = json.loads(notice.detail) repo_id = d.get('repo_id', None) group_id = d.get('group_id', None) try: if repo_id and not seafile_api.get_repo(repo_id): notice.delete() continue if group_id and not ccnet_api.get_group(group_id): notice.delete() continue except Exception as e: logger.error(e) continue if notice.to_user != to_user: continue elif notice.is_user_message(): notice = self.format_user_message(notice) elif notice.is_group_msg(): notice = self.format_group_message(notice) elif notice.is_repo_share_msg(): notice = self.format_repo_share_msg(notice) elif notice.is_repo_share_to_group_msg(): notice = self.format_repo_share_to_group_msg(notice) elif notice.is_file_uploaded_msg(): notice = self.format_file_uploaded_msg(notice) elif notice.is_group_join_request(): notice = self.format_group_join_request(notice) elif notice.is_add_user_to_group(): notice = self.format_add_user_to_group(notice) elif notice.is_file_comment_msg(): notice = self.format_file_comment_msg(notice) notices.append(notice) if not notices: continue contact_email = Profile.objects.get_contact_email_by_user(to_user) to_user = contact_email # use contact email if any c = { 'to_user': to_user, 'notice_count': count, 'notices': notices, } try: send_html_email( _('New notice on %s') % settings.SITE_NAME, 'notifications/notice_email.html', c, None, [to_user]) logger.info('Successfully sent email to %s' % to_user) self.stdout.write('[%s] Successfully sent email to %s' % (str(datetime.datetime.now()), to_user)) except Exception as e: logger.error('Failed to send email to %s, error detail: %s' % (to_user, e)) self.stderr.write( '[%s] Failed to send email to %s, error detail: %s' % (str(datetime.datetime.now()), to_user, e)) # restore current language translation.activate(cur_language)
def post(self, request): if not IS_EMAIL_CONFIGURED: error_msg = _(u'Sending shared link failed. Email service is not properly configured, please contact administrator.') return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check args email = request.POST.get('email', None) if not email: error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) token = request.POST.get('token', None) if not token: error_msg = 'token invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) extra_msg = request.POST.get('extra_msg', '') # check if token exists try: link = UploadLinkShare.objects.get(token=token) except UploadLinkShare.DoesNotExist: error_msg = 'token %s not found.' % token return api_error(status.HTTP_404_NOT_FOUND, error_msg) # check if is upload link owner username = request.user.username if not link.is_owner(username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) result = {} result['failed'] = [] result['success'] = [] to_email_list = string2list(email) # use contact_email, if present useremail = Profile.objects.get_contact_email_by_user(request.user.username) for to_email in to_email_list: failed_info = {} if not is_valid_email(to_email): failed_info['email'] = to_email failed_info['error_msg'] = 'email invalid.' result['failed'].append(failed_info) continue # prepare basic info c = { 'email': username, 'to_email': to_email, 'extra_msg': extra_msg, } if REPLACE_FROM_EMAIL: from_email = useremail else: from_email = None # use default from email if ADD_REPLY_TO_HEADER: reply_to = useremail else: reply_to = None c['shared_upload_link'] = gen_shared_upload_link(token) title = _(u'An upload link is shared to you on %s') % SITE_NAME template = 'shared_upload_link_email.html' # send email try: send_html_email(title, template, c, from_email, [to_email], reply_to=reply_to) result['success'].append(to_email) except Exception as e: logger.error(e) failed_info['email'] = to_email failed_info['error_msg'] = 'Internal Server Error' result['failed'].append(failed_info) return Response(result)
def post(self, request): if not IS_EMAIL_CONFIGURED: error_msg = _('Sending shared link failed. Email service is not properly configured, please contact administrator.') return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check args email = request.POST.get('email', None) if not email: error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) token = request.POST.get('token', None) if not token: error_msg = 'token invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) extra_msg = request.POST.get('extra_msg', '') # check if token exists try: link = FileShare.objects.get(token=token) except FileShare.DoesNotExist: error_msg = 'token %s not found.' % token return api_error(status.HTTP_404_NOT_FOUND, error_msg) # check if is share link owner username = request.user.username if not link.is_owner(username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) result = {} result['failed'] = [] result['success'] = [] to_email_list = string2list(email) # use contact_email, if present useremail = Profile.objects.get_contact_email_by_user(request.user.username) for to_email in to_email_list: failed_info = {} if not is_valid_email(to_email): failed_info['email'] = to_email failed_info['error_msg'] = 'email invalid.' result['failed'].append(failed_info) continue # prepare basic info c = { 'email': username, 'to_email': to_email, 'extra_msg': extra_msg, } if REPLACE_FROM_EMAIL: from_email = useremail else: from_email = None # use default from email if ADD_REPLY_TO_HEADER: reply_to = useremail else: reply_to = None c['file_shared_link'] = gen_shared_link(token, link.s_type) c['file_shared_name'] = os.path.basename(link.path.rstrip('/')) template = 'shared_link_email.html' if link.s_type == 'f': c['file_shared_type'] = _("file") title = _('A file is shared to you on %s') % get_site_name() else: c['file_shared_type'] = _("directory") title = _('A directory is shared to you on %s') % get_site_name() # send email try: send_html_email(title, template, c, from_email, [to_email], reply_to=reply_to) result['success'].append(to_email) except Exception as e: logger.error(e) failed_info['email'] = to_email failed_info['error_msg'] = 'Internal Server Error' result['failed'].append(failed_info) return Response(result)
def do_action(self): emails = [] user_file_updates_email_intervals = [] for ele in UserOptions.objects.filter( option_key=KEY_FILE_UPDATES_EMAIL_INTERVAL): try: user_file_updates_email_intervals.append( (ele.email, int(ele.option_val))) emails.append(ele.email) except Exception as e: logger.error(e) self.stderr.write('[%s]: %s' % (str(datetime.now()), e)) continue user_last_emailed_time_dict = {} for ele in UserOptions.objects.filter( option_key=KEY_FILE_UPDATES_LAST_EMAILED_TIME).filter( email__in=emails): try: user_last_emailed_time_dict[ele.email] = datetime.strptime( ele.option_val, "%Y-%m-%d %H:%M:%S") except Exception as e: logger.error(e) self.stderr.write('[%s]: %s' % (str(datetime.now()), e)) continue for (username, interval_val) in user_file_updates_email_intervals: # save current language cur_language = translation.get_language() # get and active user language user_language = self.get_user_language(username) translation.activate(user_language) logger.debug('Set language code to %s for user: %s' % (user_language, username)) self.stdout.write('[%s] Set language code to %s for user: %s' % (str(datetime.now()), user_language, username)) # get last_emailed_time if any, defaults to today 00:00:00.0 last_emailed_time = user_last_emailed_time_dict.get(username, None) now = datetime.utcnow().replace(microsecond=0) if not last_emailed_time: last_emailed_time = datetime.utcnow().replace(hour=0).replace( minute=0).replace(second=0).replace(microsecond=0) else: if (now - last_emailed_time).total_seconds() < interval_val: continue # get file updates(from: last_emailed_time, to: now) for repos # user can access res = seafevents_api.get_user_activities_by_timestamp( username, last_emailed_time, now) if not res: continue # remove my activities res = [x for x in res if x.op_user != username] if not res: continue # format mail content & send file updates email to user try: for ele in res: ele.user_avatar = self.get_avatar_src(ele.op_user) ele.local_timestamp = utc_to_local(ele.timestamp) ele.op_user_link = a_tag(email2nickname(ele.op_user), user_info_url(ele.op_user)) ele.operation, ele.op_details = self.format_file_operation( ele) except Exception as e: logger.error('Failed to format mail content for user: %s' % username) logger.error(e, exc_info=True) self.stderr.write( '[%s] Failed to format mail content for user: %s' % (str(datetime.now()), username)) self.stderr.write('[%s]: %s' % (str(datetime.now()), e)) continue nickname = email2nickname(username) contact_email = Profile.objects.get_contact_email_by_user(username) c = { 'name': nickname, 'updates_count': len(res), 'updates': res, } try: send_html_email( _('New file updates on %s') % get_site_name(), 'notifications/file_updates_email.html', c, None, [contact_email]) # set new last_emailed_time UserOptions.objects.set_file_updates_last_emailed_time( username, now) self.stdout.write('[%s] Successful to send email to %s' % (str(datetime.now()), contact_email)) except Exception as e: logger.error('Failed to send email to %s, error detail: %s' % (contact_email, e)) self.stderr.write('[%s] Failed to send email to %s, error ' 'detail: %s' % (str(datetime.now()), contact_email, e)) finally: # reset lang translation.activate(cur_language)
def send_notification(msg, repo_id, notification_type, user_email, doi='', doi_link='', timestamp=''): # status: 'invalid', 'success', 'error' # TODO: replace 'doi_link' with 'doi' in production if notification_type == MSG_TYPE_KEEPER_DOI_SUC_MSG: c = { 'to_user': user_email, 'message_type': 'doi_suc_msg', 'message': msg + doi, 'timestamp': timestamp, } try: send_html_email( _('New notice on %s') % get_site_name(), 'notifications/keeper_email.html', c, None, [user_email]) LOGGER.info('Successfully sent email to %s' % user_email) except Exception as e: LOGGER.error('Failed to send email to %s, error detail: %s' % (user_email, e)) UserNotification.objects._add_user_notification( user_email, notification_type, json.dumps({ 'message': (msg), 'lib': repo_id, 'archive_metadata': ARCHIVE_METADATA_TARGET, 'doi': doi, 'doi_link': doi_link, })) elif notification_type == MSG_TYPE_INVALID_METADATA_MSG: if isinstance(msg, list): UserNotification.objects._add_user_notification( user_email, notification_type, json.dumps({ 'message': (' '.join(msg)), 'lib': repo_id, 'archive_metadata': ARCHIVE_METADATA_TARGET, })) elif notification_type == MSG_TYPE_KEEPER_DOI_MSG: UserNotification.objects._add_user_notification( user_email, notification_type, json.dumps({ 'message': (msg), 'lib': repo_id, 'archive_metadata': ARCHIVE_METADATA_TARGET, 'doi': doi, 'doi_link': doi_link, })) elif notification_type == MSG_TYPE_KEEPER_ARCHIVING_MSG: UserNotification.objects._add_user_notification( user_email, notification_type, json.dumps({ 'msg': (msg), # unify format for backend '_repo': repo_id, 'status': 'prepare', # use 'prepare' to distinguish from backend sent notifications }))
def do_action(self): now = datetime.datetime.now() try: cmd_last_check = CommandsLastCheck.objects.get(command_type=self.label) logger.debug('Last check time is %s' % cmd_last_check.last_check) unseen_notices = UserNotification.objects.get_all_notifications( seen=False, time_since=cmd_last_check.last_check) logger.debug('Update last check time to %s' % now) cmd_last_check.last_check = now cmd_last_check.save() except CommandsLastCheck.DoesNotExist: logger.debug('No last check time found, get all unread notices.') unseen_notices = UserNotification.objects.get_all_notifications( seen=False) logger.debug('Create new last check time: %s' % now) CommandsLastCheck(command_type=self.label, last_check=now).save() email_ctx = {} for notice in unseen_notices: if notice.to_user in email_ctx: email_ctx[notice.to_user] += 1 else: email_ctx[notice.to_user] = 1 for to_user, count in email_ctx.items(): # save current language cur_language = translation.get_language() # get and active user language user_language = self.get_user_language(to_user) translation.activate(user_language) logger.info('Set language code to %s', user_language) notices = [] for notice in unseen_notices: if notice.to_user != to_user: continue if notice.is_priv_file_share_msg(): notice = self.format_priv_file_share_msg(notice) elif notice.is_user_message(): notice = self.format_user_message(notice) elif notice.is_group_msg(): notice = self.format_group_message(notice) elif notice.is_grpmsg_reply(): notice = self.format_grpmsg_reply(notice) elif notice.is_repo_share_msg(): notice = self.format_repo_share_msg(notice) elif notice.is_file_uploaded_msg(): notice = self.format_file_uploaded_msg(notice) elif notice.is_group_join_request(): notice = self.format_group_join_request(notice) notices.append(notice) if not notices: continue c = { 'to_user': to_user, 'notice_count': count, 'notices': notices, } try: send_html_email(_('New notice on %s') % settings.SITE_NAME, 'notifications/notice_email.html', c, None, [to_user]) logger.info('Successfully sent email to %s' % to_user) except Exception as e: logger.error('Failed to send email to %s, error detail: %s' % (to_user, e)) # restore current language translation.activate(cur_language)
def send_shared_link(request): """ Handle ajax post request to send file shared link. """ if not request.method == 'POST': raise Http404 content_type = 'application/json; charset=utf-8' if not IS_EMAIL_CONFIGURED: data = json.dumps({ 'error': _(u'Sending shared link failed. Email service is not properly configured, please contact administrator.' ) }) return HttpResponse(data, status=500, content_type=content_type) from seahub.settings import SITE_NAME form = FileLinkShareForm(request.POST) if form.is_valid(): email = form.cleaned_data['email'] file_shared_link = form.cleaned_data['file_shared_link'] file_shared_name = form.cleaned_data['file_shared_name'] file_shared_type = form.cleaned_data['file_shared_type'] extra_msg = escape(form.cleaned_data['extra_msg']) to_email_list = string2list(email) send_success, send_failed = [], [] for to_email in to_email_list: if not is_valid_email(to_email): send_failed.append(to_email) continue # Add email to contacts. mail_sended.send(sender=None, user=request.user.username, email=to_email) c = { 'email': request.user.username, 'to_email': to_email, 'file_shared_link': file_shared_link, 'file_shared_name': file_shared_name, } if extra_msg: c['extra_msg'] = extra_msg if REPLACE_FROM_EMAIL: from_email = request.user.username else: from_email = None # use default from email if ADD_REPLY_TO_HEADER: reply_to = request.user.username else: reply_to = None try: if file_shared_type == 'f': c['file_shared_type'] = _(u"file") send_html_email(_(u'A file is shared to you on %s') % SITE_NAME, 'shared_link_email.html', c, from_email, [to_email], reply_to=reply_to) else: c['file_shared_type'] = _(u"directory") send_html_email(_(u'A directory is shared to you on %s') % SITE_NAME, 'shared_link_email.html', c, from_email, [to_email], reply_to=reply_to) send_success.append(to_email) except Exception: send_failed.append(to_email) if len(send_success) > 0: data = json.dumps({ "send_success": send_success, "send_failed": send_failed }) return HttpResponse(data, status=200, content_type=content_type) else: data = json.dumps({ "error": _("Internal server error, or please check the email(s) you entered" ) }) return HttpResponse(data, status=400, content_type=content_type) else: return HttpResponseBadRequest(json.dumps(form.errors), content_type=content_type)
def send_group_member_add_mail(request, group, from_user, to_user): c = {"email": from_user, "to_email": to_user, "group": group} subject = _(u"You are invited to join a group on %s") % SITE_NAME send_html_email(subject, "group/add_member_email.html", c, None, [to_user])
def post(self, request): if user_number_over_limit(): error_msg = _("The number of users exceeds the limit.") return api_error(status.HTTP_400_BAD_REQUEST, error_msg) email = request.data.get('email', None) if not email or not is_valid_username(email): error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # basic user info check is_staff = request.data.get("is_staff", None) if is_staff: try: is_staff = to_python_boolean(is_staff) except ValueError: error_msg = 'is_staff invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_active = request.data.get("is_active", None) if is_active: try: is_active = to_python_boolean(is_active) except ValueError: error_msg = 'is_active invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # additional user info check role = request.data.get("role", None) if role: available_roles = get_available_roles() if role.lower() not in available_roles: error_msg = 'role must be in %s.' % str(available_roles) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) name = request.data.get("name", None) if name: if len(name) > 64: error_msg = 'Name is too long (maximum is 64 characters).' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if "/" in name: error_msg = "Name should not include '/'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) department = request.data.get("department", None) if department: if len(department) > 512: error_msg = "Department is too long (maximum is 512 characters)." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) quota_total_mb = request.data.get("quota_total", None) if quota_total_mb: try: quota_total_mb = int(quota_total_mb) except ValueError: error_msg = "Must be an integer that is greater than or equal to 0." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if quota_total_mb < 0: error_msg = "Space quota is too low (minimum value is 0)." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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') if quota_total_mb > org_quota_mb: error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: User.objects.get(email=email) user_exist = True except User.DoesNotExist: user_exist = False if user_exist: error_msg = "User %s already exists." % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) password = request.data.get('password', None) if not password: error_msg = 'password required.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # create user try: user_obj = User.objects.create_user(email) update_user_info(request, user_obj) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if IS_EMAIL_CONFIGURED and SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER: c = { 'user': request.user.username, 'email': email, 'password': password } try: send_html_email( _('You are invited to join %s') % get_site_name(), 'sysadmin/user_add_email.html', c, None, [email]) except Exception as e: logger.error(str(e)) user_info = get_user_info(email) return Response(user_info)
def do_action(self): emails = [] user_file_updates_email_intervals = [] for ele in UserOptions.objects.filter( option_key=KEY_COLLABORATE_EMAIL_INTERVAL): try: user_file_updates_email_intervals.append( (ele.email, int(ele.option_val)) ) emails.append(ele.email) except Exception as e: logger.error(e) self.stderr.write('[%s]: %s' % (str(datetime.datetime.now()), e)) continue user_last_emailed_time_dict = {} for ele in UserOptions.objects.filter(option_key=KEY_COLLABORATE_LAST_EMAILED_TIME).filter(email__in=emails): try: user_last_emailed_time_dict[ele.email] = datetime.datetime.strptime( ele.option_val, "%Y-%m-%d %H:%M:%S") except Exception as e: logger.error(e) self.stderr.write('[%s]: %s' % (str(datetime.datetime.now()), e)) continue # save current language cur_language = translation.get_language() for (to_user, interval_val) in user_file_updates_email_intervals: # get last_emailed_time if any, defaults to today 00:00:00.0 last_emailed_time = user_last_emailed_time_dict.get(to_user, None) now = datetime.datetime.now().replace(microsecond=0) if not last_emailed_time: last_emailed_time = datetime.datetime.now().replace(hour=0).replace( minute=0).replace(second=0).replace(microsecond=0) else: if (now - last_emailed_time).total_seconds() < interval_val: continue # get notices user_notices_qs = UserNotification.objects.get_all_notifications(seen=False, time_since=last_emailed_time) user_notices, count = list(user_notices_qs), user_notices_qs.count() if not count: continue # get and active user language user_language = self.get_user_language(to_user) translation.activate(user_language) logger.debug('Set language code to %s for user: %s' % ( user_language, to_user)) self.stdout.write('[%s] Set language code to %s for user: %s' % ( str(datetime.datetime.now()), user_language, to_user)) # format mail content and send notices = [] for notice in user_notices: d = json.loads(notice.detail) repo_id = d.get('repo_id') group_id = d.get('group_id') try: if repo_id and not seafile_api.get_repo(repo_id): notice.delete() continue if group_id and not ccnet_api.get_group(group_id): notice.delete() continue except Exception as e: logger.error(e) continue if notice.to_user != to_user: continue elif notice.is_repo_share_msg(): notice = self.format_repo_share_msg(notice) elif notice.is_repo_share_to_group_msg(): notice = self.format_repo_share_to_group_msg(notice) elif notice.is_file_uploaded_msg(): notice = self.format_file_uploaded_msg(notice) elif notice.is_group_join_request(): notice = self.format_group_join_request(notice) elif notice.is_add_user_to_group(): notice = self.format_add_user_to_group(notice) elif notice.is_file_comment_msg(): notice = self.format_file_comment_msg(notice) elif notice.is_guest_invitation_accepted_msg(): notice = self.format_guest_invitation_accepted_msg(notice) if notice is None: continue notices.append(notice) if not notices: continue user_name = email2nickname(to_user) contact_email = Profile.objects.get_contact_email_by_user(to_user) to_user = contact_email # use contact email if any c = { 'to_user': to_user, 'notice_count': count, 'notices': notices, 'user_name': user_name, } try: send_html_email(_('New notice on %s') % get_site_name(), 'notifications/notice_email.html', c, None, [to_user]) # set new last_emailed_time UserOptions.objects.set_collaborate_last_emailed_time( to_user, now) logger.info('Successfully sent email to %s' % to_user) self.stdout.write('[%s] Successfully sent email to %s' % (str(datetime.datetime.now()), to_user)) except Exception as e: logger.error('Failed to send email to %s, error detail: %s' % (to_user, e)) self.stderr.write('[%s] Failed to send email to %s, error detail: %s' % (str(datetime.datetime.now()), to_user, e)) # restore current language translation.activate(cur_language)
def do_action(self): now = datetime.datetime.now() try: cmd_last_check = CommandsLastCheck.objects.get(command_type=self.label) logger.debug('Last check time is %s' % cmd_last_check.last_check) unseen_notices = UserNotification.objects.get_all_notifications( seen=False, time_since=cmd_last_check.last_check) logger.debug('Update last check time to %s' % now) cmd_last_check.last_check = now cmd_last_check.save() except CommandsLastCheck.DoesNotExist: logger.debug('No last check time found, get all unread notices.') unseen_notices = UserNotification.objects.get_all_notifications( seen=False) logger.debug('Create new last check time: %s' % now) CommandsLastCheck(command_type=self.label, last_check=now).save() email_ctx = {} for notice in unseen_notices: if notice.to_user in email_ctx: email_ctx[notice.to_user] += 1 else: email_ctx[notice.to_user] = 1 for to_user, count in email_ctx.items(): notices = [] for notice in unseen_notices: if notice.to_user != to_user: continue if notice.is_priv_file_share_msg(): notice = self.format_priv_file_share_msg(notice) elif notice.is_user_message(): notice = self.format_user_message(notice) elif notice.is_group_msg(): notice = self.format_group_message(notice) elif notice.is_grpmsg_reply(): notice = self.format_grpmsg_reply(notice) elif notice.is_repo_share_msg(): notice = self.format_repo_share_msg(notice) elif notice.is_file_uploaded_msg(): notice = self.format_file_uploaded_msg(notice) elif notice.is_group_join_request(): notice = self.format_group_join_request(notice) notices.append(notice) if not notices: continue subject = subjects[1] if count > 1 else subjects[0] c = { 'to_user': to_user, 'notice_count': count, 'notices': notices, 'avatar_url': self.get_avatar_url(to_user), 'service_url': get_service_url(), } try: send_html_email(subject, 'notifications/notice_email.html', c, None, [to_user]) logger.info('Successfully sent email to %s' % to_user) except Exception as e: logger.error('Failed to send email to %s, error detail: %s' % (to_user, e))
def send_shared_upload_link(request): """ Handle ajax post request to send shared upload link. """ if not request.method == 'POST': raise Http404 content_type = 'application/json; charset=utf-8' if not IS_EMAIL_CONFIGURED: data = json.dumps({ 'error': _('Failed to send email, email service is not properly configured, please contact administrator.' ) }) return HttpResponse(data, status=500, content_type=content_type) form = UploadLinkShareForm(request.POST) if form.is_valid(): email = form.cleaned_data['email'] shared_upload_link = form.cleaned_data['shared_upload_link'] extra_msg = escape(form.cleaned_data['extra_msg']) to_email_list = string2list(email) send_success, send_failed = [], [] # use contact_email, if present username = Profile.objects.get_contact_email_by_user( request.user.username) for to_email in to_email_list: if not is_valid_email(to_email): send_failed.append(to_email) continue # Add email to contacts. mail_sended.send(sender=None, user=request.user.username, email=to_email) c = { 'email': request.user.username, 'to_email': to_email, 'shared_upload_link': shared_upload_link, } if extra_msg: c['extra_msg'] = extra_msg if REPLACE_FROM_EMAIL: from_email = username else: from_email = None # use default from email if ADD_REPLY_TO_HEADER: reply_to = username else: reply_to = None try: send_html_email(_('An upload link is shared to you on %s') % get_site_name(), 'shared_upload_link_email.html', c, from_email, [to_email], reply_to=reply_to) send_success.append(to_email) except Exception: send_failed.append(to_email) if len(send_success) > 0: data = json.dumps({ "send_success": send_success, "send_failed": send_failed }) return HttpResponse(data, status=200, content_type=content_type) else: data = json.dumps({ "error": _("Internal server error, or please check the email(s) you entered" ) }) return HttpResponse(data, status=400, content_type=content_type) else: return HttpResponseBadRequest(json.dumps(form.errors), content_type=content_type)
def do_action(self): now = datetime.datetime.now() try: cmd_last_check = CommandsLastCheck.objects.get(command_type=self.label) logger.debug('Last check time is %s' % cmd_last_check.last_check) unseen_notices = UserNotification.objects.get_all_notifications( seen=False, time_since=cmd_last_check.last_check) logger.debug('Update last check time to %s' % now) cmd_last_check.last_check = now cmd_last_check.save() except CommandsLastCheck.DoesNotExist: logger.debug('No last check time found, get all unread notices.') unseen_notices = UserNotification.objects.get_all_notifications( seen=False) logger.debug('Create new last check time: %s' % now) CommandsLastCheck(command_type=self.label, last_check=now).save() email_ctx = {} for notice in unseen_notices: if notice.to_user in email_ctx: email_ctx[notice.to_user] += 1 else: email_ctx[notice.to_user] = 1 for to_user, count in email_ctx.items(): # save current language cur_language = translation.get_language() # get and active user language user_language = self.get_user_language(to_user) translation.activate(user_language) logger.debug('Set language code to %s for user: %s' % (user_language, to_user)) self.stdout.write('[%s] Set language code to %s' % ( str(datetime.datetime.now()), user_language)) notices = [] for notice in unseen_notices: logger.info('Processing unseen notice: [%s]' % (notice)) d = json.loads(notice.detail) repo_id = d.get('repo_id', None) group_id = d.get('group_id', None) try: if repo_id and not seafile_api.get_repo(repo_id): notice.delete() continue if group_id and not ccnet_api.get_group(group_id): notice.delete() continue except Exception as e: logger.error(e) continue if notice.to_user != to_user: continue elif notice.is_group_msg(): notice = self.format_group_message(notice) elif notice.is_repo_share_msg(): notice = self.format_repo_share_msg(notice) elif notice.is_repo_share_to_group_msg(): notice = self.format_repo_share_to_group_msg(notice) elif notice.is_file_uploaded_msg(): notice = self.format_file_uploaded_msg(notice) elif notice.is_group_join_request(): notice = self.format_group_join_request(notice) elif notice.is_add_user_to_group(): notice = self.format_add_user_to_group(notice) elif notice.is_file_comment_msg(): notice = self.format_file_comment_msg(notice) elif notice.is_guest_invitation_accepted_msg(): notice = self.format_guest_invitation_accepted_msg(notice) if notice is None: continue notices.append(notice) if not notices: continue contact_email = Profile.objects.get_contact_email_by_user(to_user) to_user = contact_email # use contact email if any c = { 'to_user': to_user, 'notice_count': count, 'notices': notices, } try: send_html_email(_('New notice on %s') % get_site_name(), 'notifications/notice_email.html', c, None, [to_user]) logger.info('Successfully sent email to %s' % to_user) self.stdout.write('[%s] Successfully sent email to %s' % (str(datetime.datetime.now()), to_user)) except Exception as e: logger.error('Failed to send email to %s, error detail: %s' % (to_user, e)) self.stderr.write('[%s] Failed to send email to %s, error detail: %s' % (str(datetime.datetime.now()), to_user, e)) # restore current language translation.activate(cur_language)
def send_shared_link(request): """ Handle ajax post request to send file shared link. """ if not request.method == 'POST': raise Http404 content_type = 'application/json; charset=utf-8' if not IS_EMAIL_CONFIGURED: data = json.dumps({'error':_(u'Sending shared link failed. Email service is not properly configured, please contact administrator.')}) return HttpResponse(data, status=500, content_type=content_type) from seahub.settings import SITE_NAME form = FileLinkShareForm(request.POST) if form.is_valid(): email = form.cleaned_data['email'] file_shared_link = form.cleaned_data['file_shared_link'] file_shared_name = form.cleaned_data['file_shared_name'] file_shared_type = form.cleaned_data['file_shared_type'] extra_msg = escape(form.cleaned_data['extra_msg']) to_email_list = string2list(email) send_success, send_failed = [], [] for to_email in to_email_list: if not is_valid_email(to_email): send_failed.append(to_email) continue # Add email to contacts. mail_sended.send(sender=None, user=request.user.username, email=to_email) c = { 'email': request.user.username, 'to_email': to_email, 'file_shared_link': file_shared_link, 'file_shared_name': file_shared_name, } if extra_msg: c['extra_msg'] = extra_msg if REPLACE_FROM_EMAIL: from_email = request.user.username else: from_email = None # use default from email if ADD_REPLY_TO_HEADER: reply_to = request.user.username else: reply_to = None try: if file_shared_type == 'f': c['file_shared_type'] = _(u"file") send_html_email(_(u'A file is shared to you on %s') % SITE_NAME, 'shared_link_email.html', c, from_email, [to_email], reply_to=reply_to ) else: c['file_shared_type'] = _(u"directory") send_html_email(_(u'A directory is shared to you on %s') % SITE_NAME, 'shared_link_email.html', c, from_email, [to_email], reply_to=reply_to) send_success.append(to_email) except Exception: send_failed.append(to_email) if len(send_success) > 0: data = json.dumps({"send_success": send_success, "send_failed": send_failed}) return HttpResponse(data, status=200, content_type=content_type) else: data = json.dumps({"error": _("Internal server error, or please check the email(s) you entered")}) return HttpResponse(data, status=400, content_type=content_type) else: return HttpResponseBadRequest(json.dumps(form.errors), content_type=content_type)
def do_action(self): today = datetime.utcnow().replace(hour=0).replace(minute=0).replace( second=0).replace(microsecond=0) emails = [] user_file_updates_email_intervals = [] for ele in UserOptions.objects.filter( option_key=KEY_FILE_UPDATES_EMAIL_INTERVAL): try: user_file_updates_email_intervals.append( (ele.email, int(ele.option_val)) ) emails.append(ele.email) except Exception as e: logger.error(e) continue user_last_emailed_time_dict = {} for ele in UserOptions.objects.filter( option_key=KEY_FILE_UPDATES_LAST_EMAILED_TIME).filter( email__in=emails): try: user_last_emailed_time_dict[ele.email] = datetime.strptime( ele.option_val, "%Y-%m-%d %H:%M:%S") except Exception as e: logger.error(e) continue for (username, interval_val) in user_file_updates_email_intervals: # save current language cur_language = translation.get_language() # get and active user language user_language = self.get_user_language(username) translation.activate(user_language) logger.debug('Set language code to %s for user: %s' % ( user_language, username)) self.stdout.write('[%s] Set language code to %s' % ( str(datetime.now()), user_language)) # get last_emailed_time if any, defaults to today last_emailed_time = user_last_emailed_time_dict.get(username, today) now = datetime.utcnow().replace(microsecond=0) if (now - last_emailed_time).seconds < interval_val: continue # get file updates(from: last_emailed_time, to: now) for repos # user can access res = seafevents_api.get_user_activities_by_timestamp( username, last_emailed_time, now) if not res: continue # remove my activities res = filter(lambda x: x.op_user != username, res) if not res: continue # format mail content & send file updates email to user try: for ele in res: ele.user_avatar = self.get_avatar_src(ele.op_user) ele.local_timestamp = utc_to_local(ele.timestamp) ele.op_user_link = a_tag(email2nickname(ele.op_user), user_info_url(ele.op_user)) ele.operation, ele.op_details = self.format_file_operation(ele) except Exception as e: logger.error('Failed to format mail content for user: %s' % username) logger.error(e, exc_info=True) continue nickname = email2nickname(username) contact_email = Profile.objects.get_contact_email_by_user(username) c = { 'name': nickname, 'updates_count': len(res), 'updates': res, } try: send_html_email(_('New file updates on %s') % get_site_name(), 'notifications/file_updates_email.html', c, None, [contact_email]) # set new last_emailed_time UserOptions.objects.set_file_updates_last_emailed_time( username, now) except Exception as e: logger.error('Failed to send email to %s, error detail: %s' % (contact_email, e)) self.stderr.write('[%s] Failed to send email to %s, error ' 'detail: %s' % (str(now), contact_email, e)) finally: # reset lang translation.activate(cur_language)
def post(self, request): if not request.user.admin_permissions.can_manage_user(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') if user_number_over_limit(): error_msg = _("The number of users exceeds the limit.") return api_error(status.HTTP_400_BAD_REQUEST, error_msg) email = request.data.get('email', None) if not email or not is_valid_email(email): error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # basic user info check is_staff = request.data.get("is_staff", 'False') try: is_staff = to_python_boolean(is_staff) except ValueError: error_msg = 'is_staff invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_active = request.data.get("is_active", 'True') try: is_active = to_python_boolean(is_active) except ValueError: error_msg = 'is_active invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # additional user info check role = '' if is_pro_version(): role = request.data.get("role", None) if role: available_roles = get_available_roles() if role not in available_roles: error_msg = 'role must be in %s.' % str(available_roles) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) name = request.data.get("name", None) if name: if len(name) > 64: error_msg = 'Name is too long (maximum is 64 characters).' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if "/" in name: error_msg = "Name should not include '/'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) contact_email = request.data.get('contact_email', None) if contact_email and not is_valid_email(contact_email): error_msg = 'contact_email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) quota_total_mb = request.data.get("quota_total", None) if quota_total_mb: try: quota_total_mb = int(quota_total_mb) except ValueError: error_msg = "Must be an integer that is greater than or equal to 0." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if quota_total_mb < 0: error_msg = "Space quota is too low (minimum value is 0)." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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') if quota_total_mb > org_quota_mb: error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: User.objects.get(email=email) user_exist = True except User.DoesNotExist: user_exist = False if user_exist: error_msg = "User %s already exists." % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) password = request.data.get('password', None) if not password: error_msg = 'password required.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # create user try: user_obj = User.objects.create_user(email, password, is_staff, is_active) create_user_info(request, email=user_obj.username, role=role, nickname=name, contact_email=contact_email, quota_total_mb=quota_total_mb) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) add_user_tip = _('Successfully added user %(user)s.') % {'user': email} if IS_EMAIL_CONFIGURED and SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER: c = { 'user': request.user.username, 'email': email, 'password': password } try: send_html_email( _('You are invited to join %s') % get_site_name(), 'sysadmin/user_add_email.html', 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)) add_user_tip = _( 'Successfully added user %(user)s. But email notification can not be sent, because Email service is not properly configured.' ) % { 'user': email } user_info = get_user_info(email) user_info['add_user_tip'] = add_user_tip # send admin operation log signal admin_op_detail = { "email": email, } admin_operation.send(sender=None, admin_name=request.user.username, operation=USER_ADD, detail=admin_op_detail) return Response(user_info)
def put(self, request, email): if not request.user.admin_permissions.can_manage_user(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') # basic user info check is_staff = request.data.get("is_staff", None) if is_staff: try: is_staff = to_python_boolean(is_staff) except ValueError: error_msg = 'is_staff invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_active = request.data.get("is_active", None) if is_active: try: is_active = to_python_boolean(is_active) except ValueError: error_msg = 'is_active invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # additional user info check role = request.data.get("role", None) if role: available_roles = get_available_roles() if role not in available_roles: error_msg = 'role must be in %s.' % str(available_roles) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) name = request.data.get("name", None) if name: if len(name) > 64: error_msg = 'Name is too long (maximum is 64 characters).' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if "/" in name: error_msg = "Name should not include '/'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # argument check for login_id login_id = request.data.get("login_id", None) if login_id is not None: login_id = login_id.strip() username_by_login_id = Profile.objects.get_username_by_login_id( login_id) if username_by_login_id is not None: return api_error(status.HTTP_400_BAD_REQUEST, _("Login id %s already exists." % login_id)) contact_email = request.data.get("contact_email", None) if contact_email is not None and contact_email.strip() != '': if not is_valid_email(contact_email): error_msg = 'Contact email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) password = request.data.get("password") reference_id = request.data.get("reference_id", None) if reference_id: if ' ' in reference_id: return api_error(status.HTTP_400_BAD_REQUEST, 'Reference ID can not contain spaces.') primary_id = ccnet_api.get_primary_id(reference_id) if primary_id: return api_error( status.HTTP_400_BAD_REQUEST, 'Reference ID %s already exists.' % reference_id) quota_total_mb = request.data.get("quota_total", None) if quota_total_mb: try: quota_total_mb = int(quota_total_mb) except ValueError: error_msg = "Must be an integer that is greater than or equal to 0." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if quota_total_mb < 0: error_msg = "Space quota is too low (minimum value is 0)." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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') if quota_total_mb > org_quota_mb: error_msg = 'Failed to set quota: maximum quota is %d MB' % org_quota_mb return api_error(status.HTTP_400_BAD_REQUEST, error_msg) institution = request.data.get("institution", None) if institution: try: Institution.objects.get(name=institution) except Institution.DoesNotExist: error_msg = 'Institution %s does not exist' % institution return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # query user info try: user_obj = User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: update_user_info(request, user=user_obj, password=password, is_active=is_active, is_staff=is_staff, role=role, nickname=name, login_id=login_id, contact_email=contact_email, reference_id=reference_id, quota_total_mb=quota_total_mb, institution_name=institution) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # update user try: user_obj.save() except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) update_status_tip = '' if is_active is not None: update_status_tip = _('Edit succeeded') if user_obj.is_active and IS_EMAIL_CONFIGURED: try: send_html_email( _(u'Your account on %s is activated') % get_site_name(), 'sysadmin/user_activation_email.html', {'username': user_obj.email}, None, [email2contact_email(user_obj.email)]) update_status_tip = _( 'Edit succeeded, an email has been sent.') except Exception as e: logger.error(e) update_status_tip = _( 'Edit succeeded, but failed to send email, please check your email configuration.' ) user_info = get_user_info(email) user_info['update_status_tip'] = update_status_tip return Response(user_info)
def do_action(self): now = datetime.datetime.now() try: cmd_last_check = CommandsLastCheck.objects.get(command_type=self.label) logger.debug('Last check time is %s' % cmd_last_check.last_check) unseen_notices = UserNotification.objects.get_all_notifications( seen=False, time_since=cmd_last_check.last_check) logger.debug('Update last check time to %s' % now) cmd_last_check.last_check = now cmd_last_check.save() except CommandsLastCheck.DoesNotExist: logger.debug('No last check time found, get all unread notices.') unseen_notices = UserNotification.objects.get_all_notifications( seen=False) logger.debug('Create new last check time: %s' % now) CommandsLastCheck(command_type=self.label, last_check=now).save() email_ctx = {} for notice in unseen_notices: to_email = Profile.objects.get_contact_email_by_user(notice.to_user) if notice.to_user in email_ctx: email_ctx[to_email] += 1 else: email_ctx[to_email] = 1 for to_user, count in email_ctx.items(): # save current language cur_language = translation.get_language() # get and active user language user_language = self.get_user_language(to_user) translation.activate(user_language) logger.info('Set language code to %s' % user_language) self.stdout.write('[%s] Set language code to %s' % ( str(datetime.datetime.now()), user_language)) notices = [] for notice in unseen_notices: if notice.to_user != to_user: continue if notice.is_priv_file_share_msg(): notice = self.format_priv_file_share_msg(notice) elif notice.is_user_message(): notice = self.format_user_message(notice) elif notice.is_group_msg(): notice = self.format_group_message(notice) elif notice.is_grpmsg_reply(): notice = self.format_grpmsg_reply(notice) elif notice.is_repo_share_msg(): notice = self.format_repo_share_msg(notice) elif notice.is_file_uploaded_msg(): notice = self.format_file_uploaded_msg(notice) elif notice.is_group_join_request(): notice = self.format_group_join_request(notice) elif notice.is_add_user_to_group(): notice = self.format_add_user_to_group(notice) notices.append(notice) if not notices: continue c = { 'to_user': to_user, 'notice_count': count, 'notices': notices, } try: send_html_email(_('New notice on %s') % settings.SITE_NAME, 'notifications/notice_email.html', c, None, [to_user]) logger.info('Successfully sent email to %s' % to_user) self.stdout.write('[%s] Successfully sent email to %s' % (str(datetime.datetime.now()), to_user)) except Exception as e: logger.error('Failed to send email to %s, error detail: %s' % (to_user, e)) self.stderr.write('[%s] Failed to send email to %s, error detail: %s' % (str(datetime.datetime.now()), to_user, e)) # restore current language translation.activate(cur_language)