yandex360 3.2.0 → 4.0.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +110 -1
- data/README.md +112 -121
- data/README.ru.md +109 -119
- data/lib/yandex360/client.rb +8 -1
- data/lib/yandex360/objects/types.rb +42 -0
- data/lib/yandex360/resources/departments.rb +5 -2
- data/lib/yandex360/resources/dns.rb +6 -3
- data/lib/yandex360/resources/domains.rb +42 -10
- data/lib/yandex360/resources/groups.rb +7 -0
- data/lib/yandex360/resources/mail_settings.rb +72 -0
- data/lib/yandex360/resources/organizations.rb +14 -4
- data/lib/yandex360/resources/two_fa.rb +35 -15
- data/lib/yandex360/resources/users.rb +2 -1
- data/lib/yandex360/version.rb +1 -1
- metadata +2 -2
- data/lib/yandex360/resources/post_settings.rb +0 -36
data/README.ru.md
CHANGED
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
Добавьте эту строку в `Gemfile` вашего приложения:
|
|
59
59
|
|
|
60
60
|
```ruby
|
|
61
|
-
gem 'yandex360', '~>
|
|
61
|
+
gem 'yandex360', '~> 4.0'
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
Затем выполните:
|
|
@@ -85,6 +85,11 @@ gem install yandex360
|
|
|
85
85
|
|
|
86
86
|
## Переход с 1.x
|
|
87
87
|
|
|
88
|
+
Пришли с 3.x? Ломающие изменения 4.0 перечислены в
|
|
89
|
+
[changelog](CHANGELOG.md): четыре ресурса обращались к эндпоинтам, которых не
|
|
90
|
+
существует, и исправлены.
|
|
91
|
+
|
|
92
|
+
|
|
88
93
|
Два мажора произошли разом: 1.1.4 была последней опубликованной версией перед
|
|
89
94
|
3.0.0. Здесь всё, что требует вашего внимания. Обоснования в
|
|
90
95
|
[changelog](CHANGELOG.md).
|
|
@@ -387,9 +392,15 @@ users.auto_paginate.each {|user| puts user.nickname }
|
|
|
387
392
|
first_fifty = client.users.list(org_id: 1234567, per_page: 25).auto_paginate.first(50)
|
|
388
393
|
```
|
|
389
394
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
395
|
+
Пагинируются не все списки, и те, что пагинируются, делают это по-разному.
|
|
396
|
+
`users`, `groups`, `departments`, `external_contacts`, `domains`, `dns` и два
|
|
397
|
+
списка почтовых ящиков принимают `page` и `per_page`. `organizations` и оба
|
|
398
|
+
аудит-лога листаются токеном, поэтому принимают `page_size` и не принимают
|
|
399
|
+
`page`. Участники групп, права доступа к ящикам и сервисные приложения
|
|
400
|
+
отвечают целиком и не принимают ни того, ни другого.
|
|
401
|
+
|
|
402
|
+
Аргументы исходного вызова, такие как `per_page` или `parent_id` у
|
|
403
|
+
подразделений, переносятся на следующие страницы.
|
|
393
404
|
|
|
394
405
|
## Объекты ответа
|
|
395
406
|
|
|
@@ -537,7 +548,7 @@ Yandex 360, к которой относится. Покрыты все семн
|
|
|
537
548
|
| | `client.external_contacts` | [Внешние контакты](#внешние-контакты) |
|
|
538
549
|
| Домены | `client.domains` | [Домены](#домены) |
|
|
539
550
|
| | `client.dns` | [DNS-записи](#dns-записи) |
|
|
540
|
-
| Почта | `client.
|
|
551
|
+
| Почта | `client.mail_settings` | [Настройки почты](#настройки-почты) |
|
|
541
552
|
| | `client.mailboxes` | [Почтовые ящики](#почтовые-ящики) |
|
|
542
553
|
| | `client.routing` | [Маршрутизация почты](#маршрутизация-почты) |
|
|
543
554
|
| | `client.domain_policies` | [Политики домена](#политики-домена) |
|
|
@@ -570,6 +581,10 @@ puts "Email: #{org.email}"
|
|
|
570
581
|
puts "План подписки: #{org.subscription_plan}"
|
|
571
582
|
```
|
|
572
583
|
|
|
584
|
+
У сервиса есть список и ничего уже, поэтому здесь поиск по нему, а не запрос
|
|
585
|
+
одной организации. Токен обычно даёт доступ к одной организации, так что на
|
|
586
|
+
практике это один запрос.
|
|
587
|
+
|
|
573
588
|
---
|
|
574
589
|
|
|
575
590
|
### Пользователи
|
|
@@ -900,53 +915,43 @@ client.external_contacts.delete(org_id: 1234567, contact_id: created.id)
|
|
|
900
915
|
|
|
901
916
|
### Домены
|
|
902
917
|
|
|
903
|
-
Управление доменами организации и проверка владения.
|
|
904
|
-
|
|
905
|
-
#### Получить список доменов
|
|
906
|
-
|
|
907
918
|
```ruby
|
|
908
|
-
domains = client.domains.list(org_id: 1234567)
|
|
909
|
-
domains.each
|
|
910
|
-
puts "Домен: #{domain.name}"
|
|
911
|
-
puts "Статус: #{domain.status}"
|
|
912
|
-
puts "Подтверждён: #{domain.verified}"
|
|
913
|
-
end
|
|
914
|
-
```
|
|
915
|
-
|
|
916
|
-
#### Добавить домен
|
|
919
|
+
domains = client.domains.list(org_id: 1234567, page: 1, per_page: 10)
|
|
920
|
+
domains.each {|domain| puts "#{domain.name} подтверждён=#{domain.verified}" }
|
|
917
921
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
org_id: 1234567,
|
|
921
|
-
name: "example.ru"
|
|
922
|
-
)
|
|
923
|
-
puts "Добавлен домен: #{domain.name}"
|
|
924
|
-
puts "Статус проверки: #{domain.status}"
|
|
922
|
+
client.domains.add(org_id: 1234567, name: "example.com")
|
|
923
|
+
client.domains.delete(org_id: 1234567, domain: "example.com")
|
|
925
924
|
```
|
|
926
925
|
|
|
927
|
-
|
|
926
|
+
Эндпоинта для чтения одного домена нет, поэтому `find` обходит список. Это
|
|
927
|
+
стоит запроса на страницу, а не одного, отсюда и имя:
|
|
928
928
|
|
|
929
929
|
```ruby
|
|
930
|
-
|
|
931
|
-
puts "Домен: #{domain.name}"
|
|
932
|
-
puts "Статус: #{domain.status}"
|
|
933
|
-
puts "Подтверждён: #{domain.verified}"
|
|
934
|
-
puts "Email главного администратора: #{domain.master_admin}"
|
|
930
|
+
client.domains.find(org_id: 1234567, domain: "example.com")
|
|
935
931
|
```
|
|
936
932
|
|
|
937
|
-
|
|
933
|
+
Статус подключения несёт методы подтверждения и их коды, то есть ровно то, что
|
|
934
|
+
нужно для подтверждения домена:
|
|
938
935
|
|
|
939
936
|
```ruby
|
|
940
|
-
|
|
941
|
-
|
|
937
|
+
status = client.domains.connection_status(org_id: 1234567, domain: "example.com")
|
|
938
|
+
status.status
|
|
939
|
+
status.methods.each {|method| puts "#{method.method}: #{method.code}" }
|
|
942
940
|
```
|
|
943
941
|
|
|
944
|
-
|
|
942
|
+
Подпись DKIM:
|
|
945
943
|
|
|
946
944
|
```ruby
|
|
947
|
-
client.domains.
|
|
945
|
+
dkim = client.domains.dkim_status(org_id: 1234567, domain: "example.com")
|
|
946
|
+
dkim.enabled
|
|
947
|
+
dkim.public_key
|
|
948
|
+
|
|
949
|
+
client.domains.enable_dkim(org_id: 1234567, domain: "example.com")
|
|
950
|
+
client.domains.disable_dkim(org_id: 1234567, domain: "example.com")
|
|
948
951
|
```
|
|
949
952
|
|
|
953
|
+
Кириллические домены передаются в Punycode, как указано в документации API.
|
|
954
|
+
|
|
950
955
|
---
|
|
951
956
|
|
|
952
957
|
### DNS-записи
|
|
@@ -1024,53 +1029,51 @@ client.dns.delete(
|
|
|
1024
1029
|
|
|
1025
1030
|
### Настройки почты
|
|
1026
1031
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
#### Получить настройки почты пользователя
|
|
1032
|
+
Настройки отдельного сотрудника: автоматический сбор контактов, имя
|
|
1033
|
+
отправителя и подписи, правила автоответа и пересылки.
|
|
1030
1034
|
|
|
1031
1035
|
```ruby
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
```
|
|
1036
|
+
# Автоматический сбор контактов
|
|
1037
|
+
book = client.mail_settings.address_book(org_id: 1234567, user_id: 987654321)
|
|
1038
|
+
book.collect_addresses
|
|
1036
1039
|
|
|
1037
|
-
|
|
1040
|
+
client.mail_settings.update_address_book(
|
|
1041
|
+
org_id: 1234567, user_id: 987654321, collect_addresses: false
|
|
1042
|
+
)
|
|
1038
1043
|
|
|
1039
|
-
|
|
1040
|
-
|
|
1044
|
+
# Имя отправителя, основной адрес и подписи
|
|
1045
|
+
info = client.mail_settings.sender_info(org_id: 1234567, user_id: 987654321)
|
|
1046
|
+
puts "#{info.from_name} <#{info.default_from}>"
|
|
1047
|
+
info.signs.each {|sign| puts sign.text }
|
|
1048
|
+
|
|
1049
|
+
client.mail_settings.update_sender_info(
|
|
1041
1050
|
org_id: 1234567,
|
|
1042
1051
|
user_id: 987654321,
|
|
1043
|
-
|
|
1044
|
-
|
|
1052
|
+
from_name: "Иван Иванов",
|
|
1053
|
+
sign_position: "under" # либо "bottom", значение по умолчанию
|
|
1045
1054
|
)
|
|
1046
1055
|
```
|
|
1047
1056
|
|
|
1048
|
-
|
|
1057
|
+
Автоответы и пересылки это два вида одного правила, и приходят они вместе:
|
|
1049
1058
|
|
|
1050
1059
|
```ruby
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
user_id: 987654321
|
|
1055
|
-
)
|
|
1060
|
+
rules = client.mail_settings.rules(org_id: 1234567, user_id: 987654321)
|
|
1061
|
+
rules.autoreplies
|
|
1062
|
+
rules.forwards
|
|
1056
1063
|
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
# Добавить адрес пересылки
|
|
1062
|
-
client.post_settings.add_forwarding(
|
|
1063
|
-
org_id: 1234567,
|
|
1064
|
-
user_id: 987654321,
|
|
1065
|
-
address: "forward@example.ru"
|
|
1064
|
+
# Одно правило за вызов, одного вида. Автоответ:
|
|
1065
|
+
created = client.mail_settings.create_rule(
|
|
1066
|
+
org_id: 1234567, user_id: 987654321,
|
|
1067
|
+
rule_name: "В отпуске", text: "Вернусь в понедельник"
|
|
1066
1068
|
)
|
|
1067
1069
|
|
|
1068
|
-
#
|
|
1069
|
-
client.
|
|
1070
|
-
org_id: 1234567,
|
|
1071
|
-
|
|
1072
|
-
address: "forward@example.ru"
|
|
1070
|
+
# Либо пересылка:
|
|
1071
|
+
client.mail_settings.create_rule(
|
|
1072
|
+
org_id: 1234567, user_id: 987654321,
|
|
1073
|
+
rule_name: "В архив", address: "archive@example.com", with_store: true
|
|
1073
1074
|
)
|
|
1075
|
+
|
|
1076
|
+
client.mail_settings.delete_rule(org_id: 1234567, user_id: 987654321, rule_id: created.rule_id)
|
|
1074
1077
|
```
|
|
1075
1078
|
|
|
1076
1079
|
---
|
|
@@ -1219,51 +1222,33 @@ puts "Список очищен"
|
|
|
1219
1222
|
|
|
1220
1223
|
### Двухфакторная аутентификация (2FA)
|
|
1221
1224
|
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
+
Обязательная 2FA для всей организации. Все три вызова идут по одному пути и
|
|
1226
|
+
различаются только глаголом, поэтому отдельных эндпоинтов для включения и
|
|
1227
|
+
выключения нет.
|
|
1225
1228
|
|
|
1226
1229
|
```ruby
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
#### Отключить 2FA для пользователя
|
|
1232
|
-
|
|
1233
|
-
```ruby
|
|
1234
|
-
result = client.two_fa.disable(org_id: 1234567, user_id: 987654321)
|
|
1235
|
-
puts "2FA успешно отключена"
|
|
1236
|
-
```
|
|
1237
|
-
|
|
1238
|
-
#### Проверить статус 2FA пользователя
|
|
1230
|
+
settings = client.two_fa.status(org_id: 1234567)
|
|
1231
|
+
settings.enabled
|
|
1232
|
+
settings.duration # секунд, на которые сотрудник может отложить настройку
|
|
1233
|
+
settings.enabled_at
|
|
1239
1234
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1235
|
+
# duration обязателен: значения по умолчанию у API нет.
|
|
1236
|
+
client.two_fa.enable(
|
|
1237
|
+
org_id: 1234567,
|
|
1238
|
+
duration: 3600,
|
|
1239
|
+
logout_users: true, # необязательно, завершает все сессии
|
|
1240
|
+
validation_method: "phone" # необязательно, "default" или "phone"
|
|
1241
|
+
)
|
|
1247
1242
|
|
|
1248
|
-
|
|
1249
|
-
domain_status = client.two_fa.domain_status(org_id: 1234567)
|
|
1250
|
-
puts "2FA включена для домена: #{domain_status.enabled}"
|
|
1243
|
+
client.two_fa.disable(org_id: 1234567)
|
|
1251
1244
|
```
|
|
1252
1245
|
|
|
1253
|
-
|
|
1246
|
+
Персональная 2FA находится не здесь. Она относится к сотруднику, поэтому живёт
|
|
1247
|
+
на `users`:
|
|
1254
1248
|
|
|
1255
1249
|
```ruby
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
org_id: 1234567,
|
|
1259
|
-
enabled: true
|
|
1260
|
-
)
|
|
1261
|
-
|
|
1262
|
-
# Отключить 2FA для всего домена
|
|
1263
|
-
result = client.two_fa.configure_domain(
|
|
1264
|
-
org_id: 1234567,
|
|
1265
|
-
enabled: false
|
|
1266
|
-
)
|
|
1250
|
+
client.users.get2FA(org_id: 1234567, user_id: 987654321)
|
|
1251
|
+
client.users.delete_2fa_phone(org_id: 1234567, user_id: 987654321)
|
|
1267
1252
|
```
|
|
1268
1253
|
|
|
1269
1254
|
---
|
|
@@ -1379,7 +1364,7 @@ client.service_applications.delete(org_id: 1234567)
|
|
|
1379
1364
|
|
|
1380
1365
|
```ruby
|
|
1381
1366
|
# Каталог
|
|
1382
|
-
organizations.list
|
|
1367
|
+
organizations.list(page_size: 10, page_token: nil)
|
|
1383
1368
|
organizations.info(org_id:)
|
|
1384
1369
|
users.add(org_id:, dep_id:, **user_params)
|
|
1385
1370
|
users.add_alias(org_id:, user_id:, user_alias:)
|
|
@@ -1407,6 +1392,7 @@ groups.info(org_id:, group_id:)
|
|
|
1407
1392
|
groups.params(org_id:, group_id:) # deprecated, use info
|
|
1408
1393
|
groups.list(org_id:, page: 1, per_page: 10)
|
|
1409
1394
|
groups.users(org_id:, group_id:)
|
|
1395
|
+
groups.members(org_id:, group_id:)
|
|
1410
1396
|
groups.create(org_id:, name:, **group_params)
|
|
1411
1397
|
groups.delete(org_id:, group_id:)
|
|
1412
1398
|
groups.delete_user(org_id:, group_id:, type:, user_id:)
|
|
@@ -1419,22 +1405,27 @@ external_contacts.update_emails(org_id:, contact_id:, emails:)
|
|
|
1419
1405
|
external_contacts.update_phones(org_id:, contact_id:, phones:)
|
|
1420
1406
|
|
|
1421
1407
|
# Домены
|
|
1422
|
-
domains.list(org_id:)
|
|
1408
|
+
domains.list(org_id:, page: 1, per_page: 10)
|
|
1409
|
+
domains.find(org_id:, domain:)
|
|
1423
1410
|
domains.add(org_id:, name:, **params)
|
|
1424
|
-
domains.info(org_id:, domain:)
|
|
1425
1411
|
domains.delete(org_id:, domain:)
|
|
1426
|
-
domains.
|
|
1427
|
-
|
|
1412
|
+
domains.connection_status(org_id:, domain:)
|
|
1413
|
+
domains.dkim_status(org_id:, domain:)
|
|
1414
|
+
domains.enable_dkim(org_id:, domain:)
|
|
1415
|
+
domains.disable_dkim(org_id:, domain:)
|
|
1416
|
+
dns.list(org_id:, domain:, page: 1, per_page: 50)
|
|
1428
1417
|
dns.create(org_id:, domain:, **params)
|
|
1429
1418
|
dns.update(org_id:, domain:, record_id:, **params)
|
|
1430
1419
|
dns.delete(org_id:, domain:, record_id:)
|
|
1431
1420
|
|
|
1432
1421
|
# Почта
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1422
|
+
mail_settings.address_book(org_id:, user_id:)
|
|
1423
|
+
mail_settings.update_address_book(org_id:, user_id:, collect_addresses:)
|
|
1424
|
+
mail_settings.sender_info(org_id:, user_id:)
|
|
1425
|
+
mail_settings.update_sender_info(org_id:, user_id:, **params)
|
|
1426
|
+
mail_settings.rules(org_id:, user_id:)
|
|
1427
|
+
mail_settings.create_rule(org_id:, user_id:, **params)
|
|
1428
|
+
mail_settings.delete_rule(org_id:, user_id:, rule_id:)
|
|
1438
1429
|
mailboxes.shared_list(org_id:, page: 1, per_page: 10)
|
|
1439
1430
|
mailboxes.create_shared(org_id:, email:, name:, description:)
|
|
1440
1431
|
mailboxes.shared_info(org_id:, resource_id:)
|
|
@@ -1456,11 +1447,10 @@ antispam.create(org_id, *strings)
|
|
|
1456
1447
|
antispam.delete(org_id:)
|
|
1457
1448
|
|
|
1458
1449
|
# Безопасность
|
|
1459
|
-
two_fa.
|
|
1460
|
-
two_fa.
|
|
1461
|
-
two_fa.
|
|
1450
|
+
two_fa.status(org_id:)
|
|
1451
|
+
two_fa.enable(org_id:, duration:, logout_users: nil, validation_method: nil)
|
|
1452
|
+
two_fa.disable(org_id:)
|
|
1462
1453
|
two_fa.domain_status(org_id:)
|
|
1463
|
-
two_fa.configure_domain(org_id:, enabled:)
|
|
1464
1454
|
sessions.info(org_id:)
|
|
1465
1455
|
sessions.update(org_id:, auth_ttl:)
|
|
1466
1456
|
sessions.logout(org_id:, user_id:)
|
data/lib/yandex360/client.rb
CHANGED
|
@@ -83,8 +83,15 @@ module Yandex360
|
|
|
83
83
|
AuditResource.new(self)
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
+
def mail_settings
|
|
87
|
+
MailSettingsResource.new(self)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Deprecated: the old name, for a resource that called paths the API does
|
|
91
|
+
# not have. Removed in 5.0.
|
|
86
92
|
def post_settings
|
|
87
|
-
|
|
93
|
+
warn "[yandex360] client.post_settings is deprecated, use client.mail_settings", uplevel: 1
|
|
94
|
+
mail_settings
|
|
88
95
|
end
|
|
89
96
|
|
|
90
97
|
def sessions
|
|
@@ -88,6 +88,12 @@ module Yandex360
|
|
|
88
88
|
attribute :created_at, from: "createdAt"
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
+
class GroupMembers < Record
|
|
92
|
+
attribute :departments
|
|
93
|
+
attribute :groups
|
|
94
|
+
attribute :users
|
|
95
|
+
end
|
|
96
|
+
|
|
91
97
|
class Alias < Record
|
|
92
98
|
attribute :alias
|
|
93
99
|
attribute :id
|
|
@@ -104,6 +110,16 @@ module Yandex360
|
|
|
104
110
|
attribute :status
|
|
105
111
|
end
|
|
106
112
|
|
|
113
|
+
class DomainStatus < Record
|
|
114
|
+
attribute :status
|
|
115
|
+
attribute :methods
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
class DomainDkim < Record
|
|
119
|
+
attribute :enabled
|
|
120
|
+
attribute :public_key, from: "publicKey"
|
|
121
|
+
end
|
|
122
|
+
|
|
107
123
|
class DnsRecord < Record
|
|
108
124
|
attribute :record_id, from: "recordId"
|
|
109
125
|
attribute :type
|
|
@@ -227,6 +243,32 @@ module Yandex360
|
|
|
227
243
|
attribute :roles
|
|
228
244
|
end
|
|
229
245
|
|
|
246
|
+
class Domain2FA < Record
|
|
247
|
+
attribute :enabled
|
|
248
|
+
attribute :duration
|
|
249
|
+
attribute :enabled_at, from: "enabledAt"
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
class MailAddressBook < Record
|
|
253
|
+
attribute :collect_addresses, from: "collectAddresses"
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
class MailSenderInfo < Record
|
|
257
|
+
attribute :from_name, from: "fromName"
|
|
258
|
+
attribute :default_from, from: "defaultFrom"
|
|
259
|
+
attribute :signs
|
|
260
|
+
attribute :sign_position, from: "signPosition"
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
class MailUserRules < Record
|
|
264
|
+
attribute :autoreplies
|
|
265
|
+
attribute :forwards
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
class MailRule < Record
|
|
269
|
+
attribute :rule_id, from: "ruleId"
|
|
270
|
+
end
|
|
271
|
+
|
|
230
272
|
class MailboxTask < Record
|
|
231
273
|
attribute :task_id, from: "taskId"
|
|
232
274
|
attribute :status
|
|
@@ -6,7 +6,9 @@ module Yandex360
|
|
|
6
6
|
def add_alias(org_id:, dep_id:, name:)
|
|
7
7
|
validate_required_params({org_id: org_id, dep_id: dep_id, name: name}, %i[org_id dep_id name])
|
|
8
8
|
dep_alias = {alias: name}
|
|
9
|
-
|
|
9
|
+
# The reply is the whole department, aliases included.
|
|
10
|
+
Department.new post("/directory/v1/org/#{org_id}/departments/#{dep_id}/aliases",
|
|
11
|
+
body: dep_alias).body
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def update(org_id:, dep_id:, parent_id:, **params)
|
|
@@ -52,7 +54,8 @@ module Yandex360
|
|
|
52
54
|
|
|
53
55
|
def delete_alias(org_id:, dep_id:, name:)
|
|
54
56
|
validate_required_params({org_id: org_id, dep_id: dep_id, name: name}, %i[org_id dep_id name])
|
|
55
|
-
|
|
57
|
+
path = "/directory/v1/org/#{org_id}/departments/#{dep_id}/aliases/#{name}"
|
|
58
|
+
DepartmentAlias.new delete_request(path).body
|
|
56
59
|
end
|
|
57
60
|
|
|
58
61
|
def delete(org_id:, dep_id:)
|
|
@@ -4,10 +4,13 @@ module Yandex360
|
|
|
4
4
|
class DnsResource < Resource
|
|
5
5
|
include ParamBuilder
|
|
6
6
|
|
|
7
|
-
def list(org_id:, domain:)
|
|
7
|
+
def list(org_id:, domain:, page: 1, per_page: 50)
|
|
8
8
|
validate_required_params({org_id: org_id, domain: domain}, %i[org_id domain])
|
|
9
|
-
resp = get("/directory/v1/org/#{org_id}/domains/#{domain}/dns"
|
|
10
|
-
|
|
9
|
+
resp = get("/directory/v1/org/#{org_id}/domains/#{domain}/dns",
|
|
10
|
+
params: {page: page, perPage: per_page})
|
|
11
|
+
Collection.from_response(resp, key: "records", type: DnsRecord) do |next_page|
|
|
12
|
+
list(org_id: org_id, domain: domain, page: next_page, per_page: per_page)
|
|
13
|
+
end
|
|
11
14
|
end
|
|
12
15
|
|
|
13
16
|
def create(org_id:, domain:, **params)
|
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Yandex360
|
|
4
|
+
# Domains, their connection status and their DKIM signature.
|
|
5
|
+
#
|
|
6
|
+
# There is no endpoint for reading one domain: the service offers a list and
|
|
7
|
+
# nothing narrower, so #find filters what the list returns.
|
|
8
|
+
#
|
|
9
|
+
# See https://yandex.ru/dev/api360/doc/ru/ref/DomainService/
|
|
4
10
|
class DomainsResource < Resource
|
|
5
11
|
include ParamBuilder
|
|
6
12
|
|
|
7
|
-
|
|
13
|
+
# per_page is capped at 10 by the API.
|
|
14
|
+
def list(org_id:, page: 1, per_page: 10)
|
|
8
15
|
validate_required_params({org_id: org_id}, [:org_id])
|
|
9
|
-
resp = get("/directory/v1/org/#{org_id}/domains")
|
|
10
|
-
Collection.from_response(resp, key: "domains", type: Domain)
|
|
16
|
+
resp = get("/directory/v1/org/#{org_id}/domains", params: {page: page, perPage: per_page})
|
|
17
|
+
Collection.from_response(resp, key: "domains", type: Domain) do |next_page|
|
|
18
|
+
list(org_id: org_id, page: next_page, per_page: per_page)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Walks the list until the name matches, because the API has nothing to ask
|
|
23
|
+
# for a single domain with. Costs one request per page rather than one.
|
|
24
|
+
def find(org_id:, domain:)
|
|
25
|
+
validate_required_params({org_id: org_id, domain: domain}, %i[org_id domain])
|
|
26
|
+
list(org_id: org_id).auto_paginate.find {|candidate| candidate.name == domain }
|
|
11
27
|
end
|
|
12
28
|
|
|
13
29
|
def add(org_id:, name:, **params)
|
|
@@ -16,19 +32,35 @@ module Yandex360
|
|
|
16
32
|
Domain.new post("/directory/v1/org/#{org_id}/domains", body: domain).body
|
|
17
33
|
end
|
|
18
34
|
|
|
19
|
-
def
|
|
35
|
+
def delete(org_id:, domain:)
|
|
20
36
|
validate_required_params({org_id: org_id, domain: domain}, %i[org_id domain])
|
|
21
|
-
|
|
37
|
+
Response.new delete_request(domain_path(org_id, domain)).body
|
|
22
38
|
end
|
|
23
39
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
40
|
+
# Carries the confirmation methods and their codes, which is what domain
|
|
41
|
+
# verification actually needs.
|
|
42
|
+
def connection_status(org_id:, domain:)
|
|
43
|
+
DomainStatus.new get("#{domain_path(org_id, domain)}/status").body
|
|
27
44
|
end
|
|
28
45
|
|
|
29
|
-
def
|
|
46
|
+
def dkim_status(org_id:, domain:)
|
|
47
|
+
DomainDkim.new get("#{domain_path(org_id, domain)}/dkim").body
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def enable_dkim(org_id:, domain:)
|
|
51
|
+
Response.new post("#{domain_path(org_id, domain)}/dkim/enable", body: {}).body
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def disable_dkim(org_id:, domain:)
|
|
55
|
+
Response.new post("#{domain_path(org_id, domain)}/dkim/disable", body: {}).body
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
# Cyrillic domains have to be given in Punycode, as the API documents.
|
|
61
|
+
def domain_path(org_id, domain)
|
|
30
62
|
validate_required_params({org_id: org_id, domain: domain}, %i[org_id domain])
|
|
31
|
-
|
|
63
|
+
"/directory/v1/org/#{org_id}/domains/#{domain}"
|
|
32
64
|
end
|
|
33
65
|
end
|
|
34
66
|
end
|
|
@@ -46,6 +46,13 @@ module Yandex360
|
|
|
46
46
|
Collection.from_response(resp, key: "users", type: User)
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
+
# A group can hold departments and other groups as well as employees, and
|
|
50
|
+
# the endpoint answers all three. #users shows only one of them.
|
|
51
|
+
def members(org_id:, group_id:)
|
|
52
|
+
validate_required_params({org_id: org_id, group_id: group_id}, %i[org_id group_id])
|
|
53
|
+
GroupMembers.new get("/directory/v1/org/#{org_id}/groups/#{group_id}/members").body
|
|
54
|
+
end
|
|
55
|
+
|
|
49
56
|
def create(org_id:, name:, **group_params)
|
|
50
57
|
validate_required_params({org_id: org_id, name: name}, %i[org_id name])
|
|
51
58
|
group = build_params({name: name}, group_params)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Yandex360
|
|
4
|
+
# Per-employee mail settings: automatic contact collection, the sender name
|
|
5
|
+
# and signatures, and the auto-reply and forwarding rules.
|
|
6
|
+
#
|
|
7
|
+
# All three live under /admin/v1/org/{orgId}/mail/users/{userId}/settings.
|
|
8
|
+
#
|
|
9
|
+
# See https://yandex.ru/dev/api360/doc/ru/ref/MailUserSettingsService/
|
|
10
|
+
class MailSettingsResource < Resource
|
|
11
|
+
include ParamBuilder
|
|
12
|
+
|
|
13
|
+
def address_book(org_id:, user_id:)
|
|
14
|
+
MailAddressBook.new get(settings_path(org_id, user_id, "address_book")).body
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def update_address_book(org_id:, user_id:, collect_addresses:)
|
|
18
|
+
required = {org_id: org_id, user_id: user_id}
|
|
19
|
+
validate_required_params(required, %i[org_id user_id])
|
|
20
|
+
body = {collectAddresses: collect_addresses}
|
|
21
|
+
MailAddressBook.new post(settings_path(org_id, user_id, "address_book"), body: body).body
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def sender_info(org_id:, user_id:)
|
|
25
|
+
MailSenderInfo.new get(settings_path(org_id, user_id, "sender_info")).body
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Accepts from_name, default_from, signs and sign_position; the API
|
|
29
|
+
# documents them in camelCase, so they are converted here.
|
|
30
|
+
def update_sender_info(org_id:, user_id:, **params)
|
|
31
|
+
validate_required_params({org_id: org_id, user_id: user_id}, %i[org_id user_id])
|
|
32
|
+
body = camelize(build_params({}, params))
|
|
33
|
+
MailSenderInfo.new post(settings_path(org_id, user_id, "sender_info"), body: body).body
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Auto-reply and forwarding rules arrive together, under separate keys.
|
|
37
|
+
def rules(org_id:, user_id:)
|
|
38
|
+
MailUserRules.new get(settings_path(org_id, user_id, "user_rules")).body
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# One rule per call, and of one kind: an auto-reply takes rule_name and
|
|
42
|
+
# text, a forward takes rule_name, address and with_store.
|
|
43
|
+
def create_rule(org_id:, user_id:, **params)
|
|
44
|
+
validate_required_params({org_id: org_id, user_id: user_id}, %i[org_id user_id])
|
|
45
|
+
raise ArgumentError, "Provide the rule attributes" if params.empty?
|
|
46
|
+
|
|
47
|
+
body = camelize(build_params({}, params))
|
|
48
|
+
MailRule.new post(settings_path(org_id, user_id, "user_rules"), body: body).body
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def delete_rule(org_id:, user_id:, rule_id:)
|
|
52
|
+
required = {org_id: org_id, user_id: user_id, rule_id: rule_id}
|
|
53
|
+
validate_required_params(required, %i[org_id user_id rule_id])
|
|
54
|
+
Response.new delete_request("#{settings_path(org_id, user_id, 'user_rules')}/#{rule_id}").body
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def settings_path(org_id, user_id, setting)
|
|
60
|
+
validate_required_params({org_id: org_id, user_id: user_id}, %i[org_id user_id])
|
|
61
|
+
"/admin/v1/org/#{org_id}/mail/users/#{user_id}/settings/#{setting}"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Callers write snake_case here as they do everywhere else in the gem.
|
|
65
|
+
def camelize(params)
|
|
66
|
+
params.transform_keys do |key|
|
|
67
|
+
head, *rest = key.to_s.split("_")
|
|
68
|
+
[head, *rest.map(&:capitalize)].join.to_sym
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -2,14 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
module Yandex360
|
|
4
4
|
class OrganizationsResource < Resource
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
# Pages by token rather than page number, so there is no page argument.
|
|
6
|
+
# page_size is capped at 100 by the API.
|
|
7
|
+
def list(page_size: 10, page_token: nil)
|
|
8
|
+
params = {pageSize: page_size}
|
|
9
|
+
params[:pageToken] = page_token unless page_token.nil?
|
|
10
|
+
|
|
11
|
+
resp = get("/directory/v1/org", params: params)
|
|
12
|
+
Collection.from_response(resp, key: "organizations", type: Organization) do |token|
|
|
13
|
+
list(page_size: page_size, page_token: token)
|
|
14
|
+
end
|
|
8
15
|
end
|
|
9
16
|
|
|
17
|
+
# OrganizationsService offers a list and nothing narrower, so this walks
|
|
18
|
+
# it. The token usually reaches one organization, so it is a single
|
|
19
|
+
# request in practice, but it is a search rather than a fetch.
|
|
10
20
|
def info(org_id:)
|
|
11
21
|
validate_required_params({org_id: org_id}, [:org_id])
|
|
12
|
-
|
|
22
|
+
list.auto_paginate.find {|organization| organization.id.to_s == org_id.to_s }
|
|
13
23
|
end
|
|
14
24
|
end
|
|
15
25
|
end
|