mailbox-org-api 2.1__tar.gz → 2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/PKG-INFO +2 -2
  2. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/mailbox_org_api/APIClient.py +35 -3
  3. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/mailbox_org_api.egg-info/PKG-INFO +2 -2
  4. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/pyproject.toml +3 -3
  5. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/setup.py +1 -1
  6. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/tests/TestAPIClient.py +106 -22
  7. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/LICENSE +0 -0
  8. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/README.md +0 -0
  9. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/mailbox_org_api/APIError.py +0 -0
  10. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/mailbox_org_api/Account.py +0 -0
  11. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/mailbox_org_api/Invoice.py +0 -0
  12. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/mailbox_org_api/Mail.py +0 -0
  13. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/mailbox_org_api/__init__.py +0 -0
  14. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/mailbox_org_api.egg-info/SOURCES.txt +0 -0
  15. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/mailbox_org_api.egg-info/dependency_links.txt +0 -0
  16. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/mailbox_org_api.egg-info/top_level.txt +0 -0
  17. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/setup.cfg +0 -0
  18. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/tests/TestAccount.py +0 -0
  19. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/tests/TestInvoice.py +0 -0
  20. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/tests/TestMail.py +0 -0
  21. {mailbox_org_api-2.1 → mailbox_org_api-2.2}/tests/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mailbox-org-api
3
- Version: 2.1
3
+ Version: 2.2
4
4
  Summary: A library to access the mailbox.org Business API.
5
5
  Author: Hendrik Schlange
6
6
  Author-email: Hendrik Schlange <mail@heshsum.de>
@@ -9,7 +9,7 @@ Project-URL: Issues, https://github.com/heshsum/mailbox-org-api/issues
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Operating System :: OS Independent
12
- Requires-Python: >=3.8
12
+ Requires-Python: >=3.11
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
15
  Dynamic: author
@@ -564,7 +564,10 @@ class APIClient:
564
564
 
565
565
  if 'password' in kwargs and 'password_hash' in kwargs:
566
566
  raise KeyError('''Simultaneous usage of 'password' and 'password_hash' not allowed.''')
567
-
567
+
568
+ if 'additional_mail_quota' in kwargs or 'additional_cloud_quota' in kwargs and 'plan' not in kwargs:
569
+ raise KeyError('''If setting additional quota, 'plan' must be given.''')
570
+
568
571
  # Check for each argument in kwargs if it is a valid function parameter.
569
572
  # Check key and type of value. Raise errors if a check fails.
570
573
 
@@ -634,6 +637,27 @@ class APIClient:
634
637
  """
635
638
  return self.api_request('mail.set', {'mail':mail, 'active':active})
636
639
 
640
+ def mail_set_additional_mail_quota(self, mail: str, quota: int) -> dict:
641
+ """
642
+ Function to set additional mail quota for a given mail
643
+ :param mail: the mail to set the quota for
644
+ :param quota: the quota to set
645
+ :return: the response for the request
646
+ """
647
+ plan = self.mail_get(mail)['plan']
648
+ return self.api_request('mail.set', {'mail': mail, 'plan':plan, 'additional_mail_quota':quota})
649
+
650
+ def mail_set_additional_cloud_quota(self, mail: str, quota: int) -> dict:
651
+ """
652
+ Function to set additional cloud quota for a given mail
653
+ :param mail: the mail to set the quota for
654
+ :param quota: the quota to set
655
+ :return: the response for the request
656
+ """
657
+ plan = self.mail_get(mail)['plan']
658
+ return self.api_request('mail.set', {'mail': mail, 'plan': plan,
659
+ 'additional_cloud_quota': quota})
660
+
637
661
  def mail_set_deletion_date(self, mail: str, deletion_date: str) -> dict:
638
662
  """
639
663
  Function to delete an inbox at a given date.
@@ -954,14 +978,22 @@ class APIClient:
954
978
  return self.api_request('mailinglist.set', {'mailinglist':mailinglist, 'account':account,
955
979
  'password':password, 'adminmail':adminmail})
956
980
 
957
- def mailinglist_delete(self, mailinglist: str, account: str) -> dict:
981
+ def mailinglist_del(self, mailinglist: str, account: str) -> dict:
958
982
  """
959
983
  Function to delete a mailing list
960
984
  :param mailinglist: the mailing list to delete
961
985
  :param account: the account of the mailing list
962
986
  :return: the mailbox API response for the request - True if the mailing list was deleted, error code otherwise
963
987
  """
964
- return self.api_request('mailinglist.delete', {'mailinglist':mailinglist, 'account':account})
988
+ return self.api_request('mailinglist.del', {'mailinglist':mailinglist, 'account':account})
989
+
990
+ def additionalmailaccount_list(self, parent_mail: str) -> dict:
991
+ """
992
+ Function to list all additional mail accounts for a given parent mail
993
+ :param parent_mail: the parent mail to list additional mail accounts for
994
+ :return: a dict containing the parent mail account and a list of additional mail accounts
995
+ """
996
+ return self.api_request('additionalmailaccount.list', {'parent_mail':parent_mail})
965
997
 
966
998
  def additionalmailaccount_add(self, parent_mail: str, new_account_mail: str, new_account_password: str,
967
999
  primary_address: str = None, mail_server: str = 'imap.mailbox.org',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mailbox-org-api
3
- Version: 2.1
3
+ Version: 2.2
4
4
  Summary: A library to access the mailbox.org Business API.
5
5
  Author: Hendrik Schlange
6
6
  Author-email: Hendrik Schlange <mail@heshsum.de>
@@ -9,7 +9,7 @@ Project-URL: Issues, https://github.com/heshsum/mailbox-org-api/issues
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: License :: OSI Approved :: MIT License
11
11
  Classifier: Operating System :: OS Independent
12
- Requires-Python: >=3.8
12
+ Requires-Python: >=3.11
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
15
  Dynamic: author
@@ -1,12 +1,12 @@
1
1
  [project]
2
2
  name = "mailbox-org-api"
3
- version = "2.1"
3
+ version = "2.2"
4
4
  authors = [
5
5
  { name="Hendrik Schlange", email="mail@heshsum.de" },
6
6
  ]
7
7
  description = "A library to access the mailbox.org Business API."
8
8
  readme = "README.md"
9
- requires-python = ">=3.8"
9
+ requires-python = ">=3.11"
10
10
  classifiers = [
11
11
  "Programming Language :: Python :: 3",
12
12
  "License :: OSI Approved :: MIT License",
@@ -18,7 +18,7 @@ Homepage = "https://github.com/heshsum/mailbox-org-api"
18
18
  Issues = "https://github.com/heshsum/mailbox-org-api/issues"
19
19
 
20
20
  [build-system]
21
- requires = ["setuptools>=61.0"]
21
+ requires = ["setuptools>=70.0"]
22
22
  build-backend = "setuptools.build_meta"
23
23
 
24
24
  [tool.pytest.ini_options]
@@ -3,7 +3,7 @@ from setuptools import find_packages, setup
3
3
  setup(
4
4
  name='mailbox_org_api',
5
5
  packages=find_packages(),
6
- version='2.1',
6
+ version='2.2',
7
7
  description='A library to access the mailbox.org Business API',
8
8
  author='Hendrik Schlange',
9
9
  install_requires=['requests'],
@@ -15,9 +15,26 @@ def generate_id():
15
15
  return str(int(time.time()))
16
16
 
17
17
  def generate_pw():
18
- alphabet = string.ascii_letters + string.digits
19
- password = ''.join(secrets.choice(alphabet) for i in range(42))
20
- return password
18
+ # Length of password
19
+ length = 42
20
+ # Required character sets
21
+ upper = string.ascii_uppercase
22
+ lower = string.ascii_lowercase
23
+ digits = string.digits
24
+ special = '!$"%%&/()'
25
+
26
+ # Combine all allowed characters
27
+ all_chars = upper + lower + digits + special
28
+ while True:
29
+ # Generate a random string of the specified length
30
+ pw = ''.join(secrets.choice(all_chars) for _ in range(length))
31
+
32
+ # Ensure the password meets all criteria
33
+ if (any(c in upper for c in pw) and
34
+ any(c in lower for c in pw) and
35
+ any(c in digits for c in pw) and
36
+ any(c in special for c in pw)):
37
+ return pw
21
38
 
22
39
  def get_domain():
23
40
  api = APIClient.APIClient()
@@ -289,7 +306,7 @@ class TestAPIClient:
289
306
  assert returned_mail['mail'] == mail
290
307
  api.deauth()
291
308
 
292
- @pytest.mark.depends(name=['test_mail_add'])
309
+ @pytest.mark.depends(name='test_mail_add')
293
310
  def test_mail_set(self):
294
311
  api = APIClient.APIClient()
295
312
  api.auth(api_test_user, api_test_pass)
@@ -302,7 +319,7 @@ class TestAPIClient:
302
319
  'memo': 'memo_string', 'active': True, 'title': 'Title', 'position': 'Job Position',
303
320
  'department': 'Department', 'company': 'Company', 'street': 'Street 1',
304
321
  'postal_code': '12345', 'city': 'City', 'phone':'+492345678', 'fax':'+492345678',
305
- 'cell_phone':'+492345678', 'uid_extern': generate_pw(), 'language': 'de_DE'}
322
+ 'cell_phone':'+492345678', 'uid_extern': 'external_uid_value', 'language': 'de_DE'}
306
323
 
307
324
  # Adding parameters to call
308
325
  params = {}
@@ -311,14 +328,23 @@ class TestAPIClient:
311
328
 
312
329
  # Getting mail from API to act as the reference
313
330
  check_mail = api.mail_get(mail)
314
-
331
+ print(check_mail)
315
332
  # Compare values sent to values received
316
333
  for k, v in mail_set_tests.items():
317
334
  assert check_mail[k] == v
318
335
 
336
+ with pytest.raises(KeyError):
337
+ api.mail_set(mail, additional_mail_quota=5)
338
+
339
+ with pytest.raises(KeyError):
340
+ api.mail_set(mail, additional_cloud_quota=5)
341
+
342
+ with pytest.raises(KeyError):
343
+ api.mail_set(mail, additional_mail_quota = 5, additional_cloud_quota=5)
344
+
319
345
  api.deauth()
320
346
 
321
- @pytest.mark.depends(name=["test_mail_add"])
347
+ @pytest.mark.depends(name="test_mail_add")
322
348
  def test_mail_capabilities_set(self):
323
349
  capabilities = ['MAIL_SPAMPROTECTION', 'MAIL_BLACKLIST', 'MAIL_BACKUPRECOVER', 'MAIL_PASSWORDRESET_SMS']
324
350
 
@@ -352,22 +378,20 @@ class TestAPIClient:
352
378
  api.auth(api_test_user, api_test_pass)
353
379
  mails = api.mail_list(domain)
354
380
  mail = mails[0]['mail']
355
- plans = ['standard', 'premium']
381
+ plans = ['premium', 'light', 'standard']
356
382
  for plan in plans:
357
383
  api.mail_set_plan(mail, plan)
358
384
  assert str(api.mail_get(mail)['plan']).lower() == plan
359
- with pytest.raises(APIError):
360
- api.mail_set_plan(mail, 'light')
361
385
  api.deauth()
362
386
 
363
- @pytest.mark.depends(name=["test_mail_add"])
387
+ @pytest.mark.depends(name="test_mail_add")
364
388
  def test_mail_set_aliases(self):
365
389
  api = APIClient.APIClient()
366
390
  api.auth(api_test_user, api_test_pass)
367
391
  mail = test_id + '@' + domain
368
392
  aliases = []
369
393
  api.mail_set_aliases(mail, aliases)
370
- for i in range(0, 5):
394
+ for i in range(0, 2):
371
395
  address = test_id + '_alias_' + str(i) + '@' + domain
372
396
  aliases.append(address)
373
397
  api.mail_set_aliases(mail, aliases)
@@ -376,7 +400,7 @@ class TestAPIClient:
376
400
  assert api.mail_get(mail)['aliases'] == []
377
401
  api.deauth()
378
402
 
379
- @pytest.mark.depends(name=["test_mail_add"])
403
+ @pytest.mark.depends(name="test_mail_add")
380
404
  def test_mail_set_forwards(self):
381
405
  api = APIClient.APIClient()
382
406
  api.auth(api_test_user, api_test_pass)
@@ -390,7 +414,7 @@ class TestAPIClient:
390
414
  assert api.mail_get(mail)['forwards'] == forwards
391
415
  api.deauth()
392
416
 
393
- @pytest.mark.depends(name=["test_mail_add"])
417
+ @pytest.mark.depends(name="test_mail_add")
394
418
  def test_mail_set_password(self):
395
419
  api = APIClient.APIClient()
396
420
  api.auth(api_test_user, api_test_pass)
@@ -400,7 +424,7 @@ class TestAPIClient:
400
424
  assert api.mail_set_password(mail, generate_pw()) == api.mail_get(mail)
401
425
  api.deauth()
402
426
 
403
- @pytest.mark.depends(name=["test_mail_add"])
427
+ @pytest.mark.depends(name="test_mail_add")
404
428
  def test_mail_set_password_require_reset(self):
405
429
  api = APIClient.APIClient()
406
430
  api.auth(api_test_user, api_test_pass)
@@ -410,7 +434,25 @@ class TestAPIClient:
410
434
  assert api.mail_set_password_require_reset(mail, generate_pw()) == api.mail_get(mail)
411
435
  api.deauth()
412
436
 
413
- @pytest.mark.depends(name=["test_mail_add"])
437
+ def test_mail_set_additional_mail_quota(self):
438
+ api = APIClient.APIClient()
439
+ api.auth(api_test_user, api_test_pass)
440
+ mail = test_id + '@' + domain
441
+ additional_mail_quota = 23
442
+ api.mail_set_additional_mail_quota(mail, additional_mail_quota)
443
+ assert additional_mail_quota == api.mail_get(mail)['additional_mail_quota']
444
+ api.deauth()
445
+
446
+ def test_mail_set_additional_cloud_quota(self):
447
+ api = APIClient.APIClient()
448
+ api.auth(api_test_user, api_test_pass)
449
+ mail = test_id + '@' + domain
450
+ additional_cloud_quota = 42
451
+ api.mail_set_additional_cloud_quota(mail, additional_cloud_quota)
452
+ assert additional_cloud_quota == api.mail_get(mail)['additional_cloud_quota']
453
+ api.deauth()
454
+
455
+ @pytest.mark.depends(name="test_mail_add")
414
456
  def test_mail_apppassword_add(self):
415
457
  api = APIClient.APIClient()
416
458
  api.auth(api_test_user, api_test_pass)
@@ -420,7 +462,7 @@ class TestAPIClient:
420
462
  assert len(api.mail_apppassword_list(mail)) == len_before + 1
421
463
  api.deauth()
422
464
 
423
- @pytest.mark.depends(name=["test_mail_add"])
465
+ @pytest.mark.depends(name="test_mail_add")
424
466
  def test_mail_apppassword_list(self):
425
467
  api = APIClient.APIClient()
426
468
  api.auth(api_test_user, api_test_pass)
@@ -428,9 +470,9 @@ class TestAPIClient:
428
470
  assert len(api.mail_apppassword_list(mail)) > 0
429
471
  api.deauth()
430
472
 
431
- @pytest.mark.depends(name=["test_mail_add"])
432
- @pytest.mark.depends(name=['test_mail_apppassword_add'])
433
- @pytest.mark.depends(name=['test_mail_apppassword_list'])
473
+ @pytest.mark.depends(name="test_mail_add")
474
+ @pytest.mark.depends(name='test_mail_apppassword_add')
475
+ @pytest.mark.depends(name='test_mail_apppassword_list')
434
476
  def test_mail_apppassword_del(self):
435
477
  api = APIClient.APIClient()
436
478
  api.auth(api_test_user, api_test_pass)
@@ -445,8 +487,9 @@ class TestAPIClient:
445
487
 
446
488
  # After deleting all app passwords, length should be 0
447
489
  assert len(api.mail_apppassword_list(mail)) == 0
490
+ api.deauth()
448
491
 
449
- @pytest.mark.depends(name=['test_mail_add'])
492
+ @pytest.mark.depends(name='test_mail_add')
450
493
  def test_mail_set_deletion_date(self):
451
494
  api = APIClient.APIClient()
452
495
  api.auth(api_test_user, api_test_pass)
@@ -457,7 +500,47 @@ class TestAPIClient:
457
500
  assert deletion_date in api.mail_get(mail)['deletion_date']
458
501
  api.deauth()
459
502
 
460
- @pytest.mark.depends(name=['test_mail_add'])
503
+ def test_additionalmailaccount_list(self):
504
+ api = APIClient.APIClient()
505
+ api.auth(api_test_user, api_test_pass)
506
+ parent = 'parent@testbmboapi.internal'
507
+ sub = 'sub_mail@testbmboapi.internal'
508
+ assert sub in api.additionalmailaccount_list(parent)['additional_accounts']
509
+ api.deauth()
510
+
511
+ # Removed test as the API is too unrealiable.
512
+ # It oftentimes needs too much time to update and reply with the updated data for the test to work reliably
513
+ # def test_additionalmailaccount_add(self):
514
+ # api = APIClient.APIClient()
515
+ # api.auth(api_test_user, api_test_pass)
516
+ # parent_mail = test_id + '_parent@' + domain
517
+ # sub_mail = test_id + '_sub@' + domain
518
+ # pw = generate_pw()
519
+ # # Creating the accounts
520
+ # api.mail_add(parent_mail, pw, 'light', 'test parent', 'test_parent')
521
+ # api.mail_add(sub_mail, pw, 'light', 'test sub', 'test_sub' )
522
+ # # Adding it to the mail account
523
+ # assert api.additionalmailaccount_add(parent_mail, sub_mail, pw) == True
524
+ # # Before checking the result, wait for a bit
525
+ # # The mailbox API is sometimes slower than the test, resulting in failed tests
526
+ # time.sleep(5)
527
+ # # Checking that the sub account is listed as an additional account
528
+ # assert sub_mail in api.additionalmailaccount_list(parent_mail)['additional_accounts']
529
+ # api.deauth()
530
+
531
+ # @pytest.mark.depends(name='test_additionalmailaccount_add')
532
+ # def test_additionalmailaccount_delete(self):
533
+ # api = APIClient.APIClient()
534
+ # api.auth(api_test_user, api_test_pass)
535
+ # parent_mail = test_id + '_parent@' + domain
536
+ # sub_mail = test_id + '_sub@' + domain
537
+ # assert api.additionalmailaccount_delete(parent_mail, sub_mail) == True
538
+ # assert sub_mail not in api.additionalmailaccount_list(parent_mail)
539
+ # api.mail_del(parent_mail)
540
+ # api.mail_del(sub_mail)
541
+ # api.deauth()
542
+
543
+ @pytest.mark.depends(name='test_mail_add')
461
544
  def test_search(self):
462
545
  api = APIClient.APIClient()
463
546
  api.auth(api_test_user, api_test_pass)
@@ -465,6 +548,7 @@ class TestAPIClient:
465
548
  assert mail in api.search(mail)['emails']
466
549
  assert domain in api.search(domain)['domains']
467
550
  assert api_test_user in api.search(api_test_user)['accounts']
551
+ api.deauth()
468
552
 
469
553
  @pytest.mark.order('last')
470
554
  def test_mail_del(self):
File without changes
File without changes
File without changes