def send_digest(grouped_digests): """ Send digest emails and remove digests for sent messages in a callback. :param grouped_digests: digest notification messages from the past 24 hours grouped by user :return: """ for group in grouped_digests: user = User.load(group['user_id']) if not user: sentry.log_exception() sentry.log_message("A user with this username does not exist.") return info = group['info'] digest_notification_ids = [message['_id'] for message in info] sorted_messages = group_messages_by_node(info) if sorted_messages: logger.info('Sending email digest to user {0!r}'.format(user)) mails.send_mail( to_addr=user.username, mimetype='html', mail=mails.DIGEST, name=user.fullname, message=sorted_messages, callback=remove_sent_digest_notifications.si( digest_notification_ids=digest_notification_ids))
def subscribe_mailchimp(list_name, user_id): user = User.load(user_id) m = get_mailchimp_api() list_id = get_list_id_from_name(list_name=list_name) if user.mailchimp_mailing_lists is None: user.mailchimp_mailing_lists = {} try: m.lists.subscribe( id=list_id, email={'email': user.username}, merge_vars={ 'fname': user.given_name, 'lname': user.family_name, }, double_optin=False, update_existing=True, ) except mailchimp.ValidationError as error: sentry.log_exception() sentry.log_message(error.message) user.mailchimp_mailing_lists[list_name] = False else: user.mailchimp_mailing_lists[list_name] = True finally: user.save()
def subscribe_mailchimp(list_name, user_id): user = User.load(user_id) m = get_mailchimp_api() list_id = get_list_id_from_name(list_name=list_name) if user.mailing_lists is None: user.mailing_lists = {} try: m.lists.subscribe( id=list_id, email={'email': user.username}, merge_vars={ 'fname': user.given_name, 'lname': user.family_name, }, double_optin=False, update_existing=True, ) except mailchimp.ValidationError as error: sentry.log_exception() sentry.log_message(error.message) user.mailing_lists[list_name] = False else: user.mailing_lists[list_name] = True finally: user.save()
def unsubscribe_mailchimp(list_name, user_id, username=None, send_goodbye=True): """Unsubscribe a user from a mailchimp mailing list given its name. :param str list_name: mailchimp mailing list name :param str user_id: current user's id :param str username: current user's email (required for merged users) :raises: ListNotSubscribed if user not already subscribed """ user = User.load(user_id) m = get_mailchimp_api() list_id = get_list_id_from_name(list_name=list_name) m.lists.unsubscribe(id=list_id, email={'email': username or user.username}, send_goodbye=send_goodbye) # Update mailing_list user field if user.mailchimp_mailing_lists is None: user.mailchimp_mailing_lists = {} user.save() user.mailchimp_mailing_lists[list_name] = False user.save()
def get_contributors(self, obj): contributor_info = [] if is_anonymized(self.context['request']): return contributor_info contributor_ids = obj.get('contributors', None) params_node = obj.get('node', None) if contributor_ids: for contrib_id in contributor_ids: user = User.load(contrib_id) unregistered_name = None if user.unclaimed_records.get(params_node): unregistered_name = user.unclaimed_records[params_node].get('name', None) contributor_info.append({ 'id': contrib_id, 'full_name': user.fullname, 'given_name': user.given_name, 'middle_names': user.middle_names, 'family_name': user.family_name, 'unregistered_name': unregistered_name, 'active': user.is_active }) return contributor_info
def get_contributors(self, obj): contributor_info = [] if is_anonymized(self.context["request"]): return contributor_info contributor_ids = obj.get("contributors", None) params_node = obj.get("node", None) if contributor_ids: for contrib_id in contributor_ids: user = User.load(contrib_id) unregistered_name = None if user.unclaimed_records.get(params_node): unregistered_name = user.unclaimed_records[params_node].get("name", None) contributor_info.append( { "id": contrib_id, "full_name": user.fullname, "given_name": user.given_name, "middle_names": user.middle_names, "family_name": user.family_name, "unregistered_name": unregistered_name, "active": user.is_active, } ) return contributor_info
def send_users_email(send_type): """Find pending Emails and amalgamates them into a single Email. :param send_type :return: """ grouped_emails = get_users_emails(send_type) if not grouped_emails: return for group in grouped_emails: user = User.load(group['user_id']) if not user: log_exception() continue info = group['info'] notification_ids = [message['_id'] for message in info] sorted_messages = group_by_node(info) if sorted_messages: mails.send_mail( to_addr=user.username, mimetype='html', mail=mails.DIGEST, name=user.fullname, message=sorted_messages, callback=remove_notifications(email_notification_ids=notification_ids) )
def send_digest(grouped_digests): """ Send digest emails and remove digests for sent messages in a callback. :param grouped_digests: digest notification messages from the past 24 hours grouped by user :return: """ for group in grouped_digests: user = User.load(group['user_id']) if not user: sentry.log_exception() sentry.log_message("A user with this username does not exist.") return info = group['info'] digest_notification_ids = [message['_id'] for message in info] sorted_messages = group_messages_by_node(info) if sorted_messages: logger.info('Sending email digest to user {0!r}'.format(user)) mails.send_mail( to_addr=user.username, mimetype='html', mail=mails.DIGEST, name=user.fullname, message=sorted_messages, callback=remove_sent_digest_notifications.si( digest_notification_ids=digest_notification_ids ) )
def authenticate(self, request): client = cas.get_client() # Returns a CAS server client try: auth_header_field = request.META["HTTP_AUTHORIZATION"] auth_token = cas.parse_auth_header(auth_header_field) except (cas.CasTokenError, KeyError): return None # If no token in header, then this method is not applicable # Found a token; query CAS for the associated user id try: cas_auth_response = client.profile(auth_token) except cas.CasHTTPError: raise exceptions.NotAuthenticated( _('User provided an invalid OAuth2 access token')) if cas_auth_response.authenticated is False: raise exceptions.NotAuthenticated( _('CAS server failed to authenticate this token')) user_id = cas_auth_response.user user = User.load(user_id) if user is None: raise exceptions.AuthenticationFailed( _('Could not find the user associated with this token')) check_user(user) return user, cas_auth_response
def test_send_digest_called_with_correct_args(self, mock_send_mail, mock_callback): d = factories.NotificationDigestFactory( user_id=factories.UserFactory()._id, timestamp=datetime.datetime.utcnow(), message='Hello', node_lineage=[factories.ProjectFactory()._id] ) d.save() user_groups = group_digest_notifications_by_user() send_digest(user_groups) assert_true(mock_send_mail.called) assert_equals(mock_send_mail.call_count, len(user_groups)) last_user_index = len(user_groups) - 1 user = User.load(user_groups[last_user_index]['user_id']) digest_notification_ids = [message['_id'] for message in user_groups[last_user_index]['info']] args, kwargs = mock_send_mail.call_args assert_equal(kwargs['to_addr'], user.username) assert_equal(kwargs['mimetype'], 'html') assert_equal(kwargs['mail'], mails.DIGEST) assert_equal(kwargs['name'], user.fullname) message = group_messages_by_node(user_groups[last_user_index]['info']) assert_equal(kwargs['message'], message) assert_equal(kwargs['callback'], mock_callback.si(digest_notification_ids=digest_notification_ids))
def send_users_email(send_type): """Find pending Emails and amalgamates them into a single Email. :param send_type :return: """ grouped_emails = get_users_emails(send_type) if not grouped_emails: return for group in grouped_emails: user = User.load(group['user_id']) if not user: log_exception() continue info = group['info'] notification_ids = [message['_id'] for message in info] sorted_messages = group_by_node(info) if sorted_messages: mails.send_mail(to_addr=user.username, mimetype='html', mail=mails.DIGEST, name=user.fullname, message=sorted_messages, callback=remove_notifications( email_notification_ids=notification_ids))
def before_request(): from framework.auth import authenticate from framework.auth.core import User from framework.auth import cas # Central Authentication Server Ticket Validation and Authentication ticket = request.args.get('ticket') if ticket: service_url = furl.furl(request.url) service_url.args.pop('ticket') # Attempt autn wih CAS, and return a proper redirect response return cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url) # Central Authentication Server OAuth Bearer Token authorization = request.headers.get('Authorization') if authorization and authorization.startswith('Bearer '): client = cas.get_client() try: access_token = cas.parse_auth_header(authorization) except cas.CasTokenError as err: # NOTE: We assume that the request is an AJAX request return jsonify({'message_short': 'Invalid Bearer token', 'message_long': err.args[0]}), http.UNAUTHORIZED cas_resp = client.profile(access_token) if cas_resp.authenticated: user = User.load(cas_resp.user) return authenticate(user, access_token=access_token, response=None) return make_response('', http.UNAUTHORIZED) if request.authorization: # TODO: Fix circular import from framework.auth.core import get_user user = get_user( email=request.authorization.username, password=request.authorization.password ) # Create empty session # TODO: Shoudn't need to create a session for Basic Auth session = Session() if user: session.data['auth_user_username'] = user.username session.data['auth_user_id'] = user._primary_key session.data['auth_user_fullname'] = user.fullname else: # Invalid key: Not found in database session.data['auth_error_code'] = http.FORBIDDEN set_session(session) return cookie = request.cookies.get(settings.COOKIE_NAME) if cookie: try: session_id = itsdangerous.Signer(settings.SECRET_KEY).unsign(cookie) session = Session.load(session_id) or Session(_id=session_id) set_session(session) return except: pass
def authenticate(self, request): cookie_val = request.COOKIES.get(settings.COOKIE_NAME) if not cookie_val: return None session = get_session_from_cookie(cookie_val) if not session: return None user_id = session.data.get('auth_user_id') user = User.load(user_id) if user: return user, None return None
def reject_draft(request, draft_pk): draft = get_draft_obj(draft_pk) # TODO[lauren]: add proper authorizers to DraftRegistrationApproval # need to pass self, user, and token # user should be the admin user = osf_user.load('dsmpw') draftRegistrationApproval = draft[0].approval draftRegistrationApproval.add_authorizer(user) token = draftRegistrationApproval.approval_state[user._id]['rejection_token'] draftRegistrationApproval.reject(user, token) draftRegistrationApproval.save() response = serialize_draft_registration_approval(draftRegistrationApproval) return HttpResponse(json.dumps(response), content_type='application/json')
def reject_draft(request, draft_pk): draft = get_draft_obj(draft_pk) # TODO[lauren]: add proper authorizers to DraftRegistrationApproval # need to pass self, user, and token # user should be the admin user = osf_user.load('dsmpw') draftRegistrationApproval = draft[0].approval draftRegistrationApproval.add_authorizer(user) token = draftRegistrationApproval.approval_state[ user._id]['rejection_token'] draftRegistrationApproval.reject(user, token) draftRegistrationApproval.save() response = serialize_draft_registration_approval(draftRegistrationApproval) return HttpResponse(json.dumps(response), content_type='application/json')
def unsubscribe_mailchimp(list_name, user_id): """Unsubscribe a user from a mailchimp mailing list given its name. :param str list_name: mailchimp mailing list name :param str username: current user's email :raises: ListNotSubscribed if user not already subscribed """ user = User.load(user_id) m = get_mailchimp_api() list_id = get_list_id_from_name(list_name=list_name) m.lists.unsubscribe(id=list_id, email={'email': user.username}) # Update mailing_list user field if user.mailing_lists is None: user.mailing_lists = {} user.save() user.mailing_lists[list_name] = False user.save()
def unsubscribe_mailchimp(list_name, user_id): """Unsubscribe a user from a mailchimp mailing list given its name. :param str list_name: mailchimp mailing list name :param str username: current user's email :raises: ListNotSubscribed if user not already subscribed """ user = User.load(user_id) m = get_mailchimp_api() list_id = get_list_id_from_name(list_name=list_name) m.lists.unsubscribe(id=list_id, email={"email": user.username}) # Update mailing_list user field if user.mailing_lists is None: user.mailing_lists = {} user.save() user.mailing_lists[list_name] = False user.save()
def authenticate(self, request): client = cas.get_client() # Returns a CAS server client try: auth_header_field = request.META["HTTP_AUTHORIZATION"] auth_token = cas.parse_auth_header(auth_header_field) except (cas.CasTokenError, KeyError): return None # If no token in header, then this method is not applicable # Found a token; query CAS for the associated user id try: resp = client.profile(auth_token) except cas.CasHTTPError: raise exceptions.NotAuthenticated('User provided an invalid OAuth2 access token') if resp.authenticated is False: raise exceptions.NotAuthenticated('CAS server failed to authenticate this token') user_id = resp.user user = User.load(user_id) if user is None: raise exceptions.AuthenticationFailed("Could not find the user associated with this token") return user, auth_token
def get_user(self, user_id): return User.load(user_id)
def before_request(): from framework import sentry from framework.auth import cas from framework.auth.core import User from framework.auth import authenticate from framework.routing import json_renderer # Central Authentication Server Ticket Validation and Authentication ticket = request.args.get('ticket') if ticket: service_url = furl.furl(request.url) service_url.args.pop('ticket') # Attempt autn wih CAS, and return a proper redirect response return cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url) # Central Authentication Server OAuth Bearer Token authorization = request.headers.get('Authorization') if authorization and authorization.startswith('Bearer '): client = cas.get_client() try: access_token = cas.parse_auth_header(authorization) cas_resp = client.profile(access_token) except cas.CasError as err: sentry.log_exception() # NOTE: We assume that the request is an AJAX request return json_renderer(err) if cas_resp.authenticated: user = User.load(cas_resp.user) return authenticate(user, access_token=access_token, response=None) return make_response('', http.UNAUTHORIZED) if request.authorization: # TODO: Fix circular import from framework.auth.core import get_user user = get_user(email=request.authorization.username, password=request.authorization.password) # Create empty session # TODO: Shoudn't need to create a session for Basic Auth session = Session() if user: session.data['auth_user_username'] = user.username session.data['auth_user_id'] = user._primary_key session.data['auth_user_fullname'] = user.fullname else: # Invalid key: Not found in database session.data['auth_error_code'] = http.FORBIDDEN set_session(session) return cookie = request.cookies.get(settings.COOKIE_NAME) if cookie: try: session_id = itsdangerous.Signer( settings.SECRET_KEY).unsign(cookie) session = Session.load(session_id) or Session(_id=session_id) set_session(session) return except: pass
from utils import submodule_path import sys sys.path.insert(0, submodule_path('utils.py')) from website.project.model import MetaSchema, DraftRegistration, Node, DraftRegistrationApproval from framework.mongo.utils import get_or_http_error from framework.auth.core import User from framework.auth import Auth from website.project.metadata.utils import serialize_meta_schema, serialize_draft_registration from website.app import do_set_backends, init_addons from website import settings as osf_settings import utils init_addons(osf_settings, routes=False) do_set_backends(osf_settings) adminUser = User.load('dsmpw') def get_all_drafts(): # TODO[lauren]: add query parameters to only retrieve submitted drafts, they will have an approval associated with them all_drafts = DraftRegistration.find() auth = Auth(adminUser) serialized_drafts = { 'drafts': [utils.serialize_draft_registration(d, auth) for d in all_drafts] } return serialized_drafts
from utils import submodule_path import sys sys.path.insert(0, submodule_path('utils.py')) from website.project.model import MetaSchema, DraftRegistration, Node from framework.mongo.utils import get_or_http_error from framework.auth.core import User from framework.auth import Auth from website.project.metadata.utils import serialize_meta_schema, serialize_draft_registration from website.app import do_set_backends, init_addons from website import settings as osf_settings import utils init_addons(osf_settings, routes=False) do_set_backends(osf_settings) adminUser = User.load('dsmpw') def get_mongo_client(): """Create MongoDB client and authenticate database. """ client = pymongo.MongoClient(osf_settings.DB_HOST, osf_settings.DB_PORT) db = client[osf_settings.DB_NAME] if osf_settings.DB_USER and osf_settings.DB_PASS: db.authenticate(osf_settings.DB_USER, osf_settings.DB_PASS) return client client = get_mongo_client()
def get_user(self, user_id): try: user = OSFUser.objects.get(id=user_id) except OSFUser.DoesNotExist: user = User.load(user_id) return user
def before_request(): from framework.auth import authenticate from framework.auth.core import User from framework.auth import cas # Central Authentication Server Ticket Validation and Authentication ticket = request.args.get('ticket') if ticket: service_url = furl.furl(request.url) service_url.args.pop('ticket') # Attempt autn wih CAS, and return a proper redirect response return cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url) # Central Authentication Server OAuth Bearer Token authorization = request.headers.get('Authorization') if authorization and authorization.startswith('Bearer '): client = cas.get_client() try: access_token = cas.parse_auth_header(authorization) except cas.CasTokenError as err: # NOTE: We assume that the request is an AJAX request return jsonify({ 'message_short': 'Invalid Bearer token', 'message_long': err.args[0] }), http.UNAUTHORIZED cas_resp = client.profile(access_token) if cas_resp.authenticated: user = User.load(cas_resp.user) return authenticate(user, access_token=access_token, response=None) return make_response('', http.UNAUTHORIZED) if request.authorization: # Create a session from the API key; if key is # not valid, save the HTTP error code in the # "auth_error_code" field of session.data # Create empty session session = Session() # Hack: Avoid circular import from website.project.model import ApiKey api_label = request.authorization.username api_key_id = request.authorization.password api_key = ApiKey.load(api_key_id) if api_key: user = api_key.user__keyed and api_key.user__keyed[0] node = api_key.node__keyed and api_key.node__keyed[0] session.data['auth_api_label'] = api_label session.data['auth_api_key'] = api_key._primary_key if user: session.data['auth_user_username'] = user.username session.data['auth_user_id'] = user._primary_key session.data['auth_user_fullname'] = user.fullname elif node: session.data['auth_node_id'] = node._primary_key else: # Invalid key: Not attached to user or node session.data['auth_error_code'] = http.FORBIDDEN else: # Invalid key: Not found in database session.data['auth_error_code'] = http.FORBIDDEN set_session(session) return cookie = request.cookies.get(settings.COOKIE_NAME) if cookie: try: session_id = itsdangerous.Signer( settings.SECRET_KEY).unsign(cookie) session = Session.load(session_id) or Session(_id=session_id) set_session(session) return except: pass ## TODO: Create session in before_request, cookie in after_request ## Retry request, preserving status code #response = redirect(request.path, code=307) return create_session(None)
def before_request(): from framework.auth import authenticate from framework.auth.core import User from framework.auth import cas # Central Authentication Server Ticket Validation and Authentication ticket = request.args.get('ticket') if ticket: service_url = furl.furl(request.url) service_url.args.pop('ticket') # Attempt autn wih CAS, and return a proper redirect response return cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url) # Central Authentication Server OAuth Bearer Token authorization = request.headers.get('Authorization') if authorization and authorization.startswith('Bearer '): client = cas.get_client() try: access_token = cas.parse_auth_header(authorization) except cas.CasTokenError as err: # NOTE: We assume that the request is an AJAX request return jsonify({'message_short': 'Invalid Bearer token', 'message_long': err.args[0]}), http.UNAUTHORIZED cas_resp = client.profile(access_token) if cas_resp.authenticated: user = User.load(cas_resp.user) return authenticate(user, access_token=access_token, response=None) return make_response('', http.UNAUTHORIZED) if request.authorization: # Create a session from the API key; if key is # not valid, save the HTTP error code in the # "auth_error_code" field of session.data # Create empty session session = Session() # Hack: Avoid circular import from website.project.model import ApiKey api_label = request.authorization.username api_key_id = request.authorization.password api_key = ApiKey.load(api_key_id) if api_key: user = api_key.user__keyed and api_key.user__keyed[0] node = api_key.node__keyed and api_key.node__keyed[0] session.data['auth_api_label'] = api_label session.data['auth_api_key'] = api_key._primary_key if user: session.data['auth_user_username'] = user.username session.data['auth_user_id'] = user._primary_key session.data['auth_user_fullname'] = user.fullname elif node: session.data['auth_node_id'] = node._primary_key else: # Invalid key: Not attached to user or node session.data['auth_error_code'] = http.FORBIDDEN else: # Invalid key: Not found in database session.data['auth_error_code'] = http.FORBIDDEN set_session(session) return cookie = request.cookies.get(settings.COOKIE_NAME) if cookie: try: session_id = itsdangerous.Signer(settings.SECRET_KEY).unsign(cookie) session = Session.load(session_id) or Session(_id=session_id) set_session(session) return except: pass ## TODO: Create session in before_request, cookie in after_request ## Retry request, preserving status code #response = redirect(request.path, code=307) return create_session(None)