def search_user_when_global_address_book_disabled(request, q): email_list = [] username = request.user.username # search from contact # get user's contact list contacts = Contact.objects.get_contacts_by_user(username) for contact in contacts: # search user from contact list if q in contact.contact_email: email_list.append(contact.contact_email) # search from profile, limit search range in user's contacts limited_emails = [] for contact in contacts: limited_emails.append(contact.contact_email) email_list += search_user_from_profile_with_limits(q, limited_emails) if is_valid_email(q): # if `q` is a valid email email_list.append(q) # get user whose `contact_email` is `q` users = Profile.objects.filter(contact_email=q).values('user') for user in users: email_list.append(user['user']) return email_list
def contact_add(request): """ Handle normal request to add a contact. """ if request.method != 'POST': raise Http404 referer = request.META.get('HTTP_REFERER', None) if not referer: referer = SITE_ROOT username = request.user.username contact_email = request.POST.get('contact_email', '') if not is_valid_email(contact_email): messages.error(request, _(u"%s is not a valid email.") % contact_email) return HttpResponseRedirect(referer) if Contact.objects.get_contact_by_user(username, contact_email) is not None: messages.error(request, _(u"%s is already in your contacts.") % contact_email) return HttpResponseRedirect(referer) contact_name = request.POST.get('contact_name', '') note = request.POST.get('note', '') try: Contact.objects.add_contact(username, contact_email, contact_name, note) messages.success(request, _(u"Successfully added %s to contacts.") % contact_email) except Exception as e: logger.error(e) messages.error(request, _(u"Failed to add %s to contacts.") % contact_email) return HttpResponseRedirect(referer)
def search_user_when_global_address_book_disabled(request, q): """ Return 10 items at most. """ email_list = [] username = request.user.username # search from contact # get user's contact list contacts = Contact.objects.get_contacts_by_user(username) for contact in contacts: # search user from contact list if q in contact.contact_email: email_list.append(contact.contact_email) # search from profile, limit search range in user's contacts limited_emails = [] for contact in contacts: limited_emails.append(contact.contact_email) email_list += search_user_from_profile_with_limits(q, limited_emails) current_user = User.objects.get(email=username) if is_valid_email(q) and current_user.role.lower() != 'guest': # if `q` is a valid email and current is not a guest user email_list.append(q) # get user whose `contact_email` is `q` users = Profile.objects.filter(contact_email=q).values('user') for user in users: email_list.append(user['user']) return email_list
def clean(self): username = self.cleaned_data.get('login') password = self.cleaned_data.get('password') if username and password: if not is_valid_email(username): # convert login id to username if any username = Profile.objects.convert_login_str_to_username( username) self.user_cache = authenticate(username=username, password=password) if self.user_cache is None: """then try login id/contact email/primary id""" # convert contact email to username if any username = Profile.objects.convert_login_str_to_username( username) # convert username to primary id if any username = self.get_primary_id_by_username(username) self.user_cache = authenticate(username=username, password=password) if self.user_cache is None: err_msg = _( "Please enter a correct email/username and password. Note that both fields are case-sensitive." ) if settings.LOGIN_ERROR_DETAILS: try: u = User.objects.get(email=username) except User.DoesNotExist: err_msg = _( "That e-mail address doesn't have an associated user account. Are you sure you've registered?" ) self.errors['not_found'] = err_msg raise forms.ValidationError(err_msg) # user found for login string but inactive if not self.user_cache.is_active: if settings.ACTIVATE_AFTER_FIRST_LOGIN and \ not UserOptions.objects.is_user_logged_in(username): """Activate user on first login.""" self.user_cache.is_active = True self.user_cache.save() UserOptions.objects.set_user_logged_in(username) else: self.errors['inactive'] = _("This account is inactive.") raise forms.ValidationError(_("This account is inactive.")) # TODO: determine whether this should move to its own method. if self.request: if not self.request.session.test_cookie_worked(): raise forms.ValidationError( _("Your Web browser doesn't appear to have cookies enabled. Cookies are required for logging in." )) return self.cleaned_data
def post(self, request, format=None): # Send a invitation. itype = request.data.get('type', '').lower() if not itype or itype != 'guest': return api_error(status.HTTP_400_BAD_REQUEST, 'type invalid.') accepter = request.data.get('accepter', '').lower() if not accepter: return api_error(status.HTTP_400_BAD_REQUEST, 'accepter invalid.') if not is_valid_email(accepter): return api_error(status.HTTP_400_BAD_REQUEST, _('Email %s invalid.') % accepter) try: User.objects.get(accepter) user_exists = True except User.DoesNotExist: user_exists = False if user_exists: return api_error(status.HTTP_400_BAD_REQUEST, _('User %s already exists.') % accepter) i = Invitation.objects.add(inviter=request.user.username, accepter=accepter) i.send_to(email=accepter) return Response(i.to_dict(), status=201)
def contact_add_post(request): """ Handle ajax post to add a contact. """ result = {} content_type = 'application/json; charset=utf-8' username = request.user.username contact_email = request.POST.get('contact_email', '') if not is_valid_email(contact_email): result['success'] = False messages.error(request, _(u"%s is not a valid email.") % contact_email) return HttpResponseBadRequest(json.dumps(result), content_type=content_type) if Contact.objects.get_contact_by_user(username, contact_email) is not None: result['success'] = False messages.error(request, _(u"%s is already in your contacts.") % contact_email) return HttpResponseBadRequest(json.dumps(result), content_type=content_type) contact_name = request.POST.get('contact_name', '') note = request.POST.get('note', '') try: Contact.objects.add_contact(username, contact_email, contact_name, note) result['success'] = True messages.success(request, _(u"Successfully added %s to contacts.") % contact_email) return HttpResponse(json.dumps(result), content_type=content_type) except Exception as e: logger.error(e) result['success'] = False messages.error(request, _(u"Failed to add %s to contacts.") % contact_email) return HttpResponse(json.dumps(result), status=500, content_type=content_type)
def ajax_get_link_audit_code(request): """ Generate a token, and record that token with email in cache, expires in one hour, send token to that email address. User provide token and email at share link page, if the token and email are valid, record that email in session. """ content_type = 'application/json; charset=utf-8' token = request.POST.get('token') email = request.POST.get('email') if not is_valid_email(email): return HttpResponse(json.dumps( {'error': _('Email address is not valid')}), status=400, content_type=content_type) dfs = FileShare.objects.get_valid_file_link_by_token(token) ufs = UploadLinkShare.objects.get_valid_upload_link_by_token(token) fs = dfs if dfs else ufs if fs is None: return HttpResponse(json.dumps({'error': _('Share link is not found')}), status=400, content_type=content_type) cache_key = normalize_cache_key(email, 'share_link_audit_') timeout = 60 * 60 # one hour code = gen_token(max_length=6) cache.set(cache_key, code, timeout) # send code to user via email subject = _("Verification code for visiting share links") c = { 'code': code, } try: send_html_email_with_dj_template( email, dj_template='share/audit_code_email.html', context=c, subject=subject, priority=MAIL_PRIORITY.now) return HttpResponse(json.dumps({'success': True}), status=200, content_type=content_type) except Exception as e: logger.error('Failed to send audit code via email to %s') logger.error(e) return HttpResponse(json.dumps({ "error": _("Failed to send a verification code, please try again later.") }), status=500, content_type=content_type)
def post(self, request): itype = request.data.get('type', '').lower() if not itype or itype != 'guest': return api_error(status.HTTP_400_BAD_REQUEST, 'type invalid.') accepters = request.data.getlist('accepter', None) if not accepters: return api_error(status.HTTP_400_BAD_REQUEST, 'accepters invalid.') result = {} result['failed'] = [] result['success'] = [] for accepter in accepters: if not accepter.strip(): continue accepter = accepter.lower() if not is_valid_email(accepter): result['failed'].append({ 'email': accepter, 'error_msg': _('Email %s invalid.') % accepter }) continue if block_accepter(accepter): result['failed'].append({ 'email': accepter, 'error_msg': _('The email address is not allowed to be invited as a guest.') }) continue if Invitation.objects.filter(inviter=request.user.username, accepter=accepter).count() > 0: result['failed'].append({ 'email': accepter, 'error_msg': _('%s is already invited.') % accepter }) continue try: User.objects.get(accepter) result['failed'].append({ 'email': accepter, 'error_msg': _('User %s already exists.') % accepter }) continue except User.DoesNotExist: i = Invitation.objects.add(inviter=request.user.username, accepter=accepter) i.send_to(email=accepter) result['success'].append(i.to_dict()) return Response(result)
def ajax_get_link_audit_code(request): """ Generate a token, and record that token with email in cache, expires in one hour, send token to that email address. User provide token and email at share link page, if the token and email are valid, record that email in session. """ content_type = 'application/json; charset=utf-8' token = request.POST.get('token') email = request.POST.get('email') if not is_valid_email(email): return HttpResponse(json.dumps({ 'error': _('Email address is not valid') }), status=400, content_type=content_type) dfs = FileShare.objects.get_valid_file_link_by_token(token) ufs = UploadLinkShare.objects.get_valid_upload_link_by_token(token) fs = dfs if dfs else ufs if fs is None: return HttpResponse(json.dumps({ 'error': _('Share link is not found') }), status=400, content_type=content_type) cache_key = normalize_cache_key(email, 'share_link_audit_') timeout = 60 * 60 # one hour code = gen_token(max_length=6) cache.set(cache_key, code, timeout) # send code to user via email subject = _("Verification code for visiting share links") c = { 'code': code, } try: send_html_email_with_dj_template( email, dj_template='share/audit_code_email.html', context=c, subject=subject, priority=MAIL_PRIORITY.now ) return HttpResponse(json.dumps({'success': True}), status=200, content_type=content_type) except Exception as e: logger.error('Failed to send audit code via email to %s') logger.error(e) return HttpResponse(json.dumps({ "error": _("Failed to send a verification code, please try again later.") }), status=500, content_type=content_type)
def post(self, request, format=None): # Send invitation. itype = request.data.get('type', '').lower() if not itype or itype != 'guest': return api_error(status.HTTP_400_BAD_REQUEST, 'type invalid.') accepter = request.data.get('accepter', '').lower() if not accepter: return api_error(status.HTTP_400_BAD_REQUEST, 'accepter invalid.') if not is_valid_email(accepter): return api_error(status.HTTP_400_BAD_REQUEST, _('Email %s invalid.') % accepter) if block_accepter(accepter): return api_error( status.HTTP_400_BAD_REQUEST, _('The email address is not allowed to be invited as a guest.') ) if Invitation.objects.filter(inviter=request.user.username, accepter=accepter).count() > 0: return api_error(status.HTTP_400_BAD_REQUEST, _('%s is already invited.') % accepter) try: User.objects.get(accepter) user_exists = True except User.DoesNotExist: user_exists = False if user_exists: return api_error(status.HTTP_400_BAD_REQUEST, _('User %s already exists.') % accepter) i = Invitation.objects.add(inviter=request.user.username, accepter=accepter) m = i.send_to(email=accepter) if m.status == STATUS.sent: return Response(i.to_dict(), status=201) else: return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, _('Internal Server Error'))
def search_user_with_exact_match(request, q): """ Return 10 items at most. """ email_list = [] username = request.user.username current_user = User.objects.get(email=username) if is_valid_email(q) and current_user.role.lower() != 'guest': # if `q` is a valid email and current is not a guest user email_list.append(q) # get user whose `contact_email` is `q` users = Profile.objects.filter(contact_email=q).values('user') for user in users: if not is_org_user(user['user']): email_list.append(user['user']) return email_list
def post(self, request, format=None): # Send invitation. itype = request.data.get('type', '').lower() if not itype or itype != 'guest': return api_error(status.HTTP_400_BAD_REQUEST, 'type invalid.') accepter = request.data.get('accepter', '').lower() if not accepter: return api_error(status.HTTP_400_BAD_REQUEST, 'accepter invalid.') if not is_valid_email(accepter): return api_error(status.HTTP_400_BAD_REQUEST, _('Email %s invalid.') % accepter) if block_accepter(accepter): return api_error(status.HTTP_400_BAD_REQUEST, _('The email address is not allowed to be invited as a guest.')) if Invitation.objects.filter(inviter=request.user.username, accepter=accepter).count() > 0: return api_error(status.HTTP_400_BAD_REQUEST, _('%s is already invited.') % accepter) try: User.objects.get(accepter) user_exists = True except User.DoesNotExist: user_exists = False if user_exists: return api_error(status.HTTP_400_BAD_REQUEST, _('User %s already exists.') % accepter) i = Invitation.objects.add(inviter=request.user.username, accepter=accepter) m = i.send_to(email=accepter) if m.status == STATUS.sent: return Response(i.to_dict(), status=201) else: return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, _('Internal Server Error'))
def format_user_info(user_info_resp): logger.info('user info resp: %s' % user_info_resp.text) error = False user_info = {} user_info_json = user_info_resp.json() for item, attr in ATTRIBUTE_MAP.items(): required, user_attr = attr value = user_info_json.get(item, '') if value: # ccnet email if user_attr == 'email': user_info[user_attr] = value if is_valid_email(str(value)) else \ '%s@%s' % (str(value), PROVIDER_DOMAIN) else: user_info[user_attr] = value elif required: error = True return user_info, error
def authenticate(self, remote_user): """ The username passed as ``remote_user`` is considered trusted. This method simply returns the ``User`` object with the given username, creating a new ``User`` object if ``create_unknown_user`` is ``True``. Returns None if ``create_unknown_user`` is ``False`` and a ``User`` object with the given username is not found in the database. """ if remote_user: if not is_valid_email(remote_user): return None username = self.clean_username(remote_user) vid = get_virtual_id_by_email(username) try: user = User.objects.get(email=vid) return user except User.DoesNotExist: user = None else: user = None username = None # for readability if user: return user if self.create_unknown_user: user = User.objects.create_oauth_user( email=username, is_active=self.activate_after_creation) if not self.activate_after_creation: notify_admins_on_activate_request(username) elif settings.NOTIFY_ADMIN_AFTER_REGISTRATION: notify_admins_on_register_complete(username) else: user = None return user
def authenticate(self, remote_user, nickname): """ The username passed as ``remote_user`` is considered trusted. This method simply returns the ``User`` object with the given username """ if not remote_user or not is_valid_email(remote_user): return username = self.clean_username(remote_user) vid = get_virtual_id_by_email(username) try: user = User.objects.get(email=vid) except User.DoesNotExist: user = User.objects.create_saml_user( email=username, nickname=nickname, is_active=self.activate_after_creation) if settings.NOTIFY_ADMIN_AFTER_REGISTRATION: notify_admins_on_register_complete(username) return user
def post(self, request): """ Create an organization Permission checking: 1. only admin can perform this action. """ if not MULTI_TENANCY: error_msg = 'Feature is not enabled.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if not request.user.admin_permissions.other_permission(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') org_name = request.data.get('org_name', None) if not org_name: error_msg = 'org_name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) owner_email = request.data.get('owner_email', None) if not owner_email or not is_valid_email(owner_email): error_msg = 'email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) owner_password = request.data.get('owner_password', None) if not owner_password: error_msg = 'owner_password invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) url_prefix = gen_org_url_prefix(5, 20) if ccnet_api.get_org_by_url_prefix(url_prefix): error_msg = 'Failed to create organization, please try again later.' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) try: User.objects.get(email=owner_email) except User.DoesNotExist: pass else: error_msg = "User %s already exists." % owner_email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: new_user = User.objects.create_user(owner_email, owner_password, is_staff=False, is_active=True) except User.DoesNotExist as e: logger.error(e) error_msg = 'Failed to add user %s.' % owner_email return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) try: org_id = ccnet_api.create_org(org_name, url_prefix, new_user.username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) org = ccnet_api.get_org_by_id(org_id) try: org_info = get_org_info(org) 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(org_info)
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) 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, '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) 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 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 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) 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, '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) 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_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': _('Failed to send email, email service is not properly configured, please contact administrator.' ) }) return HttpResponse(data, status=500, content_type=content_type) 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 = [], [] # 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 if SHARE_LINK_EMAIL_LANGUAGE: activate(SHARE_LINK_EMAIL_LANGUAGE) # 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 = username else: from_email = None # use default from email if ADD_REPLY_TO_HEADER: reply_to = username else: reply_to = None try: if file_shared_type == 'f': c['file_shared_type'] = _("file") send_html_email(_('A file is shared to you on %s') % get_site_name(), 'shared_link_email.html', c, from_email, [to_email], reply_to=reply_to) else: c['file_shared_type'] = _("directory") send_html_email(_('A directory is shared to you on %s') % get_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 post(self, request): itype = request.data.get('type', '').lower() if not itype or itype != 'guest': return api_error(status.HTTP_400_BAD_REQUEST, 'type invalid.') accepters = request.data.getlist('accepter', None) if not accepters: return api_error(status.HTTP_400_BAD_REQUEST, 'accepters invalid.') result = {} result['failed'] = [] result['success'] = [] for accepter in accepters: if not accepter.strip(): continue accepter = accepter.lower() if not is_valid_email(accepter): result['failed'].append({ 'email': accepter, 'error_msg': _('Email %s invalid.') % accepter }) continue if block_accepter(accepter): result['failed'].append({ 'email': accepter, 'error_msg': _('The email address is not allowed to be invited as a guest.') }) continue if Invitation.objects.filter(inviter=request.user.username, accepter=accepter).count() > 0: result['failed'].append({ 'email': accepter, 'error_msg': _('%s is already invited.') % accepter }) continue try: User.objects.get(accepter) result['failed'].append({ 'email': accepter, 'error_msg': _('User %s already exists.') % accepter }) continue except User.DoesNotExist: i = Invitation.objects.add(inviter=request.user.username, accepter=accepter) m = i.send_to(email=accepter) if m.status == STATUS.sent: result['success'].append(i.to_dict()) else: result['failed'].append({ 'email': accepter, 'error_msg': _('Internal Server Error'), }) return Response(result)
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 get(self, request): """ Get all share permissions logs. Permission checking: 1. only admin can perform this action. """ try: current_page = int(request.GET.get('page', '1')) per_page = int(request.GET.get('per_page', '100')) except ValueError: current_page = 1 per_page = 100 user_selected = request.GET.get('email', None) if user_selected and not is_valid_email(user_selected): error_msg = 'email %s invalid.' % user_selected return api_error(status.HTTP_400_BAD_REQUEST, error_msg) repo_id_selected = request.GET.get('repo_id', None) if repo_id_selected and not is_valid_repo_id_format(repo_id_selected): error_msg = 'repo_id %s invalid.' % repo_id_selected return api_error(status.HTTP_400_BAD_REQUEST, error_msg) start = per_page * (current_page - 1) limit = per_page # org_id = 0, show all file audit events = get_perm_audit_events(user_selected, 0, repo_id_selected, start, limit) or [] has_next_page = True if len(events) == per_page else False # Use dict to reduce memcache fetch cost in large for-loop. from_nickname_dict = {} from_contact_email_dict = {} to_nickname_dict = {} to_contact_email_dict = {} repo_dict = {} from_user_email_set = set() to_user_email_set = set() repo_id_set = set() for event in events: from_user_email_set.add(event.from_user) to_user_email_set.add(event.to) repo_id_set.add(event.repo_id) for e in from_user_email_set: if e not in from_nickname_dict: from_nickname_dict[e] = email2nickname(e) if e not in from_contact_email_dict: from_contact_email_dict[e] = email2contact_email(e) for e in to_user_email_set: if e not in to_nickname_dict: to_nickname_dict[e] = email2nickname(e) if e not in to_contact_email_dict: to_contact_email_dict[e] = email2contact_email(e) for e in repo_id_set: if e not in repo_dict: repo_dict[e] = seafile_api.get_repo(e) events_info = [] for ev in events: data = {} from_user_email = ev.from_user to_user_email = ev.to data['from_user_email'] = from_user_email data['from_user_name'] = from_nickname_dict.get( from_user_email, '') data['from_user_contact_email'] = from_contact_email_dict.get( from_user_email, '') data['to_user_email'] = to_user_email data['to_user_name'] = to_nickname_dict.get(to_user_email, '') data['to_user_contact_email'] = to_contact_email_dict.get( to_user_email, '') data['etype'] = ev.etype data['permission'] = ev.permission repo_id = ev.repo_id data['repo_id'] = repo_id repo = repo_dict.get(repo_id, None) data['repo_name'] = repo.name if repo else '' data['folder'] = '/' if ev.file_path == '/' else os.path.basename( ev.file_path.rstrip('/')) data['date'] = utc_datetime_to_isoformat_timestr(ev.timestamp) events_info.append(data) resp = { 'share_permission_log_list': events_info, 'has_next_page': has_next_page, } return Response(resp)
def get(self, request): """ Get all file access logs. Permission checking: 1. only admin can perform this action. """ try: current_page = int(request.GET.get('page', '1')) per_page = int(request.GET.get('per_page', '100')) except ValueError: current_page = 1 per_page = 100 user_selected = request.GET.get('email', None) if user_selected and not is_valid_email(user_selected): error_msg = 'email %s invalid.' % user_selected return api_error(status.HTTP_400_BAD_REQUEST, error_msg) repo_id_selected = request.GET.get('repo_id', None) if repo_id_selected and not is_valid_repo_id_format(repo_id_selected): error_msg = 'repo_id %s invalid.' % repo_id_selected return api_error(status.HTTP_400_BAD_REQUEST, error_msg) start = per_page * (current_page - 1) limit = per_page # org_id = 0, show all file audit events = get_file_audit_events(user_selected, 0, repo_id_selected, start, limit) or [] has_next_page = True if len(events) == per_page else False # Use dict to reduce memcache fetch cost in large for-loop. nickname_dict = {} contact_email_dict = {} repo_dict = {} user_email_set = set() repo_id_set = set() for event in events: user_email_set.add(event.user) repo_id_set.add(event.repo_id) for e in user_email_set: if e not in nickname_dict: nickname_dict[e] = email2nickname(e) if e not in contact_email_dict: contact_email_dict[e] = email2contact_email(e) for e in repo_id_set: if e not in repo_dict: repo_dict[e] = seafile_api.get_repo(e) events_info = [] for ev in events: data = {} user_email = ev.user data['email'] = user_email data['name'] = nickname_dict.get(user_email, '') data['contact_email'] = contact_email_dict.get(user_email, '') data['ip'] = ev.ip data['event_type'], data[ 'device'] = generate_file_audit_event_type(ev) data['time'] = utc_datetime_to_isoformat_timestr(ev.timestamp) repo_id = ev.repo_id data['repo_id'] = repo_id repo = repo_dict.get(repo_id, None) data['repo_name'] = repo.name if repo else '' if ev.file_path.endswith('/'): data[ 'file_or_dir_name'] = '/' if ev.file_path == '/' else os.path.basename( ev.file_path.rstrip('/')) else: data['file_or_dir_name'] = os.path.basename(ev.file_path) events_info.append(data) resp = { 'file_access_log_list': events_info, 'has_next_page': has_next_page, } return Response(resp)
def get(self, request, format=None): if not self._can_use_global_address_book(request): return api_error(status.HTTP_403_FORBIDDEN, 'Guest user can not use global address book.') q = request.GET.get('q', None) if not q: return api_error(status.HTTP_400_BAD_REQUEST, 'Argument missing.') users_from_ccnet = [] users_from_profile = [] users_result = [] username = request.user.username if settings.CLOUD_MODE: if is_org_context(request): url_prefix = request.user.org.url_prefix users = seaserv.get_org_users_by_url_prefix(url_prefix, -1, -1) # search user from ccnet users_from_ccnet = filter(lambda u: q in u.email, users) # when search profile, only search users in org # 'nickname__icontains' for search by nickname # 'contact_email__icontains' for search by contact email users_from_profile = Profile.objects.filter(Q(user__in=[u.email for u in users]) & (Q(nickname__icontains=q)) | Q(contact_email__icontains=q)).values('user') elif settings.ENABLE_GLOBAL_ADDRESSBOOK: users_from_ccnet = search_user_from_ccnet(q) users_from_profile = Profile.objects.filter(Q(contact_email__icontains=q) | Q(nickname__icontains=q)).values('user') else: # in cloud mode, user will be added to Contact when share repo users = [] contacts = Contact.objects.get_contacts_by_user(username) for c in contacts: try: user = User.objects.get(email = c.contact_email) c.is_active = user.is_active except User.DoesNotExist: continue c.email = c.contact_email users.append(c) users_from_ccnet = filter(lambda u: q in u.email, users) if is_valid_email(q): users_from_ccnet += search_user_from_ccnet(q) # 'user__in' for only get profile of contacts # 'nickname__icontains' for search by nickname # 'contact_email__icontains' for search by contact users_from_profile = Profile.objects.filter(Q(user__in=[u.email for u in users]) & (Q(nickname__icontains=q)) | Q(contact_email__icontains=q)).values('user') else: users_from_ccnet = search_user_from_ccnet(q) users_from_profile = Profile.objects.filter(Q(contact_email__icontains=q) | Q(nickname__icontains=q)).values('user') # remove inactive users and add to result for u in users_from_ccnet[:10]: if u.is_active: users_result.append(u.email) for p in users_from_profile[:10]: try: user = User.objects.get(email = p['user']) except User.DoesNotExist: continue if not user.is_active: continue users_result.append(p['user']) # remove duplicate emails users_result = {}.fromkeys(users_result).keys() try: include_self = int(request.GET.get('include_self', 1)) except ValueError: include_self = 1 if include_self == 0 and username in users_result: # reomve myself users_result.remove(username) try: size = int(request.GET.get('avatar_size', 32)) except ValueError: size = 32 formated_result = format_searched_user_result(request, users_result, size)[:10] return HttpResponse(json.dumps({"users": formated_result}), status=200, content_type='application/json; charset=utf-8')
def put(self, request): email = request.user.username if not ENABLE_UPDATE_USER_INFO: error_msg = _(u'Feature disabled.') return api_error(status.HTTP_403_FORBIDDEN, error_msg) # argument check for name name = request.data.get("name", None) if name: name = name.strip() if len(name) > 64: error_msg = _(u'Name is too long (maximum is 64 characters)') return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if "/" in name: error_msg = _(u"Name should not include '/'.") return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # argument check for contact_email contact_email = request.data.get("contact_email", None) if contact_email: if not ENABLE_USER_SET_CONTACT_EMAIL: error_msg = _(u'Feature disabled.') return api_error(status.HTTP_403_FORBIDDEN, error_msg) profile = Profile.objects.get_profile_by_contact_email(contact_email) if profile and profile.user != email: # if contact email is used by others, return 403 error_msg = _('Contact email %s already exists.' % contact_email) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # update contact email contact_email = 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) # agrument check for telephone telephone = request.data.get('telephone', None) if telephone: telephone = telephone.strip() if len(telephone) > 100: error_msg = _('telephone is too long (maximum is 100 characters).') return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # argument check for list_in_address_book list_in_address_book = request.data.get("list_in_address_book", None) if list_in_address_book is not None: if list_in_address_book.lower() not in ('true', 'false'): error_msg = 'list_in_address_book invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) info_dict = { 'name': name, 'contact_email': contact_email, 'telephone': telephone, 'list_in_address_book': list_in_address_book, } # update user profile and user additionnal info try: self._update_user_info(info_dict, email) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # get user info and return info = self._get_user_info(email) return Response(info)
def put(self, request, org_id, email): """ update name of an org user. Permission checking: 1. only admin can perform this action. """ # resource check org_id = int(org_id) if not ccnet_api.get_org_by_id(org_id): error_msg = 'Organization %s not found.' % org_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: user = 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) # permission check if not request.user.org.is_staff: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if request.user.org.org_id != org_id: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if not is_org_user(email, org_id): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # update user's name name = request.data.get("name", None) if name is not None: name = name.strip() 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) try: Profile.objects.add_or_update(email, nickname=name) 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's contact email contact_email = request.data.get("contact_email", None) if contact_email is not None: contact_email = contact_email.strip() 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) try: Profile.objects.add_or_update(email, contact_email=contact_email) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) info = get_user_info(email) info['is_active'] = user.is_active return Response(info)
def put(self, request, org_id, repo_id): """Transfer an organization library """ new_owner = request.data.get('email', None) if not new_owner: error_msg = 'Email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not is_valid_email(new_owner): error_msg = 'Email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) org_id = int(org_id) if not ccnet_api.get_org_by_id(org_id): error_msg = 'Organization %s not found.' % org_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission checking if not org_user_exists(org_id, new_owner): error_msg = 'User %s not in org %s.' % (new_owner, org_id) return api_error(status.HTTP_404_NOT_FOUND, error_msg) 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 is_org_repo(org_id, repo_id): error_msg = 'Library %s not in org %s.' % (repo_id, org_id) return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_owner = seafile_api.get_org_repo_owner(repo_id) # get repo shared to user/group list shared_users = seafile_api.list_org_repo_shared_to( org_id, repo_owner, repo_id) shared_groups = seafile_api.list_org_repo_shared_group( org_id, repo_owner, repo_id) # get all pub repos pub_repos = seafile_api.list_org_inner_pub_repos_by_owner( org_id, repo_owner) seafile_api.set_org_repo_owner(org_id, repo_id, new_owner) # reshare repo to user for shared_user in shared_users: shared_username = shared_user.user if new_owner == shared_username: continue seafile_api.org_share_repo(org_id, repo_id, new_owner, shared_username, shared_user.perm) # reshare repo to group for shared_group in shared_groups: shared_group_id = shared_group.group_id if not ccnet_api.is_group_user(shared_group_id, new_owner): continue seafile_api.add_org_group_repo(repo_id, org_id, shared_group_id, new_owner, shared_group.perm) # check if current repo is pub-repo # if YES, reshare current repo to public for pub_repo in pub_repos: if repo_id != pub_repo.id: continue seafile_api.set_org_inner_pub_repo(org_id, repo_id, pub_repo.permission) break repo_info = {} repo_info['owner_email'] = new_owner repo_info['owner_name'] = email2nickname(new_owner) repo_info['encrypted'] = repo.encrypted repo_info['repo_id'] = repo.repo_id repo_info['repo_name'] = repo.name repo_info['is_department_repo'] = False repo_info['group_id'] = '' return Response(repo_info)
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 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) 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 = [], [] # 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 if SHARE_LINK_EMAIL_LANGUAGE: activate(SHARE_LINK_EMAIL_LANGUAGE) # 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 = username else: from_email = None # use default from email if ADD_REPLY_TO_HEADER: reply_to = 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') % get_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') % get_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 get(self, request, format=None): if not self._can_use_global_address_book(request): return api_error(status.HTTP_403_FORBIDDEN, 'Guest user can not use global address book.') q = request.GET.get('q', None) if not q: return api_error(status.HTTP_400_BAD_REQUEST, 'Argument missing.') users_from_ccnet = [] users_from_profile = [] users_result = [] username = request.user.username if CLOUD_MODE: if is_org_context(request): url_prefix = request.user.org.url_prefix users = seaserv.get_org_users_by_url_prefix(url_prefix, -1, -1) # search user from ccnet users_from_ccnet = filter(lambda u: q in u.email, users) # when search profile, only search users in org # 'nickname__icontains' for search by nickname # 'contact_email__icontains' for search by contact email users_from_profile = Profile.objects.filter( Q(user__in=[u.email for u in users]) & (Q(nickname__icontains=q)) | Q(contact_email__icontains=q)).values('user') elif ENABLE_GLOBAL_ADDRESSBOOK: users_from_ccnet = search_user_from_ccnet(q) users_from_profile = Profile.objects.filter( Q(contact_email__icontains=q) | Q(nickname__icontains=q)).values('user') else: # in cloud mode, user will be added to Contact when share repo users = [] contacts = Contact.objects.get_contacts_by_user(username) for c in contacts: try: user = User.objects.get(email=c.contact_email) c.is_active = user.is_active except User.DoesNotExist: continue c.email = c.contact_email users.append(c) users_from_ccnet = filter(lambda u: q in u.email, users) if is_valid_email(q): users_from_ccnet += search_user_from_ccnet(q) # 'user__in' for only get profile of contacts # 'nickname__icontains' for search by nickname # 'contact_email__icontains' for search by contact users_from_profile = Profile.objects.filter( Q(user__in=[u.email for u in users]) & (Q(nickname__icontains=q)) | Q(contact_email__icontains=q)).values('user') else: users_from_ccnet = search_user_from_ccnet(q) users_from_profile = Profile.objects.filter( Q(contact_email__icontains=q) | Q(nickname__icontains=q)).values('user') # remove inactive users and add to result for u in users_from_ccnet[:10]: if u.is_active: users_result.append(u.email) for p in users_from_profile[:10]: try: user = User.objects.get(email=p['user']) except User.DoesNotExist: continue if not user.is_active: continue users_result.append(p['user']) # remove duplicate emails users_result = {}.fromkeys(users_result).keys() try: include_self = int(request.GET.get('include_self', 1)) except ValueError: include_self = 1 if include_self == 0 and username in users_result: # reomve myself users_result.remove(username) try: size = int(request.GET.get('avatar_size', 32)) except ValueError: size = 32 formated_result = format_searched_user_result(request, users_result, size)[:10] return HttpResponse(json.dumps({"users": formated_result}), status=200, content_type='application/json; charset=utf-8')
def post(self, request, org_id): """ Add new user to org. Permission checking: 1. only admin can perform this action. """ # argument check org_id = int(org_id) if org_id == 0: error_msg = 'org_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) org = ccnet_api.get_org_by_id(org_id) if not org: error_msg = 'Organization %d not found.' % org_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) email = request.POST.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) password = request.POST.get('password', None) if not password: error_msg = 'password invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: User.objects.get(email=email) user_exists = True except User.DoesNotExist: user_exists = False if user_exists: error_msg = 'User %s already exists.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # check user number limit by license if user_number_over_limit(): error_msg = 'The number of users exceeds the limit.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check user number limit by org member quota org_members = len(ccnet_api.get_org_emailusers(org.url_prefix, -1, -1)) if ORG_MEMBER_QUOTA_ENABLED: from seahub_extra.organizations.models import OrgMemberQuota org_members_quota = OrgMemberQuota.objects.get_quota(org_id) if org_members_quota is not None and org_members >= org_members_quota: error_msg = 'Failed. You can only invite %d members.' % org_members_quota return api_error(status.HTTP_403_FORBIDDEN, error_msg) # create user try: user = User.objects.create_user(email, password, is_staff=False, is_active=True) except User.DoesNotExist as e: logger.error(e) error_msg = 'Fail to add user %s.' % email return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # add user to org # set `is_staff` parameter as `0` try: ccnet_api.add_org_user(org_id, email, 0) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) name = request.POST.get('name', None) if name: Profile.objects.add_or_update(email, name) if config.FORCE_PASSWORD_CHANGE: UserOptions.objects.set_force_passwd_change(email) user_info = get_org_user_info(org_id, user) return Response(user_info)
def post(self, request, org_id): """ Add new user to org. Permission checking: 1. only admin can perform this action. """ # argument check org_id = int(org_id) if org_id == 0: error_msg = 'org_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) org = ccnet_api.get_org_by_id(org_id) if not org: error_msg = 'Organization %d not found.' % org_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) email = request.POST.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) password = request.POST.get('password', None) if not password: error_msg = 'password invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) active = request.POST.get('active', 'true') active = active.lower() if active not in ('true', 'false'): error_msg = 'active invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) is_active = active == 'true' try: User.objects.get(email=email) user_exists = True except User.DoesNotExist: user_exists = False if user_exists: error_msg = 'User %s already exists.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # check user number limit by license if user_number_over_limit(): error_msg = 'The number of users exceeds the limit.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # check user number limit by org member quota org_members = len(ccnet_api.get_org_emailusers(org.url_prefix, -1, -1)) if ORG_MEMBER_QUOTA_ENABLED: from seahub_extra.organizations.models import OrgMemberQuota org_members_quota = OrgMemberQuota.objects.get_quota(org_id) if org_members_quota is not None and org_members >= org_members_quota: error_msg = 'Failed. You can only invite %d members.' % org_members_quota return api_error(status.HTTP_403_FORBIDDEN, error_msg) # create user try: User.objects.create_user(email, password, is_staff=False, is_active=is_active) except User.DoesNotExist as e: logger.error(e) error_msg = 'Fail to add user %s.' % email return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # add user to org # set `is_staff` parameter as `0` try: ccnet_api.add_org_user(org_id, email, 0) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) name = request.POST.get('name', None) if name: Profile.objects.add_or_update(email, name) if config.FORCE_PASSWORD_CHANGE: UserOptions.objects.set_force_passwd_change(email) user_info = get_org_user_info(org_id, email) user_info['active'] = is_active return Response(user_info)
def get(self, request): """ Get all file update logs. Permission checking: 1. only admin can perform this action. """ if not request.user.admin_permissions.can_view_user_log(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') try: current_page = int(request.GET.get('page', '1')) per_page = int(request.GET.get('per_page', '100')) except ValueError: current_page = 1 per_page = 100 user_selected = request.GET.get('email', None) if user_selected and not is_valid_email(user_selected): error_msg = 'email %s invalid.' % user_selected return api_error(status.HTTP_400_BAD_REQUEST, error_msg) repo_id_selected = request.GET.get('repo_id', None) if repo_id_selected and not is_valid_repo_id_format(repo_id_selected): error_msg = 'repo_id %s invalid.' % repo_id_selected return api_error(status.HTTP_400_BAD_REQUEST, error_msg) start = per_page * (current_page - 1) limit = per_page # org_id = 0, show all file audit events = get_file_update_events(user_selected, 0, repo_id_selected, start, limit) or [] has_next_page = True if len(events) == per_page else False # Use dict to reduce memcache fetch cost in large for-loop. nickname_dict = {} contact_email_dict = {} repo_dict = {} user_email_set = set() repo_id_set = set() for event in events: user_email_set.add(event.user) repo_id_set.add(event.repo_id) for e in user_email_set: if e not in nickname_dict: nickname_dict[e] = email2nickname(e) if e not in contact_email_dict: contact_email_dict[e] = email2contact_email(e) for e in repo_id_set: if e not in repo_dict: repo_dict[e] = seafile_api.get_repo(e) events_info = [] for ev in events: data = {} user_email = ev.user data['email'] = user_email data['name'] = nickname_dict.get(user_email, '') data['contact_email'] = contact_email_dict.get(user_email, '') data['time'] = utc_datetime_to_isoformat_timestr(ev.timestamp) repo_id = ev.repo_id data['repo_id'] = repo_id repo = repo_dict.get(repo_id, None) data['repo_name'] = repo.name if repo else '' data['repo_encrypted'] = repo.encrypted if repo else None data['file_operation'] = ev.file_oper data['commit_id'] = ev.commit_id events_info.append(data) resp = { 'file_update_log_list': events_info, 'has_next_page': has_next_page, } return Response(resp)
def put(self, request, email): # 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) # 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, _(u"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) profile = Profile.objects.get_profile_by_contact_email(contact_email) if profile: error_msg = 'Contact email %s already exists.' % contact_email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) reference_id = request.data.get("reference_id", "") 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) 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) # 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_obj) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) user_info = get_user_info(email) return Response(user_info)
def put(self, request, repo_id, format=None): """ update a library status, transfer a library, rename a library Permission checking: 1. only admin can perform this action. """ # argument check new_status = request.data.get('status', None) if new_status: if new_status not in ('normal', 'read-only'): error_msg = 'status invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) new_repo_name = request.data.get('name', None) if new_repo_name: if not is_valid_dirent_name(new_repo_name): error_msg = 'name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) new_owner = request.data.get('owner', None) if new_owner: if not is_valid_email(new_owner): error_msg = 'owner invalid.' return api_error(status.HTTP_400_BAD_REQUEST, 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 new_status: try: seafile_api.set_repo_status(repo_id, normalize_repo_status_str(new_status)) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if new_repo_name: try: res = seafile_api.edit_repo(repo_id, new_repo_name, '', None) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if res == -1: e = 'Admin rename failed: ID of library is %s, edit_repo api called failed.' % \ repo_id logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if new_owner: try: new_owner_obj = User.objects.get(email=new_owner) except User.DoesNotExist: error_msg = 'User %s not found.' % new_owner return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not new_owner_obj.permissions.can_add_repo(): error_msg = _('Transfer failed: role of %s is %s, can not add library.') % \ (new_owner, new_owner_obj.role) return api_error(status.HTTP_403_FORBIDDEN, error_msg) if MULTI_TENANCY: try: if seafile_api.get_org_id_by_repo_id(repo_id) > 0: error_msg = 'Can not transfer organization library.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if ccnet_api.get_orgs_by_user(new_owner): error_msg = 'Can not transfer library to organization user %s' % new_owner return api_error(status.HTTP_403_FORBIDDEN, error_msg) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) repo_owner = seafile_api.get_repo_owner(repo_id) if new_owner == repo_owner: error_msg = _("Library can not be transferred to owner.") return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # get repo shared to user/group list shared_users = seafile_api.list_repo_shared_to( repo_owner, repo_id) shared_groups = seafile_api.list_repo_shared_group_by_user( repo_owner, repo_id) # get all pub repos pub_repos = [] if not request.cloud_mode: pub_repos = seafile_api.list_inner_pub_repos_by_owner(repo_owner) # transfer repo seafile_api.set_repo_owner(repo_id, new_owner) # reshare repo to user for shared_user in shared_users: shared_username = shared_user.user if new_owner == shared_username: continue seafile_api.share_repo(repo_id, new_owner, shared_username, shared_user.perm) # reshare repo to group for shared_group in shared_groups: shared_group_id = shared_group.group_id if not is_group_member(shared_group_id, new_owner): continue seafile_api.set_group_repo(repo_id, shared_group_id, new_owner, shared_group.perm) # reshare repo to links try: UploadLinkShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner) FileShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # check if current repo is pub-repo # if YES, reshare current repo to public for pub_repo in pub_repos: if repo_id != pub_repo.id: continue seafile_api.add_inner_pub_repo(repo_id, pub_repo.permission) break # send admin operation log signal admin_op_detail = { "id": repo_id, "name": repo.name, "from": repo_owner, "to": new_owner, } admin_operation.send(sender=None, admin_name=request.user.username, operation=REPO_TRANSFER, detail=admin_op_detail) repo = seafile_api.get_repo(repo_id) repo_info = get_repo_info(repo) return Response(repo_info)
def post(self, request, org_id): """Added an organization user, check member quota before adding. """ # resource check org_id = int(org_id) if not ccnet_api.get_org_by_id(org_id): error_msg = 'Organization %s not found.' % org_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # check plan url_prefix = request.user.org.url_prefix org_members = len( ccnet_api.get_org_users_by_url_prefix(url_prefix, -1, -1)) if ORG_MEMBER_QUOTA_ENABLED: from seahub_extra.organizations.models import OrgMemberQuota org_members_quota = OrgMemberQuota.objects.get_quota( request.user.org.org_id) if org_members_quota is not None and org_members >= org_members_quota: err_msg = 'Failed. You can only invite %d members.' % org_members_quota return api_error(status.HTTP_403_FORBIDDEN, err_msg) if user_number_over_limit(): return api_error(status.HTTP_403_FORBIDDEN, 'The number of users exceeds the limit') email = request.data.get('email', '') name = request.data.get('name', '') password = request.data.get('password', '') if not email or not is_valid_email(email): return api_error(status.HTTP_400_BAD_REQUEST, 'Email invalid.') if not password: return api_error(status.HTTP_400_BAD_REQUEST, 'Password invalid.') name = name.strip() if not name: return api_error(status.HTTP_400_BAD_REQUEST, 'Name invalid.') 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) try: user = User.objects.get(email=email) error_msg = 'User %s already exists.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) except User.DoesNotExist: pass try: user = User.objects.create_user(email, password, is_staff=False, is_active=True) except User.DoesNotExist as e: logger.error(e) error_msg = 'Fail to add user %s.' % email return api_error(status.HTTP_403_FORBIDDEN, error_msg) if user and name: Profile.objects.add_or_update(username=user.username, nickname=name) set_org_user(org_id, user.username) if IS_EMAIL_CONFIGURED: if SEND_EMAIL_ON_ADDING_SYSTEM_MEMBER: try: send_user_add_mail(request, email, password) except Exception, e: logger.error(str(e))
def post(self, request): """ Create an organization Permission checking: 1. only admin can perform this action. """ if not (CLOUD_MODE and MULTI_TENANCY): error_msg = 'Feature is not enabled.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) org_name = request.data.get('org_name', None) if not org_name: error_msg = 'org_name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) admin_email = request.data.get('admin_email', None) if not admin_email or not is_valid_email(admin_email): error_msg = 'admin_email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) admin_name = request.data.get('admin_name') password = request.data.get('password', None) if not password: error_msg = 'password invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) url_prefix = gen_org_url_prefix(5, 20) if ccnet_api.get_org_by_url_prefix(url_prefix): error_msg = 'Failed to create organization, please try again later.' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) try: User.objects.get(email=admin_email) except User.DoesNotExist: pass else: error_msg = "User %s already exists." % admin_email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # check profile if Profile.objects.filter(contact_email=admin_email).exists(): error_msg = "User %s already exists." % admin_email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: new_user = User.objects.create_user(admin_email, password, is_staff=False, is_active=True) except User.DoesNotExist as e: logger.error(e) error_msg = 'Failed to add user %s.' % admin_email return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # update profile nickname if admin_name: Profile.objects.add_or_update(new_user.username, nickname=admin_name) try: org_id = ccnet_api.create_org(org_name, url_prefix, new_user.username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) org = ccnet_api.get_org_by_id(org_id) OrgSettings.objects.add_or_update(org, ORG_DEFAULT) try: org_info = get_org_info(org) 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(org_info)
def put(self, request, org_id, email): """ update name of an org user. Permission checking: 1. only admin can perform this action. """ # resource check org_id = int(org_id) if not ccnet_api.get_org_by_id(org_id): error_msg = 'Organization %s not found.' % org_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: user = 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) # permission check if not is_org_user(email, org_id): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # update user's name name = request.data.get("name", None) if name is not None: name = name.strip() 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) try: Profile.objects.add_or_update(email, nickname=name) 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's contact email contact_email = request.data.get("contact_email", None) if contact_email is not None: contact_email = contact_email.strip() 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) try: Profile.objects.add_or_update(email, contact_email=contact_email) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) is_staff = request.data.get("is_staff", None) if is_staff is not None: 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) if is_staff: if is_org_staff(org_id, user.username): error_msg = '%s is already organization staff.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) set_org_staff(org_id, user.username) if not is_staff: if not is_org_staff(org_id, user.username): error_msg = '%s is not organization staff.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) unset_org_staff(org_id, user.username) 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) org_quota = seafile_api.get_org_quota(org_id) org_quota_mb = org_quota / get_file_size_unit('MB') # -1 means org has unlimited quota if org_quota > 0 and quota_total_mb > org_quota_mb: error_msg = _(u'Failed to set quota: maximum quota is %d MB' % org_quota_mb) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) quota_total = int(quota_total_mb) * get_file_size_unit('MB') try: seafile_api.set_org_user_quota(org_id, email, quota_total) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) info = get_user_info(email, org_id) info['is_active'] = user.is_active info['id'] = user.id info['ctime'] = timestamp_to_isoformat_timestr(user.ctime) try: last_login = UserLastLogin.objects.get(username=user.email) info['last_login'] = datetime_to_isoformat_timestr( last_login.last_login) except UserLastLogin.DoesNotExist: info['last_login'] = None # these two fields are designed to be compatible with the old API info['self_usage'] = info.get('quota_usage') info['quota'] = info.get('quota_total') return Response(info)