def __init__(self, loop): self.loop = loop self.signer = itsdangerous.Signer(os.environ['GENREML_SIGNING_TOKEN']) self.session_signer = itsdangerous.Signer( os.environ['SESSION_SIGNING_TOKEN']) self.serializer = itsdangerous.Serializer( os.environ['GENREML_SIGNING_TOKEN']) self.filestore_directory = "/opt/file_store" self.genres = os.environ['GENREML_GENRES'].split('|') self.model_hash = os.environ['GENREML_MODEL_HASH'] self.image_labels_to_title = { "image_mel_spectrogram_grayscale_original": "Mel Spectrogram", "image_mel_spectrogram_image": "Mel Spectrogram", "image_mel_spectrogram_original_color": "Mel Spectrogram", "image_chromagram_grayscale_original": "Chromagram", "image_chromagram_image": "Chromagram", "image_chromagram_original_color": "Chromagram", "image_db_spectrogram_grayscale_original": "DB Spectrogram", "image_db_spectrogram_image": "DB Spectrogram", "image_db_spectrogram_original_color": "DB Spectrogram" } self.prediction_queue = asyncio.Queue() self.spectrograms_queue = asyncio.Queue() self.batch_store = dict() self.predictor_connections = dict() self.spectrogram_connections = dict()
def create_session(response, data=None): current_session = get_session() if current_session: current_session.data.update(data or {}) current_session.save() cookie_value = itsdangerous.Signer(settings.SECRET_KEY).sign(current_session._id) else: session_id = str(bson.objectid.ObjectId()) session = Session(_id=session_id, data=data or {}) session.save() cookie_value = itsdangerous.Signer(settings.SECRET_KEY).sign(session_id) set_session(session) if response is not None: response.set_cookie(settings.COOKIE_NAME, value=cookie_value, domain=settings.OSF_COOKIE_DOMAIN) return response
def create_signer(secret_key, salt): """Create a signer configured how we like it. The secret_key should be a cyptographically random key. The salt should be specific to intend usage of the signature, but does not need to be random. It acts to partition signatures between use cases that shared the same secret_key. The length of secret_key and salt together should be more than the digest size, which for sha256 is 32 bytes. See https://itsdangerous.palletsprojects.com/en/2.0.x/concepts/ for more info. Ideally, we'd use cryptography for this, but that's a much heavier dependency than itsdangerous, which is pure python.""" value = secret_key if salt is not None: value += salt assert len( value.encode("utf8")) > 32, "secret_key+salt needs to be > 32 bytes" return itsdangerous.Signer( secret_key=secret_key, salt=salt, key_derivation="hmac", # would like to use HDKF, but not supported digest_method=hashlib.sha256, )
def test_login0(client): """Test login from orcid.""" resp = client.get("/login0") assert resp.status_code == 401 u = User.select().where(User.orcid.is_null(False)).first() email = u.email import itsdangerous signature = itsdangerous.Signer( client.application.secret_key).get_signature(email).decode() auth = email + ':' + signature resp = client.get(f"/login0/{auth}") assert resp.status_code == 302 assert current_user.email == email resp = client.get("/login0", headers={"Authorization": auth}) assert resp.status_code == 302 assert current_user.email == email from base64 import b64encode resp = client.get( "/login0", headers={"Authorization": b64encode(auth.encode()).decode()}) assert resp.status_code == 302 assert current_user.email == email
def __init__(self, secret_key, *, cookie_name="AIOHTTP_SESSION", domain=None, max_age=None, path="/", secure=None, httponly=True, encoder=json.dumps, decoder=json.loads): super().__init__( cookie_name=cookie_name, domain=domain, max_age=max_age, path=path, secure=secure, httponly=httponly, encoder=encoder, decoder=decoder, ) if isinstance(secret_key, str): pass elif isinstance(secret_key, (bytes, bytearray)): secret_key = base64.urlsafe_b64encode(secret_key) self._s = itsdangerous.Signer(secret_key)
def get_or_create_cookie(self, secret=None): """Find the cookie for the given user Create a new session if no cookie is found :param str secret: The key to sign the cookie with :returns: The signed cookie """ secret = secret or settings.SECRET_KEY sessions = Session.find( Q('data.auth_user_id', 'eq', self._id) ).sort( '-date_modified' ).limit(1) if sessions.count() > 0: user_session = sessions[0] else: user_session = Session(data={ 'auth_user_id': self._id, 'auth_user_username': self.username, 'auth_user_fullname': self.fullname, }) user_session.save() signer = itsdangerous.Signer(secret) return signer.sign(user_session._id)
def __init__(self, loop): self.loop = loop self.model_hash_registry = dict() self.model_dir = '/opt/model_store' self.temp_file_lock = asyncio.Lock() self.signer = itsdangerous.Signer(os.environ['SIGNING_TOKEN']) self.serializer = itsdangerous.Serializer(os.environ['SIGNING_TOKEN'])
def __init__(self, app: ASGIApp, secret_key: str, session_cookie: str = "session") -> None: self.app = app self.signer = itsdangerous.Signer(secret_key) self.session_cookie = session_cookie
def before_request(): # TODO: Fix circular import from framework.auth.core import get_user from framework.auth import cas from website.util import time as util_time # 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 to authenticate wih CAS, and return a proper redirect response return cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url) if request.authorization: user = get_user(email=request.authorization.username, password=request.authorization.password) # Create an empty session # TODO: Shoudn't need to create a session for Basic Auth user_session = Session() set_session(user_session) if user: user_addon = user.get_addon('twofactor') if user_addon and user_addon.is_confirmed: otp = request.headers.get('X-OSF-OTP') if otp is None or not user_addon.verify_code(otp): # Must specify two-factor authentication OTP code or invalid two-factor authentication OTP code. user_session.data['auth_error_code'] = http.UNAUTHORIZED return user_session.data['auth_user_username'] = user.username user_session.data['auth_user_id'] = user._primary_key user_session.data['auth_user_fullname'] = user.fullname else: # Invalid key: Not found in database user_session.data['auth_error_code'] = http.UNAUTHORIZED return cookie = request.cookies.get(settings.COOKIE_NAME) if cookie: try: session_id = itsdangerous.Signer( settings.SECRET_KEY).unsign(cookie) user_session = Session.load(session_id) or Session(_id=session_id) except itsdangerous.BadData: return if not util_time.throttle_period_expired(user_session.date_created, settings.OSF_SESSION_TIMEOUT): if user_session.data.get( 'auth_user_id') and 'api' not in request.url: database['user'].update( {'_id': user_session.data.get('auth_user_id')}, {'$set': { 'date_last_login': datetime.utcnow() }}, w=0) set_session(user_session) else: remove_session(user_session)
def verify_state(state): """Verify the state GitHub returned is valid See `generate_state` for how this is verified """ signer = itsdangerous.Signer(os.environ['STATE_KEY']) return signer.validate(state)
def create_session(response, data=None): Session = apps.get_model('osf.Session') current_session = get_session() if current_session: current_session.data.update(data or {}) current_session.save() cookie_value = itsdangerous.Signer(settings.SECRET_KEY).sign(current_session._id) else: session_id = str(bson.objectid.ObjectId()) new_session = Session(_id=session_id, data=data or {}) new_session.save() cookie_value = itsdangerous.Signer(settings.SECRET_KEY).sign(session_id) set_session(new_session) if response is not None: response.set_cookie(settings.COOKIE_NAME, value=cookie_value, domain=settings.OSF_COOKIE_DOMAIN, secure=settings.SESSION_COOKIE_SECURE, httponly=settings.SESSION_COOKIE_HTTPONLY) return response
def before_request(): 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 setUp(self): super(TestAddonLogs, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon()
def test_cookie_has_admin(self): session = Session(data={'auth_user_id': self.user._id}) session.save() cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(session._id) self.app.set_cookie(settings.COOKIE_NAME, str(cookie)) res = self.app.get(self.url) assert_equal(res.status_code, 200) assert_equal(res.json['meta']['admin'], True)
def setUp(self): super(TestSloanMetrics, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.preprint = PreprintFactory(creator=self.user, is_public=True) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id).decode() self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8'))
def api_login(): data = {"status": "error"} if flask.request.is_json: json = flask.request.get_json() username = json.get('username', None) password = json.get('password', None) validate_code = json.get('validate_code', None) if not validate_code: data["reason"] = "no_validate_code" return flask.jsonify(data) if not check_validate_code(validate_code): data["reason"] = "error_validate_code" return flask.jsonify(data) if username == '': username = "******" if username: user_info = self.check_user_password(username, password) if user_info: uid = str(uuid.uuid1()) signed_uid = itsdangerous.Signer(user_info.password, salt='LoginChecker:uid').sign( uid.encode(errors='ignore')).decode( errors='ignore') self.signed_uid = signed_uid self.username = username self.uid = uid self.is_admin = user_info.is_admin self.user_id = user_info.id self.role = user_info.role if use_mongoengine: user_login_data = UserLoginData(uid=uid, user=user_info, username=username, timestamp=int(time.time() * 1e3), datetime=datetime.now(), utc_datetime=datetime.utcnow()) user_login_data.save() logger.info("<username=%s,uid=%s> save login with mongodb" % (username, uid)) elif use_peewee: with db.execution_context(): UserLoginData.create(uid=uid, user=user_info, username=username, timestamp=int(time.time() * 1e3), datetime=datetime.now(), utc_datetime=datetime.utcnow()) logger.info("<username=%s,uid=%s> save login with peewee" % (username, uid)) data["status"] = "ok" data["username"] = self.username data["is_admin"] = self.is_admin data["role"] = self.role data["uid"] = self.signed_uid data["_csrf_token"] = get_csrf_token() resp = flask.make_response(flask.jsonify(data)) self.save_login_info_to_cookie(resp) return resp data["reason"] = "error_user" else: data["reason"] = "no_json" return flask.jsonify(data)
def setUp(self): super(TestAddonAuth, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8'))
def get_user_from_cookie(cookie): if not cookie: return None try: token = itsdangerous.Signer(settings.SECRET_KEY).unsign(cookie) except itsdangerous.BadSignature: raise HTTPError(httplib.UNAUTHORIZED) session = Session.load(token) if session is None: raise HTTPError(httplib.UNAUTHORIZED) return User.load(session.data['auth_user_id'])
def generate_signed_id(secret): ''' Generate a unique ID with a signature. We want this to include date for sorting, be a valid ISO-8601 datetime, and to use a big random number for fake nanosecond accuracy to increase likelihood of uniqueness. ''' now, nsec = datetime.datetime.utcnow(), random.randint(0, 999999999) identifier = '{}.{:09d}Z'.format(now.strftime('%Y%m%dT%H%M%S'), nsec) signer = itsdangerous.Signer(secret) return identifier, signer.sign(identifier.encode('utf8')).decode('utf8')
def setUp(self): super(TestAddonAuth, self).setUp() self.flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='127.0.0.1') self.test_app = webtest.TestApp(self.flask_app) self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon()
def socketio(remaining): real_request = request._get_current_object() # add redis connection real_request._conn = get_connection() real_request._data_root = current_app.config.get('DATA_ROOT') real_request._signer = itsdangerous.Signer(current_app.secret_key) socketio_manage(request.environ, { '/status': StatusNamespace, '/build': BuildNamespace, }, request=real_request) return Response()
def setUp(self): super(TestUserLastLoginDate, self).setUp() self.user = AuthUserFactory() self.session = SessionFactory( data={ 'auth_user_id': self.user._id, 'auth_user_username': self.user.username } ) self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id).decode()
def before_request(): 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 resp = cas.make_response_from_ticket(ticket=ticket, service_url=service_url.url) if request.cookies.get(settings.COOKIE_NAME): # TODO: Delete legacy cookie, this special case can be removed anytime after 1/1/2016. # A cookie is received which could potentially be a legacy (pre multi-domain) cookie. # Issuing a targeted delete of the legacy cookie ensures the user does not end up in a # login loop whereby both cookies are sent to the server and one of them at random # read for authentication. resp.delete_cookie(settings.COOKIE_NAME, domain=None) return resp 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 user.date_last_login = datetime.utcnow() user.save() 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) except itsdangerous.BadData: return if session.data.get('auth_user_id'): database['user'].update({'_id': session.data.get('auth_user_id')}, {'$set': {'date_last_login': datetime.utcnow()}}, w=0) set_session(session)
def __init__(self, loop): self.loop = loop self.uid = str(uuid.uuid4()) self.model_hash_registry = dict() self.model_dir = '/opt/model_store' self.temp_file_lock = asyncio.Lock() self.signer = itsdangerous.Signer(os.environ['SIGNING_TOKEN']) self.serializer = itsdangerous.Serializer(os.environ['SIGNING_TOKEN']) self.model_hash = os.environ['GENREML_MODEL_HASH'] self.model_path = self.get_model_path(self.model_hash) if not self.check_model_hash(self.model_hash) is True: eprint("model not found during init")
def lambda_handler(event, context): ''' ''' s3 = boto3.client('s3', endpoint_url=constants.S3_ENDPOINT_URL) query = util.event_query_args(event) website_base = constants.WEBSITE_BASE try: id = itsdangerous.Signer(constants.SECRET).unsign( query['id']).decode('utf8') except itsdangerous.BadSignature: return { 'statusCode': '400', 'headers': { 'Access-Control-Allow-Origin': '*' }, 'body': 'Bad ID' } if query.get('incumbency') == 'yes': rules = { rule.endpoint: str(rule) for rule in website.app.url_map.iter_rules() } redirect_url = urllib.parse.urljoin(website_base, rules['get_incumbency']) return { 'statusCode': '302', 'headers': { 'Location': redirect_url }, 'body': '' } upload = create_upload(s3, query['bucket'], query['key'], id) redirect_url = get_redirect_url(website_base, id) event = dict(bucket=query['bucket']) event.update(upload.to_dict()) lam = boto3.client('lambda', endpoint_url=constants.LAMBDA_ENDPOINT_URL) lam.invoke(FunctionName=after_upload.FUNCTION_NAME, InvocationType='Event', Payload=json.dumps(event).encode('utf8')) return { 'statusCode': '302', 'headers': { 'Location': redirect_url }, 'body': '' }
def test_cookied_requests_can_create_and_email(self, mock_mail, app, user, email_unconfirmed, data, url_base): session = Session(data={'auth_user_id': user._id}) session.save() cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(session._id) app.set_cookie(settings.COOKIE_NAME, str(cookie)) assert OSFUser.objects.filter(username=email_unconfirmed).count() == 0 res = app.post_json_api('{}?send_email=true'.format(url_base), data) assert res.status_code == 201 assert OSFUser.objects.filter(username=email_unconfirmed).count() == 1 assert mock_mail.call_count == 1
def is_login(self): if self.username is None: username = flask.request.cookies.get('MEMBER_LOGIN', None) signed_uid = flask.request.cookies.get('UID', None) if username and signed_uid and (use_mongoengine or use_peewee): user_info = self.get_user_info(username) if user_info: try: uid = itsdangerous.Signer(user_info.password, salt='LoginChecker:uid').unsign( signed_uid).decode( errors='ignore') except itsdangerous.BadData: return False if use_mongoengine: user_login_data = UserLoginData.objects(uid=uid, user=user_info.id, username=username).first() if user_login_data: self.is_admin = user_info.is_admin self.username = username self.uid = uid self.signed_uid = signed_uid self.user_id = user_info.id self.role = user_info.role user_login_data.timestamp = int(time.time() * 1e3) user_login_data.datetime = datetime.now() user_login_data.utc_datetime = datetime.utcnow() user_login_data.save() logger.info("<username=%s,uid=%s> pass login with mongodb" % (username, uid)) return True return False elif use_peewee: with db.execution_context(): user_login_data = UserLoginData.get(UserLoginData.uid == uid, UserLoginData.user == user_info.id, UserLoginData.username == username) if user_login_data: self.is_admin = user_info.is_admin self.username = username self.uid = uid self.signed_uid = signed_uid self.user_id = user_info.id self.role = user_info.role user_login_data.timestamp = int(time.time() * 1e3) user_login_data.datetime = datetime.now() user_login_data.utc_datetime = datetime.utcnow() user_login_data.save() logger.info("<username=%s,uid=%s> pass login with peewee" % (username, uid)) return True return False return False return False return True
def get_session_from_cookie(cookie_val): """ Given a cookie value, return the `Session` object or `None`. :param cookie_val: the cookie :return: the `Session` object or None """ session_id = itsdangerous.Signer(settings.SECRET_KEY).unsign(cookie_val) try: session = Session.objects.get(_id=session_id) return session except Session.DoesNotExist: return None
def test_cookied_requests_can_create_and_email(self, mock_mail): session = Session(data={'auth_user_id': self.user._id}) session.save() cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(session._id) self.app.set_cookie(settings.COOKIE_NAME, str(cookie)) assert_equal( User.find(Q('username', 'eq', self.unconfirmed_email)).count(), 0) res = self.app.post_json_api( '{}?send_email=true'.format(self.base_url), self.data) assert_equal(res.status_code, 201) assert_equal( User.find(Q('username', 'eq', self.unconfirmed_email)).count(), 1) assert_equal(mock_mail.call_count, 1)
def _get_signer(self): if not self._secret_key: apm.capture_message('Secret key not set.') logger.error({'message': 'Secret key not set.'}) return None if not self._salt: apm.capture_message('Salt not set.') logger.error({'message': 'Salt not set.'}) return None return itsdangerous.Signer( secret_key=self._secret_key, salt=self._salt, key_derivation='hmac' )