def save_request(self, user): try: db = AuthToken.objects.get(user=user, service=self.service) except AuthToken.DoesNotExist: db = AuthToken(user=user, service=self.service) db.save() return db.pk
def _get_auth_token(self): """Get AuthorizationToken. Actually gets the authorization token and secret from the service. The token and secret are stored in our database, and the auth token is returned. """ response = self.make_request(self.request_url) result = self._extract_credentials(response) auth_token = result["token"] auth_secret = result["secret"] # Save the auth token and secret in our database. auth = AuthToken(service=self.service_name, token=auth_token, secret=auth_secret) auth.put() # Add the secret to memcache as well. memcache.set(self._get_memcache_auth_key(auth_token), auth_secret, time=20*60) return auth_token
def test_token_generation(self): from models import AuthToken # we want each token to be different as the same user can have more than one if they have multiple devices token = AuthToken.gen_token_string('[email protected]') same_token = AuthToken.gen_token_string('[email protected]') different_token = AuthToken.gen_token_string('[email protected]') self.assertIs(False, token == same_token) self.assertIs(False, token == different_token)
def post(self, action=None, **kwargs): if action == 'get_auth_url': auth_url, oauth_token, oauth_token_secret =\ User.get_auth_url() # TODO: Use redis? # app.db['auth_tokens'].insert({ # 'oauth_token': oauth_token, # 'oauth_token_secret': oauth_token_secret, # }) auth = AuthToken(oauth_token, oauth_token_secret) auth.save() logging.debug("User Auth: oauth token %s added", oauth_token) return self._render({'auth_url': auth_url}) if action == 'authenticate': parser = reqparse.RequestParser() parser.add_argument('oauth_token', type=str) parser.add_argument('oauth_verifier', type=str) params = parser.parse_args() oauth_token = params.get('oauth_token') oauth_verifier = params.get('oauth_verifier') logging.debug("User Auth: trying to authenticate with token %s", oauth_token) # TODO: Use redis? auth = AuthToken.get_auth(oauth_token) if not auth: logging.error('User Auth: token %s not found', oauth_token) return odesk_error_response( 500, 500, 'Wrong token: {0!s}'.format(oauth_token)) oauth_token_secret = auth.get('oauth_token_secret') auth_token, user = User.authenticate(oauth_token, oauth_token_secret, oauth_verifier) logging.debug('User Auth: Removing token %s', oauth_token) AuthToken.delete(auth.get('oauth_token')) return self._render({'auth_token': auth_token, 'user': user}) if action == 'get_user': user = getattr(request, 'user', None) if user: return self._render({'user': user}) return odesk_error_response(401, 401, 'Unauthorized') logging.error('User Auth: invalid action %s', action) raise NotFound('Action not found')
def my_ranking_weekly(request): from models import UserStats week = request.GET.get('week') token_param = request.GET.get('token') if not AuthToken.is_token_valid(token_param) and settings.DEBUG is False: return JsonResponse({'status': 'INVALID_TOKEN'}) token = AuthToken.objects.get(token_string=token_param) if week: try: week = datetime.strptime(week, '%m-%d-%Y') except: return JsonResponse({'status': 'ILLEGAL_DATE_FORMAT'}) ranking_list = [] for ranking, user, total_steps, isUser in UserStats.get_weekly_ranking(token.user, week): all_time_stats = UserStats.get_all_time_stats(user) prestige, challenge_progress = divmod(all_time_stats.get('all_time_steps'), 100) ranking_list.append({'name': user.public_name, 'id': user.pk, 'prestige': prestige, 'total_steps': total_steps, 'isUser': isUser, 'ranking': ranking, }) return JsonResponse({'status': 'OK', 'ranking': ranking_list, })
def my_ranking_all_time(request): from models import UserStats token_param = request.GET.get('token') if not AuthToken.is_token_valid(token_param) and settings.DEBUG is False: return JsonResponse({'status': 'INVALID_TOKEN'}) token = AuthToken.objects.get(token_string=token_param) ranking_list = [] for ranking, user, total_steps, isUser in UserStats.get_all_time_ranking(token.user): prestige, challenge_progress = divmod(total_steps, 100) ranking_list.append({'name': user.public_name, 'id': user.pk, 'prestige': prestige, 'total_steps': total_steps, 'isUser': isUser, 'ranking': ranking, }) return JsonResponse({'status': 'OK', 'ranking': ranking_list, })
def authorized(): if request.method == 'POST': token = AuthToken.objects.get(id=request.form['revoke']) token.delete() #todo: delete client if no outstanding tokens tokens = AuthToken.objects() return render_template('authorized.html', tokens=tokens)
def wrapper(*args, **kwargs): auth = request.headers.get('Authorization', None) if not auth: return not_authenticated() else: token = auth.split('Bearer ')[-1] if not AuthToken.verify(token): return not_authenticated() return f(*args, **kwargs)
def get(self): self.response.headers['Content-Type'] = 'application/json' auth = self.request.params.get('auth') or self.session.get('auth') if auth: auth_token = AuthToken.query(AuthToken.token == auth).get() auth_token.key.delete() if self.session.get('auth'): self.session['auth'] = None logging.info('removed auth token %s ' % auth) result = {'message': 'logout success'} self.response.out.write(json.dumps(result))
def post(self): self.response.headers['Content-Type'] = 'application/json' login_data = json.loads(self.request.body) username = login_data.get('username') password = login_data.get('password') account = Account.query(Account.username == username, Account.password == password).get() if account: self.session['auth'] = uuid.uuid1().hex token = AuthToken.query(AuthToken.account == account.key, ancestor=account.key).get() if token: token.token = self.session['auth'] else: token = AuthToken(account=account.key, token=self.session['auth'], parent=account.key) token.put() result = {'auth': token.token, 'account_id': account.key.id(), 'username': account.username} self.response.out.write(json.dumps(result)) else: result = {'error': 'Invalid credentials', 'message': 'Invalid credentials'} self.response.set_status(401, json.dumps(result)) self.response.out.write(json.dumps(result))
def test_send_mail(self): from models import AuthToken, User from django.core import mail u = User() u.email = '*****@*****.**' u.save() auth = AuthToken() auth.user = u auth.token = AuthToken.gen_token_string('*****@*****.**') auth.gen_validation_key() auth.send_validation_mail(settings.PUBLIC_URL) self.assertEqual(len(mail.outbox), 1, msg='is settings.EMAILS_ENABLED set to True ?')
def test_my_ranking_weekly(self): from models import User, AuthToken, UserStats from django.test import RequestFactory from django.core.urlresolvers import reverse from views import my_ranking_weekly users = [] for i in range(10): u = User() u.email = '*****@*****.**' + str(i) u.public_name = 'TEST' + str(i) u.save() users.append(u) UserStats.record_stats(u, i * 100, datetime.date.today()) auth = AuthToken() auth.token_string = AuthToken.gen_token_string('*****@*****.**') auth.user = users[9] auth.valid = True auth.save() factory = RequestFactory() rq = factory.get(reverse('my_ranking_weekly'), data={'token': auth.token_string}) response = my_ranking_weekly(rq) data = json.loads(response.content) self.assertEqual(data['status'], 'OK')
def test_update_profile(self): from models import User, AuthToken from django.test import RequestFactory from django.core.urlresolvers import reverse from views import update_profile u = User() u.email = '*****@*****.**' u.public_name = 'TEST' u.save() auth = AuthToken() auth.token_string = AuthToken.gen_token_string('*****@*****.**') auth.user = u auth.valid = True auth.save() factory = RequestFactory() rq = factory.get(reverse('update_profile'), data={ 'token': auth.token_string, 'nickname': 'El Nicknamo' }) response = update_profile(rq) data = json.loads(response.content) self.assertEqual(data['status'], 'OK') u = User.objects.get(pk=u.pk) self.assertEqual(u.public_name, 'El Nicknamo')
def inner(*args, **kwargs): handler = args[0] account_id = kwargs.get('account_id') auth = handler.request.params.get('auth') or handler.session.get('auth') if auth: account = Account.get_by_id(int(account_id)) auth_token = AuthToken.query(AuthToken.token == auth, ancestor=account.key).get() if auth_token and auth_token.account.id() == int(account_id): ret = func(*args, **kwargs) return ret handler.response.headers['Content-Type'] = 'application/json' handler.response.set_status(401, 'Not Authenticated') handler.response.out.write(json.dumps({'error': 'Not Authenticated'}))
def create(name, expiry): """Create a token for authentication to REST API.""" try: token = AuthToken(name=name, token=str(base64.urlsafe_b64encode(os.urandom(18)), "utf-8"), expiration=datetime.datetime.utcnow() + datetime.timedelta(days=expiry)) db.session.add(token) db.session.commit() print(f'NAME:\t {token.name:}') print(f'TOKEN:\t {token.token}') print(f'EXPIRY:\t {token.expiration}') except exc.IntegrityError: print(f'ERROR: Couldn\'t create token. Token with name {name!r} already exists.')
def save_token(token_data, request, *args, **kwargs): client = load_client(request.client.client_id) # make sure that every client has only one token existing_tokens = AuthToken.objects(client=client) for token in existing_tokens: token.delete() expires_in = token_data.pop('expires_in') expires = datetime.utcnow() + timedelta(seconds=expires_in) token = AuthToken() token.access_token = token_data['access_token'] #token.refresh_token=token_data['refresh_token'] token.token_type = token_data['token_type'] token._scopes = urllib.unquote_plus(token_data['scope']) token.expires = expires token.client = client token.save() return token
def test_token(self, delete_mock, get_mock, put_mock): TOKEN = '394c46b8902fb5e8fc9268f3cfd84539' SECRET = '394c46b8902fb5e8fc9268f3cfd84538' token_dict = dict(oauth_token=TOKEN, oauth_token_secret=SECRET, id=TOKEN) token = AuthToken(oauth_token=TOKEN, oauth_token_secret=SECRET) self.assertEquals(token.to_dict(), token_dict) token.save() put_mock.assert_called_with(token.TABLE_NAME, token_dict) get_mock.return_value = None self.assertEquals(AuthToken.get_auth('invalid'), None) # get_item get_mock.return_value = token_dict self.assertEquals(AuthToken.get_auth(TOKEN), token_dict) # delete AuthToken.delete(TOKEN) delete_mock.assert_called_with(token.TABLE_NAME, id=TOKEN) get_mock.return_value = None self.assertEquals(AuthToken.get_auth('invalid'), None)
def post(self): user = get_user_from_http_auth() if not user: logger.debug("no user returned: %s" % user) print "no user returned" abort(401) if not login_user(user): logger.debug("couldn't log user in: %s" % user) print "couldn't log user in" abort(401) token = AuthToken.create_token_for_user(user) base64_token = b64encode(token.token) resp = jsonify({'token': base64_token, 'newtoken': token.created, 'created': token.created, 'expires': token.expires}) return resp
def post(): if request.headers['Content-Type'] != 'application/octet-stream': return {'error': "Unsupported Media Type"}, 415 now = datetime.datetime.now() auth = request.headers.get('Authorization', None) token = auth.split('Bearer ')[-1] source = AuthToken.verify(token) log = Log(source=source) log.save() path = destination_path(now, source) background.run(upload_log, (request.get_data(), path)) response = log_schema.dump(log).data return response, 201
def test_token_validation(self): from models import AuthToken, User u = User() u.email = 'rururur' u.save() auth = AuthToken() auth.user = u auth.token = AuthToken.gen_token_string(email='[email protected]') auth.gen_validation_key() self.assertIsNotNone(auth.validation_key) self.assertFalse(auth.valid) self.assertIs(True, auth.validate(auth.validation_key)) self.assertIs(True, auth.valid)
def log_distance(request): from models import UserStats token_param = request.GET.get('token') if not AuthToken.is_token_valid(token_param) and settings.DEBUG is False: return JsonResponse({'status': 'INVALID_TOKEN'}) steps = request.GET.get('steps') if not steps: HttpResponseBadRequest('steps parameter is required') steps = int(steps) token = AuthToken.objects.get(token_string=token_param) user = token.user UserStats.record_stats(user, steps) return JsonResponse({'status': 'OK'})
def test_log_distance(self): from models import User, AuthToken, Level, StairWell from django.test import RequestFactory from django.core.urlresolvers import reverse from views import log_distance, distance, profile u = User() u.email = '*****@*****.**' u.public_name = 'TEST' u.save() auth = AuthToken() auth.token_string = AuthToken.gen_token_string('*****@*****.**') auth.user = u auth.valid = True auth.save() sw = StairWell(building='ASP', shaft='south') sw.save() level1 = Level(stairwell=sw, floorNumber=1) level1.save() level2 = Level(stairwell=sw, floorNumber=2) level2.save() factory = RequestFactory() rq = factory.get(reverse('distance'), data={ 'qr_id_1': level1.pk, 'qr_id_2': level2.pk }) response = distance(rq) data = json.loads(response.content) self.assertEqual(data['distance'], 18) rq = factory.get(reverse('log_distance'), data={ 'token': auth.token_string, 'steps': 18 }) response = log_distance(rq) data = json.loads(response.content) self.assertEqual(data['status'], 'OK') rq = factory.get(reverse('profile'), data={'token': auth.token_string}) response = profile(rq) data = json.loads(response.content) self.assertEqual(data['status'], 'OK')
def weekly_stat(request): week = request.GET.get('week') token_param = request.GET.get('token') if not AuthToken.is_token_valid(token_param) and settings.DEBUG is False: return JsonResponse({'status': 'INVALID_TOKEN'}) if week: try: week = datetime.strptime(week, '%m-%d-%Y') except: return JsonResponse({'status': 'ILLEGAL_DATE_FORMAT'}) from models import UserStats token = AuthToken.objects.get(token_string=token_param) weekly_stats = UserStats.get_weekly_stats(token.user, week) return JsonResponse({'status': 'OK', 'week_of': week - datetime.timedelta(days=week.weekday()), 'weekly_stats': weekly_stats, })
def profile(request): token_param = request.GET.get('token') if not AuthToken.is_token_valid(token_param) and settings.DEBUG is False: return JsonResponse({'status': 'INVALID_TOKEN'}) from models import UserStats token = AuthToken.objects.get(token_string=token_param) weekly_stats = UserStats.get_weekly_stats(token.user) all_time_stats = UserStats.get_all_time_stats(token.user) prestige, challenge_progress = divmod(all_time_stats.get('all_time_steps'), 100) return JsonResponse({'status': 'OK', 'nick_name': token.user.public_name, 'all_time_stats': all_time_stats, 'weekly_stats': weekly_stats, 'current_challenge': { 'id': '1', 'prestige': prestige, 'name': 'mount_europa', 'total_steps': '100', 'current_steps': challenge_progress, }, })
def get_credentials(self, auth_token, auth_verifier=""): """Gets credentials Exchanges the auth token for an access token and returns it for storage elsewhere. """ auth_token = urlunquote(auth_token) auth_verifier = urlunquote(auth_verifier) auth_secret = memcache.get(self._get_memcache_auth_key(auth_token)) if not auth_secret: result = AuthToken.gql(""" WHERE service = :1 AND token = :2 LIMIT 1 """, self.service_name, auth_token).get() if not result: logging.error("The auth token %s was not found in our db" % auth_token) raise Exception, "Could not find AuthToken in database" else: auth_secret = result.secret response = self.make_request(self.access_url, token=auth_token, secret=auth_secret, additional_params={"oauth_verifier": auth_verifier}) # Extract the access token/secret from the response. result = self._extract_credentials(response) return result
def update_profile(request): token_param = request.GET.get('token') if not AuthToken.is_token_valid(token_param) and settings.DEBUG is False: return JsonResponse({'status': 'INVALID_TOKEN'}) name = request.GET.get('nickname') if not name: return HttpResponseBadRequest('nickname get parameter is required') nickname_max_size = 25 if len(name) > nickname_max_size: return JsonResponse({'status': 'NICKNAME_TOO_LONG', 'max_size': nickname_max_size}) from django.utils.html import strip_tags, escape name = escape(strip_tags(name)) token = AuthToken.objects.get(token_string=token_param) user = token.user user.public_name = name user.save() return JsonResponse({'status': 'OK'})
def authenticate(self, username=None, password=None): try: f = urllib2.urlopen(self.minecraft_login_url, urllib.urlencode([('user',username),('password',password),('version',self.minecraft_version)])) except: return None ret = f.readline().strip(); valid = ret != "Bad login" if valid: items = ret.split(':') if ret == "User not premium": uname = username else: uname = items[2] try: user = User.objects.get(username=uname) #user.set_password(password) except User.DoesNotExist: user = User(username=uname,password="******") user.save() if ret != "User not premium": try: token = user.authtoken except AuthToken.DoesNotExist: token = AuthToken(user=user) token.download_ticket = items[1] token.session_id = items[3] token.latest_version = items[0] token.save() return user return None
def on_post(self, req, resp): """ Handle POST requests. """ username = req.media.get('username') password = req.media.get('password') # Check if parameters not empty if None in [username, password]: raise falcon.HTTPBadRequest('Bad Request', 'Invalid Parameters') user = self.db_conn.query(User).filter_by(username=username).first() # If user does not exist if user == None: raise falcon.HTTPUnauthorized('Unauthorized', 'Wrong Credentials') # If password does not match if not pbkdf2_sha256.verify(password, user.password): raise falcon.HTTPUnauthorized('Unauthorized', 'Wrong Credentials') # Get user bearer token token = self.db_conn.query(AuthToken).filter_by( user_id=user.user_id).first() # Check if user does not have token if token == None: # Create user token (32 bits length) cond = False # Retry while token has not been inserted while not cond: token = AuthToken(user_id=user.user_id, auth_type='bearer', token=token_hex(16)) try: self.db_conn.add(token) self.db_conn.commit() cond = True except Exception: pass # If user has token but it has expired elif token.expires_at < time(): # Create user token (32 bits length) cond = False while not cond: token.token = token_hex(16) token.expires_at = time() + AppConfig.TOKEN_LIFE try: self.db_conn.add(token) self.db_conn.commit() cond = True except Exception: pass resp.media = { 'auth_type': token.auth_type, 'token': token.token, 'expires_on': token.expires_at } resp.status = falcon.HTTP_201
from datetime import datetime, timedelta import logging from google.appengine.ext import db from models import AuthToken delta = timedelta(seconds=60*60*2) while(AuthToken.all().count() > 0): authtokens = AuthToken.all().fetch(1000) for authtoken in authtokens: if datetime.now() > authtoken.created + delta: db.delete(authtoken)
def auth(request): token_param = request.GET.get('token') email_param = request.GET['email'] # device name/identifier device_param = request.GET.get('device') email_param = email_param.lower() if token_param is None: # register new token if not settings.ENABLE_REGISTRATION: return JsonResponse({'status': 'REGISTRATION_DISABLED'}) if not email.is_email_valid(email_param) or not email_param.endswith('europa.eu'): return JsonResponse({'status': 'INVALID_EMAIL'}) user_list = User.objects.filter(email=email_param) if not user_list: u = User(email=email_param) u.reset_public_name() u.save() else: u = user_list[0] if email.is_spamming(u.email): return JsonResponse({'status': 'CANCELED_BY_SPAM_PREVENTION'}) token = AuthToken(token_string=AuthToken.gen_token_string(email_param), user=u) token.gen_validation_key() token.save() token.send_validation_mail(public_url='https://' + request.META.get('HTTP_HOST', settings.PUBLIC_URL)) token.save() return JsonResponse({'token': token.token_string, 'status': 'OK'}) else: # actual auth token_list = AuthToken.objects.filter(token_string=token_param) if len(token_list) == 0: return JsonResponse({'status': 'TOKEN_NOT_FOUND'}) token = token_list[0] if token.valid is False: return JsonResponse({'status': 'TOKEN_NOT_ACTIVATED'}) if token.valid and email_param == token.user.email: return JsonResponse({'status': 'OK', 'public_name': token.user.public_name})
def load_token(access_token=None, refresh_token=None): if access_token: return AuthToken.objects(access_token=access_token)[0] elif refresh_token: return AuthToken.objects(refresh_token=refresh_token)[0]