Esempio n. 1
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
Esempio n. 2
0
def validate_lost_password(request):
    """
    validate_lost_password
    """
    serializer = serializers.ValidLostPasswordSerializer(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='lost-password',
                                audience='guest')
    except jwt.InvalidTokenError:
        return Response({'error': 'Unable to read token!'},
                        status=status.HTTP_400_BAD_REQUEST)

    try:
        # Check SecurityQA with custom methods in models.SecurityAnswer
        answer = models.SecurityAnswer.objects.get(owner=token_data['login'])
        if not answer.check_answer(serializer.data['answer']):
            return Response({'status': 'NOK'},
                            status=status.HTTP_400_BAD_REQUEST)

        # Dans Cyclos, activer l'utilisateur (au cas où il soit à l'état bloqué)
        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)

        # Dans Cyclos, reset 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':
            serializer.data['new_password'],  # saisi par l'utilisateur
            'confirmNewPassword':
            serializer.data['confirm_password'],  # saisi par l'utilisateur
        }
        cyclos.post(method='password/change',
                    data=password_data,
                    token=cyclos_token)

        return Response({'status': 'success'})

    except (EuskalMonetaAPIException, CyclosAPIException, KeyError,
            IndexError):
        return Response({'error': 'Unable to get user data for this login!'},
                        status=status.HTTP_400_BAD_REQUEST)
Esempio n. 3
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)