Merge branch 'master' of https://git.mindplus-dev.ir/sahama/accounts
This commit is contained in:
commit
55dadd67f4
10 changed files with 66 additions and 42 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -6,4 +6,5 @@ delme*.py
|
|||
.env
|
||||
/venv/
|
||||
oidc.key
|
||||
/log/
|
||||
/logs/*.log
|
||||
|
|
|
|||
|
|
@ -160,9 +160,6 @@ class User(AbstractUser):
|
|||
return state.get_province_by_id(self.province)
|
||||
|
||||
def set_otp(self):
|
||||
if self.otp_expire and (self.otp_expire + timedelta(seconds=MAX_OTP_VALID_DURATION)) > timezone.now():
|
||||
raise Exception(_('otp expire time not reached.'))
|
||||
|
||||
if not settings.SMS_SEND:
|
||||
self._otp = '77501'
|
||||
elif self.phone_number in settings.TEST_PHONENUMBERS:
|
||||
|
|
|
|||
|
|
@ -76,16 +76,9 @@ class RequestOTPSerializer(serializers.ModelSerializer):
|
|||
user = User.objects.create_user(**validated_data)
|
||||
|
||||
if not user.otp_is_valid():
|
||||
try:
|
||||
user.set_otp()
|
||||
except Exception as e:
|
||||
raise UnprocessableEntity(_('otp expire time not reached'))
|
||||
|
||||
user.set_otp()
|
||||
user.send_otp()
|
||||
|
||||
else:
|
||||
raise UnprocessableEntity(_('otp expire time not reached yet'))
|
||||
|
||||
self.instance = user
|
||||
return user
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ from apps.users.models import User
|
|||
from apps.users.provinces_and_cities import State
|
||||
from apps.users.serializers import PublicUserSerializer, AccountSerializer, RequestOTPSerializer, RequestOTTSerializer, \
|
||||
ChangePasswordSerializer, UserInquirySerializer, SessionSerializer
|
||||
from utils.throttles import RequestOTPDayRateThrottle, RequestOTPMinRateThrottle
|
||||
from utils.throttles import RequestOTPDayRateThrottle, RequestOTPMinRateThrottle, NumberedRequestOTPDayRateThrottle, NumberedRequestOTPMinRateThrottle
|
||||
|
||||
UserModel = get_user_model()
|
||||
|
||||
|
|
@ -90,7 +90,10 @@ class RequestOTPView(generics.CreateAPIView):
|
|||
permission_classes = []
|
||||
serializer_class = RequestOTPSerializer
|
||||
required_scopes = []
|
||||
throttle_classes = [RequestOTPMinRateThrottle, RequestOTPDayRateThrottle]
|
||||
throttle_classes = [RequestOTPMinRateThrottle,
|
||||
RequestOTPDayRateThrottle,
|
||||
NumberedRequestOTPDayRateThrottle,
|
||||
NumberedRequestOTPMinRateThrottle]
|
||||
|
||||
class RequestOTTView(generics.CreateAPIView):
|
||||
permission_classes = [IsAuthenticatedOrTokenHasScope]
|
||||
|
|
|
|||
32
client.py
32
client.py
|
|
@ -3,10 +3,10 @@ import time
|
|||
|
||||
import requests
|
||||
|
||||
OAUTH_CLIENT_ID = 'xrFXKf53jrxVOygbLEoqrtOlUwBP00jIQ4zVpzc6'
|
||||
OAUTH_CLIENT_SECRET = 'qelUdRCdEEalVdko5aHRojxsC3CaL29yjwxmc6FeWs39SeVSb6aM9mNrYQixMJNTYQK7s2wffwPW94JPPbP6jTdd9dSf1mlqYcr6hW2COuayFUk4jP33OWu4taUYP2F5'
|
||||
OAUTH_CLIENT_ID = '4INGOCMoulE0fNY1SQlTbPtsWqqxGj2DdqjADq6u'
|
||||
OAUTH_CLIENT_SECRET = 'KPc4dMSztNwAIB3vii3geXrzC1mKUIsAztz3t2ylC3HlrgJudJWhdrtoY6XeRJIuadTAREYYsXk9XtFHUDfPVcJvyfHMpNkz2VvghwrijhVprok0VYV7XrOirJ5nFUxD'
|
||||
|
||||
API_URI = 'https://accounts.gooyal.com'
|
||||
API_URI = 'https://accounts.gooyal.ir'
|
||||
|
||||
|
||||
# API_URI = 'http://127.0.0.1:8000'
|
||||
|
|
@ -27,7 +27,7 @@ class ApiClient():
|
|||
"grant_type": "password",
|
||||
"username": phone_number,
|
||||
"password": password,
|
||||
"scope": 'accounts.account:request_ott accounts.account:change_password accounts.profile:inquiry accounts.account:update accounts.account:retrieve accounts.profile:retrieve accounts.profile:list introspection wallet.wallet:get_balance',
|
||||
"scope": 'introspection',
|
||||
"auth_fields": 'phone_number:otp'
|
||||
}
|
||||
auth = (OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET)
|
||||
|
|
@ -51,7 +51,8 @@ class ApiClient():
|
|||
"grant_type": "password",
|
||||
"username": phone_number,
|
||||
"password": token,
|
||||
"scope": 'introspection education.course:retrieve education.course:submit superapp.applications:list accounts.account:request_ott accounts.profile:list accounts.profile:retrieve accounts.account:retrieve accounts.account:update accounts.profile:inquiry accounts.account:change_password wallet.transaction:list wallet.invoice:create wallet.transaction:retrieve wallet.invoice:pay wallet.invoice:receipt wallet.deposit:submit wallet.deposit:verify wallet.withdraw:submit wallet.withdraw:verify ',
|
||||
# "scope": 'introspection education.course:retrieve education.course:submit superapp.applications:list accounts.account:request_ott accounts.profile:list accounts.profile:retrieve accounts.account:retrieve accounts.account:update accounts.profile:inquiry accounts.account:change_password wallet.transaction:list wallet.invoice:create wallet.transaction:retrieve wallet.invoice:pay wallet.invoice:receipt wallet.deposit:submit wallet.deposit:verify wallet.withdraw:submit wallet.withdraw:verify ',
|
||||
"scope": 'introspection',
|
||||
"auth_fields": 'phone_number:ott'
|
||||
}
|
||||
auth = (OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET)
|
||||
|
|
@ -156,6 +157,7 @@ class ApiClient():
|
|||
}
|
||||
url = f'{API_URI}/{path}'
|
||||
response = self._request(url, method='PUT', data=data)
|
||||
print(response)
|
||||
return response and 'code' in response, response
|
||||
|
||||
def introspect_account(self, token):
|
||||
|
|
@ -185,19 +187,29 @@ class ApiClient():
|
|||
|
||||
return self._request(url=url)
|
||||
|
||||
def get_wallet_balance(self):
|
||||
url = 'http://127.0.0.1:8000/wallet/api/wallet/default/balance'
|
||||
def get_application_preferences(self):
|
||||
url = 'https://preferences.gooyal.com/data/application/'
|
||||
|
||||
return self._request(url=url)
|
||||
|
||||
|
||||
auth_data = {'access_token': 'DJ1mycH9r5FCwaNgDA9nB9uU3KWt9m', 'expires_in': 36000, 'token_type': 'Bearer', 'scope': 'accounts.account:change_password accounts.account:update accounts.account:retrieve wallet.wallet:get_balance billboard_merchant.billboard:retrieve billboard_merchant.billboard:update billboard_merchant.billboard:create wallet.user:transaction_list data_crud.data:retrieve data_crud.data:update data_crud.data:delete', 'refresh_token': 'VF4P11tfcnGv9tc2u0qH6035OW5qU4'}
|
||||
|
||||
client = ApiClient('+989106853582')
|
||||
# client.auth_data = auth_data
|
||||
# print(client.login_as_client_credentials())
|
||||
print(client.request_otp())
|
||||
print(client.otp_login('12345'))
|
||||
print(client.introspect_account('V3LUQ9OryHOy6q5iWwLBRAtRBm80ex'))
|
||||
print(client.get_wallet_balance())
|
||||
import time
|
||||
start = time.time()
|
||||
print(client.otp_login('77502'))
|
||||
# end = time.time()
|
||||
# print(end - start)
|
||||
# print(client.get_application_preferences())
|
||||
# exit()
|
||||
# print(client.introspect_account('V3LUQ9OryHOy6q5iWwLBRAtRBm80ex'))
|
||||
# print(client.get_wallet_balance())
|
||||
# ott = client.get_application_token()[1]['ott']
|
||||
# print(client.ott_login(ott))
|
||||
# print(ott)
|
||||
client.update_account('test')
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
# from django.conf import settings
|
||||
#
|
||||
# # set the default Django settings module for the 'celery' program.
|
||||
# # os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'accounts.settings')
|
||||
# # os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'main.settings')
|
||||
#
|
||||
# app = Celery('notification_service')
|
||||
#
|
||||
|
|
|
|||
|
|
@ -126,7 +126,9 @@ REST_FRAMEWORK = {
|
|||
],
|
||||
'DEFAULT_THROTTLE_RATES': {
|
||||
'otp_min': '2/min',
|
||||
'otp_day': '200/day',
|
||||
'otp_day': '50/day',
|
||||
'numbered_otp_min': '1/min',
|
||||
'numbered_otp_day': '10/day',
|
||||
},
|
||||
'EXCEPTION_HANDLER': 'utils.exceptions.exception_handler',
|
||||
}
|
||||
|
|
@ -293,7 +295,7 @@ CACHES = {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
LOKI_BASE_PUBLIC_URL = config('LOKI_BASE_PUBLIC_URL', default=None, cast=str)
|
||||
|
||||
from main.other_settings.logging import LOGGING
|
||||
|
||||
|
|
@ -315,7 +317,7 @@ STORAGES = {
|
|||
"MINIO_ACCESS_KEY": config('MINIO_ACCESS_KEY'),
|
||||
"MINIO_SECRET_KEY": config('MINIO_SECRET_KEY'),
|
||||
"MINIO_URL_EXPIRY_HOURS": timedelta(days=1), # Default is 7 days (longest) if not defined
|
||||
"MINIO_CONSISTENCY_CHECK_ON_START": False,
|
||||
"MINIO_CONSISTENCY_CHECK_ON_START": True,
|
||||
"MINIO_DEFAULT_BUCKET": config('MINIO_MEDIA_FILES_BUCKET'), # replacement for MEDIA_ROOT
|
||||
# MINIO_STATIC_FILES_BUCKET = 'my-static-files-bucket' # replacement for STATIC_ROOT
|
||||
|
||||
|
|
|
|||
4
run.sh
4
run.sh
|
|
@ -4,6 +4,6 @@
|
|||
# sleep 3
|
||||
#done
|
||||
#python3 manage.py collectstatic --noinput
|
||||
#python3 manage.py migrate
|
||||
python3 manage.py migrate
|
||||
gunicorn main.wsgi:application --bind 0.0.0.0:8000 -w 4
|
||||
#daphne -b 0.0.0.0 -p 8000 accounts.asgi:application
|
||||
#daphne -b 0.0.0.0 -p 8000 main.asgi:application
|
||||
|
|
@ -23,14 +23,9 @@ def exception_handler(exc, context):
|
|||
|
||||
if isinstance(exc, APIException):
|
||||
try:
|
||||
if isinstance(exc.detail, dict):
|
||||
if 'code' in exc.detail:
|
||||
error = exc.detail['code']
|
||||
else:
|
||||
attr = next(iter(exc.detail))
|
||||
error = exc.detail[attr].code
|
||||
else:
|
||||
error = exc.detail.code or exc.code
|
||||
error = getattr(getattr(exc, 'detail', None), 'code', None) or getattr(exc, 'code', None)
|
||||
if not error:
|
||||
error = getattr(exc, 'default_code')
|
||||
except:
|
||||
error = ''
|
||||
|
||||
|
|
@ -46,10 +41,7 @@ def exception_handler(exc, context):
|
|||
# message = error
|
||||
#
|
||||
# response_data['message'] = message
|
||||
if isinstance(exc.detail, dict):
|
||||
response_data['details'] = exc.detail
|
||||
else:
|
||||
response_data['details'] = {"message": exc.detail}
|
||||
response_data['details'] = {"message": exc.detail}
|
||||
response_data['details']['error'] = error
|
||||
response_data['details']['timestamp'] = timezone.now().isoformat()
|
||||
|
||||
|
|
@ -89,7 +81,7 @@ from django.utils.translation import gettext_lazy as _
|
|||
|
||||
|
||||
class UnprocessableEntity(APIException):
|
||||
status_code = 422
|
||||
status_code = status.HTTP_422_UNPROCESSABLE_ENTITY
|
||||
default_detail = 'The request was well-formed but cannot be processed due to semantic errors.'
|
||||
default_code = 'unprocessable_entity'
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,33 @@ class RequestOTPDayRateThrottle(SimpleRateThrottle):
|
|||
}
|
||||
|
||||
|
||||
|
||||
class RequestOTPMinRateThrottle(RequestOTPDayRateThrottle):
|
||||
scope = 'otp_min'
|
||||
|
||||
|
||||
class NumberedRequestOTPDayRateThrottle(SimpleRateThrottle):
|
||||
scope = 'numbered_otp_day'
|
||||
|
||||
def get_ident(self, request):
|
||||
return request.data.get('phone_number')
|
||||
|
||||
def get_cache_key(self, request, view):
|
||||
if request.user and request.user.is_authenticated:
|
||||
ident = request.user.pk
|
||||
else:
|
||||
ident = self.get_ident(request)
|
||||
|
||||
return self.cache_format % {
|
||||
'scope': self.scope,
|
||||
'ident': ident
|
||||
}
|
||||
|
||||
|
||||
|
||||
class NumberedRequestOTPMinRateThrottle(NumberedRequestOTPDayRateThrottle):
|
||||
scope = 'numbered_otp_min'
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue