能够通过 API 将事件写入只读日历
Able to write events to read-only calendar via API
我认为这是 Calendar REST 中的错误 API - 但我希望找到解决方法。
简而言之,我可以通过 API 将日历事件 POST 无误地添加到只读日历。奇怪的是 365 UI 知道日历是只读的,并且不允许通过 UI 进行编辑。
这会导致我们的同步出现问题,因为当原始日历再次发布时,所有新事件都会被删除。我的问题是我如何确定我正在写入的日历具有适当的写入权限(如 UI 所做的那样),其次,这是一个我可以通过 API 写入的错误但是不通过 UI?
重现步骤:
- 获取 public,只读日历地址。例如this
- 在365中右击'My calendars'然后'open calendar'
- 将 (1) 中的地址粘贴到 'internet calendar' 字段中。日历应显示在 'My Calendars' 下。 请注意,您无法通过 UI
为此日历创建活动
- 使用
GET https://outlook.office.com/api/v1.0/me/calendars
获取新添加的日历ID
- 使用
POST https://outlook.office.com/api/v1.0/me/calendars/[CALENDAR_ID]/events
为新日历创建活动。
预期行为
与 UI 一样,API 不允许您写入此日历。
实际行为
创建成功,返回201创建。惊喜!一段时间后(4-6 小时),新创建的事件将被删除。如果您正在同步此日历,这会导致问题,因为删除将传播到与该日历同步的任何客户端。
感谢您报告此事。我对此进行了调查,不幸的是 目前 没有一个很好的答案。这是我们正在努力改进的内容,以使 API 与 Outlook 和 OWA 更加一致。不幸的是,我没有任何时间表可以分享。
基本上,当您订阅 Internet 日历时,会在邮箱中创建一个辅助日历。它不是真正的只读,但 Outlook 和 OWA 知道它用于与 Internet 日历同步,不会让您在那里创建项目。该逻辑全部在客户端上,而不是在服务器上,这就是它今天的行为方式的原因。
下次启动与 webcal URL 的同步过程时,该事件将被删除,因为它不存在于从 webcal link 下拉的 ICS 中。
作为解决方法,如果您愿意深入研究 /beta
端点,您可以在日历上检索 PidTagExtendedFolderFlags
属性。这是一个二进制 属性,因此您需要对其进行一些解析以获取数据。格式记录在 MS-OXOCFG. You'd need to parse for the sub-property 中,其中 Id
等于 0x01,然后测试 Data
作为 0x40 位的位掩码。如果已设置,则该文件夹应被视为只读。
要获得此 属性,您需要在 Calendar
实体上展开 SingleValueExtendedProperties
,如下所示:
GET https://outlook.office.com/api/beta/me/calendars?
$expand=SingleValueExtendedProperties($filter=PropertyId eq 'Binary 0x36da')
这将 return 类似于:
{
"value": [
{
"Id": "AAMkAGRm...AAA=",
"Name": "Calendar",
"Color": "Auto",
"ChangeKey": "nxdFEDVaMUqvOVUO3592PQAAFmsEKg==",
"SingleValueExtendedProperties": [
{
"PropertyId": "Binary 0x36da",
"Value": "AQQAABAA"
}
]
},
{
"Id": "AAMkAGRm...AAA=",
"Name": "Internet Calendar",
"Color": "Auto",
"ChangeKey": "nxdFEDVaMUqvOVUO3592PQAAFmsELQ==",
"SingleValueExtendedProperties": [
{
"PropertyId": "Binary 0x36da",
"Value": "AQRAJRAC"
}
]
}
]
}
这些属性的值是 base64 编码的二进制 blob。如果你解码它们,你会得到类似的东西:
- 对于日历:010400001000
- 对于 Internet 日历:010440251002
根据格式解释这些,我们有:
Id: 0x01
Cb: 0x04
Data: 0x02102540
Data
字段中设置了 0x40 位,因此其中一个是只读的。
我认为这是 Calendar REST 中的错误 API - 但我希望找到解决方法。
简而言之,我可以通过 API 将日历事件 POST 无误地添加到只读日历。奇怪的是 365 UI 知道日历是只读的,并且不允许通过 UI 进行编辑。
这会导致我们的同步出现问题,因为当原始日历再次发布时,所有新事件都会被删除。我的问题是我如何确定我正在写入的日历具有适当的写入权限(如 UI 所做的那样),其次,这是一个我可以通过 API 写入的错误但是不通过 UI?
重现步骤:
- 获取 public,只读日历地址。例如this
- 在365中右击'My calendars'然后'open calendar'
- 将 (1) 中的地址粘贴到 'internet calendar' 字段中。日历应显示在 'My Calendars' 下。 请注意,您无法通过 UI 为此日历创建活动
- 使用
GET https://outlook.office.com/api/v1.0/me/calendars
获取新添加的日历ID - 使用
POST https://outlook.office.com/api/v1.0/me/calendars/[CALENDAR_ID]/events
为新日历创建活动。
预期行为 与 UI 一样,API 不允许您写入此日历。
实际行为 创建成功,返回201创建。惊喜!一段时间后(4-6 小时),新创建的事件将被删除。如果您正在同步此日历,这会导致问题,因为删除将传播到与该日历同步的任何客户端。
感谢您报告此事。我对此进行了调查,不幸的是 目前 没有一个很好的答案。这是我们正在努力改进的内容,以使 API 与 Outlook 和 OWA 更加一致。不幸的是,我没有任何时间表可以分享。
基本上,当您订阅 Internet 日历时,会在邮箱中创建一个辅助日历。它不是真正的只读,但 Outlook 和 OWA 知道它用于与 Internet 日历同步,不会让您在那里创建项目。该逻辑全部在客户端上,而不是在服务器上,这就是它今天的行为方式的原因。
下次启动与 webcal URL 的同步过程时,该事件将被删除,因为它不存在于从 webcal link 下拉的 ICS 中。
作为解决方法,如果您愿意深入研究 /beta
端点,您可以在日历上检索 PidTagExtendedFolderFlags
属性。这是一个二进制 属性,因此您需要对其进行一些解析以获取数据。格式记录在 MS-OXOCFG. You'd need to parse for the sub-property 中,其中 Id
等于 0x01,然后测试 Data
作为 0x40 位的位掩码。如果已设置,则该文件夹应被视为只读。
要获得此 属性,您需要在 Calendar
实体上展开 SingleValueExtendedProperties
,如下所示:
GET https://outlook.office.com/api/beta/me/calendars?
$expand=SingleValueExtendedProperties($filter=PropertyId eq 'Binary 0x36da')
这将 return 类似于:
{
"value": [
{
"Id": "AAMkAGRm...AAA=",
"Name": "Calendar",
"Color": "Auto",
"ChangeKey": "nxdFEDVaMUqvOVUO3592PQAAFmsEKg==",
"SingleValueExtendedProperties": [
{
"PropertyId": "Binary 0x36da",
"Value": "AQQAABAA"
}
]
},
{
"Id": "AAMkAGRm...AAA=",
"Name": "Internet Calendar",
"Color": "Auto",
"ChangeKey": "nxdFEDVaMUqvOVUO3592PQAAFmsELQ==",
"SingleValueExtendedProperties": [
{
"PropertyId": "Binary 0x36da",
"Value": "AQRAJRAC"
}
]
}
]
}
这些属性的值是 base64 编码的二进制 blob。如果你解码它们,你会得到类似的东西:
- 对于日历:010400001000
- 对于 Internet 日历:010440251002
根据格式解释这些,我们有:
Id: 0x01
Cb: 0x04
Data: 0x02102540
Data
字段中设置了 0x40 位,因此其中一个是只读的。