def countries(request): """ Get the list of countries. """ if request.user.is_authenticated: dolibarr = DolibarrAPI(api_key=request.user.profile.dolibarr_token) else: dolibarr = DolibarrAPI() dolibarr.login(login=settings.APPS_ANONYMOUS_LOGIN, password=settings.APPS_ANONYMOUS_PASSWORD) # On récupère la liste de tous les pays indiqués comme actifs dans # Dolibarr, on ne garde que l'identifiant et le nom de chaque pays, # et on trie la liste par ordre alphabétique, à l'exception de la # France qui est placée en premier. countries = dolibarr.get(model='setup/dictionary/countries', lang='fr_FR', limit='0', sqlfilters='active=1') france_id = next(c for c in countries if c['label'] == 'France')['id'] countries = [{ 'id': c['id'], 'label': c['label'] } for c in countries if c['label'] != 'France'] countries.sort(key=lambda c: c['label']) countries.insert(0, {'id': france_id, 'label': 'France'}) return Response(countries)
def authenticate(username, password): user = None username = get_username_from_username_or_email(username) if not username: raise AuthenticationFailed() try: dolibarr = DolibarrAPI() dolibarr_token = dolibarr.login(login=username, password=password, reset=True) except (DolibarrAPIException): raise AuthenticationFailed() try: cyclos = CyclosAPI(mode='login') cyclos_token = cyclos.login(auth_string=b64encode( bytes('{}:{}'.format(username, password), 'utf-8')).decode( 'ascii')) except CyclosAPIException: raise AuthenticationFailed() try: user_results = dolibarr.get(model='users', sqlfilters="login='******'".format(username), api_key=dolibarr_token) dolibarr_user = [ item for item in user_results if item['login'] == username ][0] except (DolibarrAPIException, KeyError, IndexError): raise AuthenticationFailed() user, created = User.objects.get_or_create(username=username) user_profile = user.profile user_profile.cyclos_token = cyclos_token user_profile.dolibarr_token = dolibarr_token # if there is a member linked to this user, load it in order to retrieve its company name user_profile.companyname = '' if dolibarr_user['fk_member']: try: member = dolibarr.get(model='members', id=dolibarr_user['fk_member'], api_key=dolibarr_token) if member['company']: user_profile.companyname = member['company'] except DolibarrAPIException: pass try: user_profile.firstname = dolibarr_user['firstname'] user_profile.lastname = dolibarr_user['lastname'] except KeyError: raise AuthenticationFailed() user_profile.save() return user
def get_username_from_username_or_email(username_or_email): username = '' try: # validate (or not) the fact that our "username_or_email" variable is an email validate_email(username_or_email) # we detected that our "username_or_email" variable is an email, # we try to find the user that has this email (there must be exactly one) try: dolibarr = DolibarrAPI() dolibarr_anonymous_token = dolibarr.login(login=settings.APPS_ANONYMOUS_LOGIN, password=settings.APPS_ANONYMOUS_PASSWORD, reset=True) user_results = dolibarr.get(model='users', sqlfilters="email='{}'".format(username_or_email), api_key=dolibarr_anonymous_token) matching_users = [item for item in user_results if item['email'] == username_or_email] if matching_users and len(matching_users) == 1: username = matching_users[0]['login'] except (DolibarrAPIException, KeyError, IndexError): pass except forms.ValidationError: # we detected that our "username_or_email" variable is NOT an email so it's a username username = username_or_email log.debug('get_username_from_username_or_email({}) -> {}'.format(username_or_email, username)) return username
def towns_by_zipcode(request): """ List all towns, filtered by a zipcode. """ search = request.GET.get('zipcode', '') if not search: return Response({'error': 'Zipcode must not be empty'}, status=status.HTTP_400_BAD_REQUEST) if request.user.is_authenticated: dolibarr = DolibarrAPI(api_key=request.user.profile.dolibarr_token) else: dolibarr = DolibarrAPI() dolibarr.login(login=settings.APPS_ANONYMOUS_LOGIN, password=settings.APPS_ANONYMOUS_PASSWORD) return Response( dolibarr.get(model='setup/dictionary/towns', zipcode=search))
def login(request): """ User login from dolibarr """ serializer = serializers.LoginSerializer(data=request.data) serializer.is_valid( raise_exception=True) # log.critical(serializer.errors) try: dolibarr = DolibarrAPI() try: # validate (or not) the fact that our "username" variable is an email validate_email(request.data['username']) # we detected that our "username" variable is an email, we try to connect to dolibarr with it dolibarr_anonymous_token = dolibarr.login( login=settings.APPS_ANONYMOUS_LOGIN, password=settings.APPS_ANONYMOUS_PASSWORD) user_results = dolibarr.get( model='members', sqlfilters="email='{}' and statut=1".format( request.data['username']), api_key=dolibarr_anonymous_token) user_data = [ item for item in user_results if item['email'] == request.data['username'] ][0] if not user_data: raise AuthenticationFailed() login = user_data['login'] token = dolibarr.login(login=user_data['login'], password=request.data['password']) except forms.ValidationError: # we detected that our "username" variable is NOT an email login = request.data['username'] token = dolibarr.login(login=request.data['username'], password=request.data['password']) except (DolibarrAPIException, KeyError, IndexError): raise AuthenticationFailed() return Response({'auth_token': token, 'login': login})
def associations(request): """ List all associations, and if you want, you can filter them. """ if request.user.is_authenticated: dolibarr = DolibarrAPI(api_key=request.user.profile.dolibarr_token) else: dolibarr = DolibarrAPI() dolibarr.login(login=settings.APPS_ANONYMOUS_LOGIN, password=settings.APPS_ANONYMOUS_PASSWORD) associations = dolibarr.get(model='associations') associations.sort(key=lambda a: a['nom']) approved = request.GET.get('approved', '') if approved: # We want to filter out the associations that doesn't have the required sponsorships associations = [ asso for asso in associations if int(asso['nb_parrains']) >= settings.MINIMUM_PARRAINAGES_3_POURCENTS ] return Response(associations)
def list(self, request): email = request.GET.get('email', '') login = request.GET.get('login', '') name = request.GET.get('name', '') valid_login = Member.validate_num_adherent(login) token = request.GET.get('token', '') # Si un token est fourni pour récupérer un adhérent, la # recherche peut être faite de manière anonyme, sinon il faut # être authentifié, afin d'éviter la fuite d'information sur les # adhérents. if token and not request.user.is_authenticated: dolibarr = DolibarrAPI() dolibarr_token = dolibarr.login(login=settings.APPS_ANONYMOUS_LOGIN, password=settings.APPS_ANONYMOUS_PASSWORD) else: dolibarr_token = request.user.profile.dolibarr_token if login and valid_login: # We want to search in members by login (N° Adhérent) try: response = self.dolibarr.get(model='members', sqlfilters="login='******'".format(login), api_key=dolibarr_token) except DolibarrAPIException: return Response(status=status.HTTP_204_NO_CONTENT) return Response(response) elif login and not valid_login: return Response({'error': 'You need to provide a *VALID* ?login parameter! (Format: E12345)'}, status=status.HTTP_400_BAD_REQUEST) elif name and len(name) >= 3: # We want to search in members by name (firstname, lastname or societe) try: sqlfilters = "(firstname like '%25{name}%25' or lastname like '%25{name}%25' or societe like '%25{name}%25') and statut=1".format(name=name) response = self.dolibarr.get(model='members', sqlfilters=sqlfilters, api_key=dolibarr_token) except DolibarrAPIException: return Response(status=status.HTTP_204_NO_CONTENT) return Response(response) elif name and len(name) < 3: return Response({'error': 'You need to provide a ?name parameter longer than 2 characters!'}, status=status.HTTP_400_BAD_REQUEST) elif email: try: validate_email(email) user_results = self.dolibarr.get(model='members', sqlfilters="email='{}' and statut=1".format(email), api_key=dolibarr_token) user_data = [item for item in user_results if item['email'] == email][0] return Response(user_data) except forms.ValidationError: return Response({'error': 'You need to provide a *VALID* ?email parameter! (Format: E12345)'}, status=status.HTTP_400_BAD_REQUEST) elif token: try: response = self.dolibarr.get(model='members', token=token, api_key=dolibarr_token) except DolibarrAPIException: return Response(status=status.HTTP_204_NO_CONTENT) return Response(response) else: objects = self.dolibarr.get(model='members', sqlfilters="statut=1", api_key=dolibarr_token) paginator = CustomPagination() result_page = paginator.paginate_queryset(objects, request) serializer = MemberSerializer(result_page, many=True) return paginator.get_paginated_response(serializer.data)
def first_connection(request): """ First connection """ serializer = serializers.FirstConnectionSerializer(data=request.data) serializer.is_valid( raise_exception=True) # log.critical(serializer.errors) try: dolibarr = DolibarrAPI() dolibarr_token = dolibarr.login( login=settings.APPS_ANONYMOUS_LOGIN, password=settings.APPS_ANONYMOUS_PASSWORD) valid_login = Member.validate_num_adherent(request.data['login']) try: dolibarr.get(model='users', login=request.data['login'], api_key=dolibarr_token) return Response({'error': 'User already exist!'}, status=status.HTTP_201_CREATED) except DolibarrAPIException: pass if valid_login: # We want to search in members by login (N° Adhérent) response = dolibarr.get(model='members', login=request.data['login'], api_key=dolibarr_token) user_data = [ item for item in response if item['login'] == request.data['login'] ][0] if user_data['email'] == request.data['email']: # We got a match! # We need to mail a token etc... payload = { 'login': request.data['login'], 'aud': 'guest', 'iss': 'first-connection', 'jti': str(uuid4()), 'iat': datetime.utcnow(), 'nbf': datetime.utcnow(), 'exp': datetime.utcnow() + timedelta(hours=1) } jwt_token = jwt.encode(payload, settings.JWT_SECRET) confirm_url = '{}/valide-premiere-connexion?token={}'.format( settings.CEL_PUBLIC_URL, jwt_token.decode("utf-8")) # Activate user pre-selected language activate(user_data['array_options']['options_langue']) # Translate subject & body for this email subject = _('Première connexion à votre compte en ligne Eusko') body = render_to_string('mails/first_connection.txt', { 'token': confirm_url, 'user': user_data }) sendmail_euskalmoneta(subject=subject, body=body, to_email=request.data['email']) return Response({'member': 'OK'}) else: return Response(status=status.HTTP_400_BAD_REQUEST) else: return Response( { 'error': 'You need to provide a *VALID* login parameter! (Format: E12345)' }, status=status.HTTP_400_BAD_REQUEST) except (DolibarrAPIException, KeyError, IndexError): return Response({'error': 'Unable to get user data for this login!'}, status=status.HTTP_400_BAD_REQUEST)
def validate_first_connection(request): """ validate_first_connection """ serializer = serializers.ValidFirstConnectionSerializer(data=request.data) serializer.is_valid( raise_exception=True) # log.critical(serializer.errors) try: token_data = jwt.decode(request.data['token'], settings.JWT_SECRET, issuer='first-connection', audience='guest') except jwt.InvalidTokenError: return Response({'error': 'Unable to read token!'}, status=status.HTTP_400_BAD_REQUEST) try: dolibarr = DolibarrAPI() dolibarr_token = dolibarr.login( login=settings.APPS_ANONYMOUS_LOGIN, password=settings.APPS_ANONYMOUS_PASSWORD) # We check if the user already exist, if he already exist we return a 400 try: dolibarr.get(model='users', login=token_data['login'], api_key=dolibarr_token) return Response({'error': 'User already exist!'}, status=status.HTTP_201_CREATED) except DolibarrAPIException: pass # 1) Créer une réponse à une SecurityQuestion (créer aussi une SecurityAnswer). if serializer.data.get('question_id', False): # We got a question_id q = models.SecurityQuestion.objects.get( id=serializer.data['question_id']) elif serializer.data.get('question_text', False): # We didn't got a question_id, but a question_text: we need to create a new SecurityQuestion object q = models.SecurityQuestion.objects.create( question=serializer.data['question_text']) else: return Response( { 'status': ('Error: You need to provide at least one thse two fields: ' 'question_id or question_text') }, status=status.HTTP_400_BAD_REQUEST) res = models.SecurityAnswer.objects.create(owner=token_data['login'], question=q) res.set_answer(raw_answer=serializer.data['answer']) res.save() if not res: Response({'error': 'Unable to save security answer!'}, status=status.HTTP_400_BAD_REQUEST) # 2) Dans Dolibarr, créer un utilisateur lié à l'adhérent member = dolibarr.get(model='members', login=token_data['login'], api_key=dolibarr_token) create_user = '******'.format(member[0]['id']) create_user_data = {'login': token_data['login']} # user_id will be the ID for this new user user_id = dolibarr.post(model=create_user, data=create_user_data, api_key=dolibarr_token) # 3) Dans Dolibarr, ajouter ce nouvel utilisateur dans le groupe "Adhérents" user_group_model = 'users/{}/setGroup/{}'.format( user_id, settings.DOLIBARR_CONSTANTS['groups']['adherents']) user_group_res = dolibarr.get(model=user_group_model, api_key=dolibarr_token) if not user_group_res == 1: raise EuskalMonetaAPIException # 4) Dans Cyclos, activer l'utilisateur cyclos = CyclosAPI(mode='login') cyclos_token = cyclos.login(auth_string=b64encode( bytes( '{}:{}'.format(settings.APPS_ANONYMOUS_LOGIN, settings.APPS_ANONYMOUS_PASSWORD), 'utf-8')).decode('ascii')) cyclos_user_id = cyclos.get_member_id_from_login( member_login=token_data['login'], token=cyclos_token) active_user_data = { 'user': cyclos_user_id, # ID de l'utilisateur 'status': 'ACTIVE' } cyclos.post(method='userStatus/changeStatus', data=active_user_data, token=cyclos_token) # 5) Dans Cyclos, initialiser le mot de passe d'un utilisateur password_data = { 'user': cyclos_user_id, # ID de l'utilisateur 'type': str(settings.CYCLOS_CONSTANTS['password_types']['login_password']), 'newPassword': request.data['new_password'], # saisi par l'utilisateur 'confirmNewPassword': request.data['confirm_password'], # saisi par l'utilisateur } cyclos.post(method='password/change', data=password_data, token=cyclos_token) return Response({'status': 'success'}) except (EuskalMonetaAPIException, DolibarrAPIException, CyclosAPIException, KeyError, IndexError): return Response({'error': 'Unable to get user data for this login!'}, status=status.HTTP_400_BAD_REQUEST)