Exemple #1
0
    def test_authenticate_method_setups_auth_token(self):
        client = HubstaffClient(app_token=os.getenv('HUBSTAFF_APP_TOKEN'),
                                username=os.getenv('HUBSTAFF_USERNAME'),
                                password=os.getenv('HUBSTAFF_PASSWORD'))
        client.authenticate()

        self.assertIsNotNone(client._auth_token)
Exemple #2
0
    def test_authenticate_method_calls_post_with_right_params(self, m_post):
        m_post.return_value.status_code = 200
        m_post.return_value.json.return_value = {
            'user': {
                'auth_token': self.auth_token
            }
        }

        client = HubstaffClient(app_token=self.app_token,
                                username='******',
                                password='******')
        client.authenticate()

        self.assertEqual(m_post.call_count, 1)
        call_args, call_kwargs = m_post.call_args
        self.assertEqual(call_args, ('https://api.hubstaff.com/v1/auth', ))
        self.assertDictEqual(
            call_kwargs, {
                'headers': {
                    'App-Token': self.app_token
                },
                'data': {
                    'email': '*****@*****.**',
                    'password': '******'
                },
            })
Exemple #3
0
    def test_authenticate_method_raises_error_on_invalid_app_token(self):
        client = HubstaffClient(app_token='x' * 43,
                                username=os.getenv('HUBSTAFF_USERNAME'),
                                password=os.getenv('HUBSTAFF_PASSWORD'))
        with self.assertRaises(HubstaffAuthError) as err_ctx:
            client.authenticate()

        self.assertEqual(err_ctx.exception.message, 'Invalid app_token')
Exemple #4
0
 def _init_client(self):
     self._hubstaff = HubstaffClient(
         app_token=self._config.hubstaff_app_token,
         auth_token=self._config.hubstaff_auth_token,
         username=self._config.hubstaff_username,
         password=self._config.hubstaff_password)
     # set given auth_token to the config
     self._config.hubstaff_auth_token = self._hubstaff.authenticate()
Exemple #5
0
    def test_authenticate_method_raises_error_on_invalid_username(self):
        client = HubstaffClient(app_token=os.getenv('HUBSTAFF_APP_TOKEN'),
                                username='******',
                                password=os.getenv('HUBSTAFF_PASSWORD'))
        with self.assertRaises(HubstaffAuthError) as err_ctx:
            client.authenticate()

        self.assertEqual(err_ctx.exception.message,
                         'Invalid email and/or password')
Exemple #6
0
    def test_request_method_refreshes_auth_token(self, m_post, m_request):
        m_post.side_effect = self._auth_endpoint
        m_request.side_effect = self._users_endpoint

        client = HubstaffClient(app_token=self.app_token,
                                auth_token='EXPIRED!',
                                username='******',
                                password='******')
        client._request('get',
                        '/users',
                        params={
                            'organization_memberships': False,
                            'project_memberships': False,
                            'offset': 0
                        })

        self.assertEqual(m_request.call_count, 2)
        # The first call uses expired token
        call_args, call_kwargs = m_request.call_args_list[0]
        self.assertEqual(call_args, (
            'get',
            'https://api.hubstaff.com/v1/users',
        ))
        self.assertDictEqual(
            call_kwargs, {
                'headers': {
                    'App-Token': self.app_token,
                    'Auth-Token': 'EXPIRED!',
                },
                'params': {
                    'organization_memberships': False,
                    'project_memberships': False,
                    'offset': 0
                },
                'data': None,
                'json': None,
            })
        # The second call uses refreshed token
        call_args, call_kwargs = m_request.call_args_list[1]
        self.assertEqual(call_args, (
            'get',
            'https://api.hubstaff.com/v1/users',
        ))
        self.assertDictEqual(
            call_kwargs, {
                'headers': {
                    'App-Token': self.app_token,
                    'Auth-Token': self.auth_token,
                },
                'params': {
                    'organization_memberships': False,
                    'project_memberships': False,
                    'offset': 0
                },
                'data': None,
                'json': None,
            })
Exemple #7
0
    def test_authenticate_method_raises_error_on_invalid_password(self):
        client = HubstaffClient(app_token=os.getenv('HUBSTAFF_APP_TOKEN'),
                                username=os.getenv('HUBSTAFF_USERNAME'),
                                password='******' * 16)
        with self.assertRaises(HubstaffAuthError) as err_ctx:
            client.authenticate()

        self.assertEqual(err_ctx.exception.message,
                         'Invalid email and/or password')
Exemple #8
0
    def test_authenticate_method_raises_invalid_app_token_error(self, m_post):
        m_post.return_value.status_code = 401
        m_post.return_value.json.return_value = {'error': 'Invalid app_token'}

        client = HubstaffClient(app_token='bad_token',
                                username='******',
                                password='******')
        with self.assertRaises(HubstaffAuthError) as err_ctx:
            client.authenticate()

        self.assertEqual(err_ctx.exception.message, 'Invalid app_token')
Exemple #9
0
    def test_authenticate_method_returns_auth_token_no_password(self, m_post):
        m_post.return_value.status_code = 401
        m_post.return_value.json.return_value = {
            'error': 'Invalid email and/or password'
        }

        client = HubstaffClient(app_token=self.app_token,
                                auth_token=self.auth_token)
        auth_token = client.authenticate()

        self.assertEqual(auth_token, self.auth_token)
Exemple #10
0
    def test_post_method_calls_request_method_with_data(self, m_request):
        m_request.return_value = {'user': {'id': 123}}

        client = HubstaffClient(app_token=self.app_token,
                                username='******',
                                password='******')
        result = client._post('/users', data={'name': 'Johny'})

        self.assertDictEqual(result, {'user': {'id': 123}})
        m_request.assert_called_once_with('post',
                                          '/users',
                                          data={'name': 'Johny'},
                                          json=None)
Exemple #11
0
    def test_authenticate_method_setups_auth_token(self, m_post):
        m_post.return_value.status_code = 200
        m_post.return_value.json.return_value = {
            'user': {
                'auth_token': self.auth_token
            }
        }

        client = HubstaffClient(app_token=self.app_token,
                                username='******',
                                password='******')
        client.authenticate()

        self.assertEqual(client._auth_token, self.auth_token)
Exemple #12
0
    def test_authenticate_method_raises_invalid_password_error(self, m_post):
        m_post.return_value.status_code = 401
        m_post.return_value.json.return_value = {
            'error': 'Invalid email and/or password'
        }

        client = HubstaffClient(app_token=self.app_token,
                                username='******',
                                password='******' * 16)
        with self.assertRaises(HubstaffAuthError) as err_ctx:
            client.authenticate()

        self.assertEqual(err_ctx.exception.message,
                         'Invalid email and/or password')
 def setUpClass(cls):
     cls.client = HubstaffClient(
         app_token=os.getenv('HUBSTAFF_APP_TOKEN'),
         auth_token=os.getenv('HUBSTAFF_AUTH_TOKEN'),
         username=os.getenv('HUBSTAFF_USERNAME'),
         password=os.getenv('HUBSTAFF_PASSWORD'))
     # save auth_token to prevent auth api throttling
     if not os.getenv('HUBSTAFF_AUTH_TOKEN'):
         os.environ['HUBSTAFF_AUTH_TOKEN'] = cls.client.authenticate()
     # date range
     cls.date_from = datetime.strptime(os.getenv('HUBSTAFF_TEST_DATE_FROM'),
                                       '%Y-%m-%d')
     cls.date_to = datetime.strptime(os.getenv('HUBSTAFF_TEST_DATE_TO'),
                                     '%Y-%m-%d')
     # save first found user id
     users_list = cls.client.get_users_list(include_projects=True,
                                            include_organizations=True)
     cls.user_id = users_list[0]['id']
     # save first found organization id
     cls.organization_id = users_list[0]['organizations'][0]['id']
     # take the rest of organization members
     cls.organization_members = set()
     for user_item in users_list:
         user_organizations = user_item.get('organizations') or []
         user_organization_id_list = [o['id'] for o in user_organizations]
         if cls.organization_id in user_organization_id_list:
             cls.organization_members.add(user_item['id'])
     # save first found project id
     cls.project_id = users_list[0]['projects'][0]['id']
Exemple #14
0
    def test_request_method_returns_json_data(self, m_request):
        m_request.return_value.status_code = 200
        m_request.return_value.json.return_value = {'users': []}

        client = HubstaffClient(app_token=self.app_token,
                                auth_token=self.auth_token)

        result = client._request('get',
                                 '/users',
                                 params={
                                     'organization_memberships': False,
                                     'project_memberships': False,
                                     'offset': 0
                                 })

        self.assertDictEqual(result, {'users': []})
Exemple #15
0
    def test_init_raises_error_on_no_auth_token_no_password(self):
        with self.assertRaises(ValueError) as err_ctx:
            HubstaffClient(app_token=self.app_token,
                           username='******')

        self.assertEqual(
            err_ctx.exception.args[0],
            'auth_token or (username, password) pair must be set')
Exemple #16
0
    def test_authenticate_method_raises_too_many_requests_error(self, m_post):
        m_post.return_value.status_code = 429
        m_post.return_value.json.return_value = {
            'error':
            'Rate limit has been reached. '
            'Please wait before making your next request.'
        }

        client = HubstaffClient(app_token=self.app_token,
                                username='******',
                                password='******')
        with self.assertRaises(HubstaffError) as err_ctx:
            client.authenticate()

        self.assertEqual(
            err_ctx.exception.message, 'Rate limit has been reached. '
            'Please wait before making your next request.')
Exemple #17
0
    def test_request_method_doesnt_call_authenticate_method(
            self, m_authenticate, m_request):
        m_request.return_value.status_code = 200
        m_request.return_value.json.return_value = {'users': []}

        client = HubstaffClient(app_token=self.app_token,
                                auth_token=self.auth_token)

        client._request('get',
                        '/users',
                        params={
                            'organization_memberships': False,
                            'project_memberships': False,
                            'offset': 0
                        })

        m_authenticate.assert_not_called()
 def setUpClass(cls):
     cls.client = HubstaffClient(
         app_token=os.getenv('HUBSTAFF_APP_TOKEN'),
         auth_token=os.getenv('HUBSTAFF_AUTH_TOKEN'),
         username=os.getenv('HUBSTAFF_USERNAME'),
         password=os.getenv('HUBSTAFF_PASSWORD'))
     # save auth_token to prevent auth api throttling
     if not os.getenv('HUBSTAFF_AUTH_TOKEN'):
         os.environ['HUBSTAFF_AUTH_TOKEN'] = cls.client.authenticate()
Exemple #19
0
 def setUpClass(cls):
     cls.client = HubstaffClient(
         app_token=os.getenv('HUBSTAFF_APP_TOKEN'),
         auth_token=os.getenv('HUBSTAFF_AUTH_TOKEN'),
         username=os.getenv('HUBSTAFF_USERNAME'),
         password=os.getenv('HUBSTAFF_PASSWORD'))
     # save auth_token to prevent auth api throttling
     if not os.getenv('HUBSTAFF_AUTH_TOKEN'):
         os.environ['HUBSTAFF_AUTH_TOKEN'] = cls.client.authenticate()
     # save the first found project id
     cls.project_id = cls.client.get_projects_list()[0]['id']
Exemple #20
0
    def test_request_method_raises_unauthorized_error(self, _, m_request):
        m_request.return_value.status_code = 401
        m_request.return_value.json.return_value = {
            'error': 'Permission denied'
        }

        client = HubstaffClient(
            app_token=self.app_token,
            auth_token=self.auth_token,  # valid but probably expired
            username='******',
            password='******')
        with self.assertRaises(HubstaffAuthError) as err_ctx:
            client._request('get',
                            '/users',
                            params={
                                'organization_memberships': False,
                                'project_memberships': False,
                                'offset': 0
                            })

        self.assertEqual(err_ctx.exception.message, 'Permission denied')
Exemple #21
0
    def test_request_method_raises_too_many_requests(self, m_request):
        m_request.return_value.status_code = 429
        m_request.return_value.json.return_value = {
            'error':
            'Rate limit has been reached. '
            'Please wait before making your next request.'
        }

        client = HubstaffClient(app_token=self.app_token,
                                auth_token=self.auth_token)
        with self.assertRaises(HubstaffError) as err_ctx:
            client._request('get',
                            '/users',
                            params={
                                'organization_memberships': False,
                                'project_memberships': False,
                                'offset': 0
                            })

        self.assertEqual(
            err_ctx.exception.message, 'Rate limit has been reached. '
            'Please wait before making your next request.')
Exemple #22
0
    def test_get_method_calls_request_method(self, m_request):
        m_request.return_value = {'users': []}

        client = HubstaffClient(app_token=self.app_token,
                                username='******',
                                password='******')
        result = client._get('/users',
                             params={
                                 'organization_memberships': False,
                                 'project_memberships': False,
                                 'offset': 0
                             })

        self.assertDictEqual(result, {'users': []})
        m_request.assert_called_once_with('get',
                                          '/users',
                                          params={
                                              'organization_memberships':
                                              False,
                                              'project_memberships': False,
                                              'offset': 0
                                          })
Exemple #23
0
    def test_request_method_tries_to_to_refresh_the_token(
            self, m_authenticate, m_request):
        m_request.return_value.status_code = 401
        m_request.return_value.json.return_value = {
            'error': 'Permission denied'
        }

        client = HubstaffClient(
            app_token=self.app_token,
            auth_token=self.auth_token,  # valid but probably expired
            username='******',
            password='******')

        with self.assertRaises(HubstaffAuthError):
            client._request('get',
                            '/users',
                            params={
                                'organization_memberships': False,
                                'project_memberships': False,
                                'offset': 0
                            })

        m_authenticate.asert_called_once_with()
Exemple #24
0
    def test_request_method_calls_api_with_auth_token(self, m_post, m_request):
        m_post.side_effect = self._auth_endpoint
        m_request.return_value.status_code = 200
        m_request.return_value.json.return_value = {'users': []}

        client = HubstaffClient(app_token=self.app_token,
                                username='******',
                                password='******')
        client._request('get',
                        '/users',
                        params={
                            'organization_memberships': False,
                            'project_memberships': False,
                            'offset': 0
                        })

        self.assertEqual(m_request.call_count, 1)
        call_args, call_kwargs = m_request.call_args
        self.assertEqual(call_args, (
            'get',
            'https://api.hubstaff.com/v1/users',
        ))
        self.assertDictEqual(
            call_kwargs, {
                'headers': {
                    'App-Token': self.app_token,
                    'Auth-Token': self.auth_token,
                },
                'params': {
                    'organization_memberships': False,
                    'project_memberships': False,
                    'offset': 0
                },
                'data': None,
                'json': None,
            })
Exemple #25
0
 def handle(self, *args, **options):
     HUBSTAFF_APP_TOKEN = "S-HAXY_8ZU996f1xGEX-OATcWaAwb51HqlnwN6oi4vU"
     hubstaff = HubstaffClient(app_token=HUBSTAFF_APP_TOKEN,
                               username='******',
                               password='******')
     os.environ['HUBSTAFF_AUTH_TOKEN'] = hubstaff.authenticate()
     hubstaff = HubstaffClient(app_token=HUBSTAFF_APP_TOKEN,
                               auth_token=os.getenv('HUBSTAFF_AUTH_TOKEN'))
     hubstaff.authenticate()
     users_list = hubstaff.get_users_list(include_projects=True,
                                          include_organizations=True)
     ids = map(lambda user: (user['id'], user['email']), users_list)
     for user_id in ids:
         try:
             user = CustomUser.objects.get(email=user_id[1])
             HubstaffUser.objects.get_or_create(user=user,
                                                hubstaff_id=user_id[0])
         except Exception as e:
             print("user not found")
def hubStaffAuthentication():
    hubstaff = HubstaffClient(app_token=config.HUBSTAFF_APP_TOKEN,
                              username=config.HUBSTAFF_USERNAME,
                              password=config.HUBSTAFF_PASSWORD)
    hubstaff.authenticate()
    return hubstaff
Exemple #27
0
    def handle(self, *args, **options):

        month = options['month']
        year = options['year']
        day = options['day']

        HUBSTAFF_APP_TOKEN = "S-HAXY_8ZU996f1xGEX-OATcWaAwb51HqlnwN6oi4vU"
        #hubstaff = HubstaffClient(app_token=HUBSTAFF_APP_TOKEN,username='******',password='******')
        #os.environ['HUBSTAFF_AUTH_TOKEN'] = hubstaff.authenticate()
        #print (os.getenv('HUBSTAFF_AUTH_TOKEN'))
        os.environ[
            'HUBSTAFF_AUTH_TOKEN'] = "p-XSy3G4v4nkVewG0Z72G4SlDnXe8uljLzo7MJhtQ5g"

        hubstaff = HubstaffClient(app_token=HUBSTAFF_APP_TOKEN,
                                  auth_token=os.getenv('HUBSTAFF_AUTH_TOKEN'))
        hubstaff.authenticate()
        if month and year and day:

            params = {
                'start_date': datetime(year=year, month=month,
                                       day=day).isoformat(),
                'end_date': datetime(year=year, month=month,
                                     day=day).isoformat(),
            }
        else:
            params = {
                'start_date': datet.today().isoformat(),
                'end_date': datet.today().isoformat(),
            }

        result = hubstaff._get('/custom/by_date/team', params=params)

        for data in result['organizations'][0]['dates']:
            date = datetime.strptime(data['date'], '%Y-%m-%d').date()
            for user in data['users']:
                #import pdb;pdb.set_trace()

                try:
                    wfh = WorkFromHome.objects.get(
                        date=date, hubstaff_id__hubstaff_id=user['id'])
                    if user['projects']:
                        shift = wfh.user.shifts.get(date=date)
                        obj, created = UserAttendanceLog.objects.get_or_create(
                            date=date, user=wfh.user, shift=shift)
                        #import pdb;pdb.set_trace()
                        #time_from = time(11, 30)
                        time_from = shift.shift.time_from
                        for log in user['projects']:
                            time_to = (
                                datetime.combine(date, time_from) +
                                timedelta(seconds=log['duration'])).time()
                            ctx = {
                                'attendance_log': obj,
                                'in_time': time_from,
                                'out_time': time_to,
                                'type': 'in',
                                'duration': timedelta(seconds=log['duration']),
                                'comment': log['name']
                            }
                            UserAttendanceLogSummary.objects.get_or_create(
                                **ctx)
                            time_from = time_to
                except Exception as e:
                    print("work from home not found", e)
Exemple #28
0
class Command:
    def __init__(self, **opts):
        self._logger = logging.getLogger(__name__)
        self._logger.setLevel(logging.WARNING)
        self._config = Config(**opts)
        self._hubstaff = None

    def _load_config(self):
        self._config.load()

    def _init_client(self):
        self._hubstaff = HubstaffClient(
            app_token=self._config.hubstaff_app_token,
            auth_token=self._config.hubstaff_auth_token,
            username=self._config.hubstaff_username,
            password=self._config.hubstaff_password)
        # set given auth_token to the config
        self._config.hubstaff_auth_token = self._hubstaff.authenticate()

    def _save_config(self):
        self._config.save()

    def _get_report_data(self, date_from, date_to):
        users_list = self._hubstaff.get_users_list(include_projects=True)

        users_dict = {}
        projects_dict = {}
        for user_item in users_list:
            users_dict[user_item['id']] = {
                'id': user_item['id'],
                'name': user_item['name'],
            }
            for project_item in user_item['projects']:
                projects_dict[project_item['id']] = {
                    'id': project_item['id'],
                    'name': project_item['name'],
                }

        activities_list = self._hubstaff.get_activities_list(
            date_from, date_to)

        spent_time_dict = defaultdict(lambda: 0)
        for activity_item in activities_list:
            spent_time_dict[(
                activity_item['user_id'],
                activity_item['project_id'])] += activity_item['tracked']

        report_data = {
            'date_from': date_from,
            'date_to': date_to,
            'users': users_dict,
            'projects': projects_dict,
            'spent_time': spent_time_dict,
        }
        return report_data

    @classmethod
    def _render_report_to_html(cls, data):
        template = jinja2.Template('''<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>rt-bot-34 report {{ date_from }} - {{ date_to }}</title>
  </head>
  <body>
    <h1>{{ date_from }} - {{ date_to }}</h1>
    <table>
      <thead>
        <tr>
          <th>&nbsp;</th>
        {% for user_id, user in users.items() %}
          <th>{{ user.name }}</th>
        {% endfor %}
        </tr>
      </thead>
      <tbody>
      {% for project_id, project in projects.items() %}
        <tr>
          <td>{{ project.name }}</td>
        {% for user_id, user in users.items() %}
          <td>{{ spent_time.get((user_id, project_id), 0) }}</td>
        {% endfor %}
        </tr>
      {% endfor %}
      </tbody>
    </table>
  </body>
</html>
''')
        html = template.render(**data)
        return html

    @classmethod
    def _save_report_html_to_file(cls, html, filename):
        with open(filename, 'w+') as f:
            f.write(html)

    def _build_report(self):
        report_data = self._get_report_data(
            date_from=self._config.report_date_from,
            date_to=self._config.report_date_to)
        report_html = self._render_report_to_html(data=report_data)
        self._save_report_html_to_file(html=report_html,
                                       filename=self._config.report_filename)
        # here you can add sending report html by email ...

    def handle(self):
        try:
            self._load_config()
            self._init_client()
            self._save_config()
            self._build_report()
        except HubstaffAuthError:
            self._logger.error('hubstaff error: authentication failed')
        except ma.ValidationError as e:
            self._logger.error('validation error: %s' % e.messages)
Exemple #29
0
    def test_authenticate_method_no_password_doesnt_call_api(self, m_post):
        client = HubstaffClient(app_token=self.app_token,
                                auth_token=self.auth_token)
        client.authenticate()

        m_post.assert_not_called()