Exemple #1
0
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)
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
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))
Exemple #5
0
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})
Exemple #6
0
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)
Exemple #7
0
    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)
Exemple #8
0
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)
Exemple #9
0
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)