Add privacy set/get to API
This commit is contained in:
parent
30ed293dc6
commit
af344bb77c
@ -79,10 +79,10 @@ namespace PluralKit
|
|||||||
[JsonIgnore] public string Token { get; set; }
|
[JsonIgnore] public string Token { get; set; }
|
||||||
[JsonProperty("created")] public Instant Created { get; set; }
|
[JsonProperty("created")] public Instant Created { get; set; }
|
||||||
[JsonProperty("tz")] public string UiTz { get; set; }
|
[JsonProperty("tz")] public string UiTz { get; set; }
|
||||||
public PrivacyLevel DescriptionPrivacy { get; set; }
|
[JsonProperty("description_privacy")] public PrivacyLevel DescriptionPrivacy { get; set; }
|
||||||
public PrivacyLevel MemberListPrivacy { get; set; }
|
[JsonProperty("member_list_privacy")] public PrivacyLevel MemberListPrivacy { get; set; }
|
||||||
public PrivacyLevel FrontPrivacy { get; set; }
|
[JsonProperty("front_privacy")] public PrivacyLevel FrontPrivacy { get; set; }
|
||||||
public PrivacyLevel FrontHistoryPrivacy { get; set; }
|
[JsonProperty("front_history_privacy")] public PrivacyLevel FrontHistoryPrivacy { get; set; }
|
||||||
|
|
||||||
[JsonIgnore] public DateTimeZone Zone => DateTimeZoneProviders.Tzdb.GetZoneOrNull(UiTz);
|
[JsonIgnore] public DateTimeZone Zone => DateTimeZoneProviders.Tzdb.GetZoneOrNull(UiTz);
|
||||||
|
|
||||||
@ -96,6 +96,10 @@ namespace PluralKit
|
|||||||
o.Add("avatar_url", AvatarUrl);
|
o.Add("avatar_url", AvatarUrl);
|
||||||
o.Add("created", Formats.TimestampExportFormat.Format(Created));
|
o.Add("created", Formats.TimestampExportFormat.Format(Created));
|
||||||
o.Add("tz", UiTz);
|
o.Add("tz", UiTz);
|
||||||
|
o.Add("description_privacy", ctx == LookupContext.ByOwner ? (DescriptionPrivacy == PrivacyLevel.Private ? "private" : "public") : null);
|
||||||
|
o.Add("member_list_privacy", ctx == LookupContext.ByOwner ? (MemberListPrivacy == PrivacyLevel.Private ? "private" : "public") : null);
|
||||||
|
o.Add("front_privacy", ctx == LookupContext.ByOwner ? (FrontPrivacy == PrivacyLevel.Private ? "private" : "public") : null);
|
||||||
|
o.Add("front_history_privacy", ctx == LookupContext.ByOwner ? (FrontHistoryPrivacy == PrivacyLevel.Private ? "private" : "public") : null);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,6 +110,34 @@ namespace PluralKit
|
|||||||
if (o.ContainsKey("tag")) Tag = o.Value<string>("tag").NullIfEmpty().BoundsCheck(Limits.MaxSystemTagLength, "System tag");
|
if (o.ContainsKey("tag")) Tag = o.Value<string>("tag").NullIfEmpty().BoundsCheck(Limits.MaxSystemTagLength, "System tag");
|
||||||
if (o.ContainsKey("avatar_url")) AvatarUrl = o.Value<string>("avatar_url").NullIfEmpty();
|
if (o.ContainsKey("avatar_url")) AvatarUrl = o.Value<string>("avatar_url").NullIfEmpty();
|
||||||
if (o.ContainsKey("tz")) UiTz = o.Value<string>("tz") ?? "UTC";
|
if (o.ContainsKey("tz")) UiTz = o.Value<string>("tz") ?? "UTC";
|
||||||
|
|
||||||
|
if (o.ContainsKey("description_privacy")) {
|
||||||
|
var val = o.Value<string>("description_privacy").NullIfEmpty();
|
||||||
|
if(val == null || val == "public") DescriptionPrivacy = PrivacyLevel.Public;
|
||||||
|
else if(val == "private") DescriptionPrivacy = PrivacyLevel.Private;
|
||||||
|
else throw new PKParseError("Could not parse description privacy.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.ContainsKey("member_list_privacy")) {
|
||||||
|
var val = o.Value<string>("member_list_privacy").NullIfEmpty();
|
||||||
|
if(val == null || val == "public") MemberListPrivacy = PrivacyLevel.Public;
|
||||||
|
else if(val == "private") MemberListPrivacy = PrivacyLevel.Private;
|
||||||
|
else throw new PKParseError("Could not parse member list privacy.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.ContainsKey("front_privacy")) {
|
||||||
|
var val = o.Value<string>("front_privacy").NullIfEmpty();
|
||||||
|
if(val == null || val == "public") FrontPrivacy = PrivacyLevel.Public;
|
||||||
|
else if(val == "private") FrontPrivacy = PrivacyLevel.Private;
|
||||||
|
else throw new PKParseError("Could not parse front privacy.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.ContainsKey("front_history_privacy")) {
|
||||||
|
var val = o.Value<string>("front_history_privacy").NullIfEmpty();
|
||||||
|
if(val == null || val == "public") FrontHistoryPrivacy = PrivacyLevel.Public;
|
||||||
|
else if(val == "private") FrontHistoryPrivacy = PrivacyLevel.Private;
|
||||||
|
else throw new PKParseError("Could not parse front history privacy.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,8 +157,7 @@ namespace PluralKit
|
|||||||
[JsonProperty("proxy_tags")] public ICollection<ProxyTag> ProxyTags { get; set; }
|
[JsonProperty("proxy_tags")] public ICollection<ProxyTag> ProxyTags { get; set; }
|
||||||
[JsonProperty("keep_proxy")] public bool KeepProxy { get; set; }
|
[JsonProperty("keep_proxy")] public bool KeepProxy { get; set; }
|
||||||
[JsonProperty("created")] public Instant Created { get; set; }
|
[JsonProperty("created")] public Instant Created { get; set; }
|
||||||
|
[JsonProperty("privacy")] public PrivacyLevel MemberPrivacy { get; set; }
|
||||||
public PrivacyLevel MemberPrivacy { get; set; }
|
|
||||||
|
|
||||||
/// Returns a formatted string representing the member's birthday, taking into account that a year of "0001" or "0004" is hidden
|
/// Returns a formatted string representing the member's birthday, taking into account that a year of "0001" or "0004" is hidden
|
||||||
/// Before Feb 10 2020, the sentinel year was 0001, now it is 0004.
|
/// Before Feb 10 2020, the sentinel year was 0001, now it is 0004.
|
||||||
@ -160,6 +191,7 @@ namespace PluralKit
|
|||||||
o.Add("pronouns", MemberPrivacy.CanAccess(ctx) ? Pronouns : null);
|
o.Add("pronouns", MemberPrivacy.CanAccess(ctx) ? Pronouns : null);
|
||||||
o.Add("avatar_url", AvatarUrl);
|
o.Add("avatar_url", AvatarUrl);
|
||||||
o.Add("description", MemberPrivacy.CanAccess(ctx) ? Description : null);
|
o.Add("description", MemberPrivacy.CanAccess(ctx) ? Description : null);
|
||||||
|
o.Add("privacy", ctx == LookupContext.ByOwner ? (MemberPrivacy == PrivacyLevel.Private ? "private" : "public") : null);
|
||||||
|
|
||||||
var tagArray = new JArray();
|
var tagArray = new JArray();
|
||||||
foreach (var tag in ProxyTags)
|
foreach (var tag in ProxyTags)
|
||||||
@ -208,6 +240,13 @@ namespace PluralKit
|
|||||||
.OfType<JObject>().Select(o => new ProxyTag(o.Value<string>("prefix"), o.Value<string>("suffix")))
|
.OfType<JObject>().Select(o => new ProxyTag(o.Value<string>("prefix"), o.Value<string>("suffix")))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (o.ContainsKey("privacy")) {
|
||||||
|
var val = o.Value<string>("privacy").NullIfEmpty();
|
||||||
|
if (val == null || val == "public") MemberPrivacy = PrivacyLevel.Public;
|
||||||
|
else if (val == "private") MemberPrivacy = PrivacyLevel.Private;
|
||||||
|
else throw new PKParseError("Could not parse member privacy.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,10 @@ The following three models (usually represented in JSON format) represent the va
|
|||||||
|avatar_url|url?|Yes|Not validated server-side.|
|
|avatar_url|url?|Yes|Not validated server-side.|
|
||||||
|tz|string?|Yes|Tzdb identifier. Patching with `null` will store `"UTC"`.|
|
|tz|string?|Yes|Tzdb identifier. Patching with `null` will store `"UTC"`.|
|
||||||
|created|datetime|No||
|
|created|datetime|No||
|
||||||
|
|description_privacy|string?|Yes|Patching with `private` will set it to private; `public` or `null` will set it to public.|
|
||||||
|
|member_list_privacy|string?|Yes|Same as above.|
|
||||||
|
|front_privacy|string?|Yes|Same as above.|
|
||||||
|
|front_history_privacy|string?|Yes|Same as above.|
|
||||||
|
|
||||||
### Member model
|
### Member model
|
||||||
|
|
||||||
@ -57,6 +61,7 @@ The following three models (usually represented in JSON format) represent the va
|
|||||||
|proxy_tags|ProxyTag[]|Yes (entire array)|An array of ProxyTag (see below) objects, each representing a single prefix/suffix pair.|
|
|proxy_tags|ProxyTag[]|Yes (entire array)|An array of ProxyTag (see below) objects, each representing a single prefix/suffix pair.|
|
||||||
|keep_proxy|bool|Yes|Whether to display a member's proxy tags in the proxied message.|
|
|keep_proxy|bool|Yes|Whether to display a member's proxy tags in the proxied message.|
|
||||||
|created|datetime|No||
|
|created|datetime|No||
|
||||||
|
|privacy|string?|Yes|Patching with `private` will set it to private; `public` or `null` will set it to public.|
|
||||||
|
|
||||||
#### ProxyTag object
|
#### ProxyTag object
|
||||||
|
|
||||||
@ -103,7 +108,11 @@ Returns information about your own system.
|
|||||||
"tag": "[MySys]",
|
"tag": "[MySys]",
|
||||||
"avatar_url": "https://path/to/avatar/image.png",
|
"avatar_url": "https://path/to/avatar/image.png",
|
||||||
"tz": "Europe/Copenhagen",
|
"tz": "Europe/Copenhagen",
|
||||||
"created": "2019-01-01T14:30:00.987654Z"
|
"created": "2019-01-01T14:30:00.987654Z",
|
||||||
|
"description_privacy": "private",
|
||||||
|
"member_list_privacy": "public",
|
||||||
|
"front_privacy": "public",
|
||||||
|
"front_history_privacy": "private"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -123,7 +132,11 @@ Some fields may be set to `null` if unauthenticated and the system has chosen to
|
|||||||
"tag": "[MySys]",
|
"tag": "[MySys]",
|
||||||
"avatar_url": "https://path/to/avatar/image.png",
|
"avatar_url": "https://path/to/avatar/image.png",
|
||||||
"tz": "Europe/Copenhagen",
|
"tz": "Europe/Copenhagen",
|
||||||
"created": "2019-01-01T14:30:00.987654Z"
|
"created": "2019-01-01T14:30:00.987654Z",
|
||||||
|
"description_privacy": null,
|
||||||
|
"member_list_privacy": null,
|
||||||
|
"front_privacy": null,
|
||||||
|
"front_history_privacy": null
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -148,7 +161,8 @@ If the request is not authenticated with the system's token, members marked as p
|
|||||||
"description": "I am Craig, example user extraordinaire.",
|
"description": "I am Craig, example user extraordinaire.",
|
||||||
"proxy_tags": [{"prefix": "[", "suffix": "]"}],
|
"proxy_tags": [{"prefix": "[", "suffix": "]"}],
|
||||||
"keep_proxy": false,
|
"keep_proxy": false,
|
||||||
"created": "2019-01-01T15:00:00.654321Z"
|
"created": "2019-01-01T15:00:00.654321Z",
|
||||||
|
"privacy": null
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
@ -212,7 +226,7 @@ If the system has chosen to hide its current fronters, this will return `403 For
|
|||||||
### PATCH /s
|
### PATCH /s
|
||||||
**Requires authentication.**
|
**Requires authentication.**
|
||||||
|
|
||||||
Edits your own system's information. Missing fields will be set to `null`. Will return the new system object.
|
Edits your own system's information. Missing fields will keep their current values. Will return the new system object.
|
||||||
|
|
||||||
#### Example request
|
#### Example request
|
||||||
PATCH https://api.pluralkit.me/v1/s
|
PATCH https://api.pluralkit.me/v1/s
|
||||||
@ -222,7 +236,11 @@ Edits your own system's information. Missing fields will be set to `null`. Will
|
|||||||
"name": "New System Name",
|
"name": "New System Name",
|
||||||
"tag": "{Sys}",
|
"tag": "{Sys}",
|
||||||
"avatar_url": "https://path/to/new/avatar.png",
|
"avatar_url": "https://path/to/new/avatar.png",
|
||||||
"tz": "America/New_York"
|
"tz": "America/New_York",
|
||||||
|
"description_privacy": "private",
|
||||||
|
"member_list_privacy": "public",
|
||||||
|
"front_privacy": "public",
|
||||||
|
"front_history_privacy": "private"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
(note the absence of a `description` field, which has its old value preserved in the response)
|
(note the absence of a `description` field, which has its old value preserved in the response)
|
||||||
@ -236,7 +254,11 @@ Edits your own system's information. Missing fields will be set to `null`. Will
|
|||||||
"tag": "{Sys}",
|
"tag": "{Sys}",
|
||||||
"avatar_url": "https://path/to/new/avatar.png",
|
"avatar_url": "https://path/to/new/avatar.png",
|
||||||
"tz": "America/New_York",
|
"tz": "America/New_York",
|
||||||
"created": "2019-01-01T14:30:00.987654Z"
|
"created": "2019-01-01T14:30:00.987654Z",
|
||||||
|
"description_privacy": "private",
|
||||||
|
"member_list_privacy": "public",
|
||||||
|
"front_privacy": "public",
|
||||||
|
"front_history_privacy": "private"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -259,7 +281,7 @@ Registers a new switch to your own system given a list of member IDs.
|
|||||||
|
|
||||||
### GET /m/\<id>
|
### GET /m/\<id>
|
||||||
Queries a member's information by its 5-character member ID. If the member does not exist, will return `404 Not Found`.
|
Queries a member's information by its 5-character member ID. If the member does not exist, will return `404 Not Found`.
|
||||||
If this member is marked private, and the request isn't authenticated with the member's system's token, some fields (currently only `description`) will contain `null` rather than the true value.
|
If this member is marked private, and the request isn't authenticated with the member's system's token, some fields (currently only `description`) will contain `null` rather than the true value. Regardless of privacy setting, a non-authenticated request will only receive `null` for the `privacy` field.
|
||||||
|
|
||||||
#### Example request
|
#### Example request
|
||||||
GET https://api.pluralkit.me/v1/m/qwert
|
GET https://api.pluralkit.me/v1/m/qwert
|
||||||
@ -276,7 +298,8 @@ If this member is marked private, and the request isn't authenticated with the m
|
|||||||
"description": "I am Craig, example user extraordinaire.",
|
"description": "I am Craig, example user extraordinaire.",
|
||||||
"proxy_tags": [{"prefix": "[", "suffix": "]"}],
|
"proxy_tags": [{"prefix": "[", "suffix": "]"}],
|
||||||
"keep_proxy": false,
|
"keep_proxy": false,
|
||||||
"created": "2019-01-01T15:00:00.654321Z"
|
"created": "2019-01-01T15:00:00.654321Z",
|
||||||
|
"privacy": "public"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -297,7 +320,8 @@ Creates a new member with the information given. Missing fields (except for name
|
|||||||
"birthday": "1997-07-14",
|
"birthday": "1997-07-14",
|
||||||
"pronouns": "they/them",
|
"pronouns": "they/them",
|
||||||
"description": "I am Craig, cooler example user extraordinaire.",
|
"description": "I am Craig, cooler example user extraordinaire.",
|
||||||
"keep_proxy": false
|
"keep_proxy": false,
|
||||||
|
"privacy": "public"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
(note the absence of a `proxy_tags` field, which is cleared in the response)
|
(note the absence of a `proxy_tags` field, which is cleared in the response)
|
||||||
@ -315,14 +339,15 @@ Creates a new member with the information given. Missing fields (except for name
|
|||||||
"description": "I am Craig, cooler example user extraordinaire.",
|
"description": "I am Craig, cooler example user extraordinaire.",
|
||||||
"proxy_tags": [],
|
"proxy_tags": [],
|
||||||
"keep_proxy": false,
|
"keep_proxy": false,
|
||||||
"created": "2019-01-01T15:00:00.654321Z"
|
"created": "2019-01-01T15:00:00.654321Z",
|
||||||
|
"privacy": "public"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### PATCH /m/\<id>
|
### PATCH /m/\<id>
|
||||||
**Requires authentication.**
|
**Requires authentication.**
|
||||||
|
|
||||||
Edits a member's information. Missing fields will be set to `null`. Will return the new member object. Member must (obviously) belong to your own system.
|
Edits a member's information. Missing fields will keep their current values. Will return the new member object. Member must (obviously) belong to your own system.
|
||||||
|
|
||||||
#### Example request
|
#### Example request
|
||||||
PATCH https://api.pluralkit.me/v1/m/qwert
|
PATCH https://api.pluralkit.me/v1/m/qwert
|
||||||
@ -336,7 +361,8 @@ Edits a member's information. Missing fields will be set to `null`. Will return
|
|||||||
"birthday": "1997-07-14",
|
"birthday": "1997-07-14",
|
||||||
"pronouns": "they/them",
|
"pronouns": "they/them",
|
||||||
"description": "I am Craig, cooler example user extraordinaire.",
|
"description": "I am Craig, cooler example user extraordinaire.",
|
||||||
"keep_proxy": false
|
"keep_proxy": false,
|
||||||
|
"privacy": "public"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
(note the absence of a `proxy_tags` field, which keeps its old value in the response)
|
(note the absence of a `proxy_tags` field, which keeps its old value in the response)
|
||||||
@ -354,7 +380,8 @@ Edits a member's information. Missing fields will be set to `null`. Will return
|
|||||||
"description": "I am Craig, cooler example user extraordinaire.",
|
"description": "I am Craig, cooler example user extraordinaire.",
|
||||||
"proxy_tags": [{"prefix": "[", "suffix": "]"}],
|
"proxy_tags": [{"prefix": "[", "suffix": "]"}],
|
||||||
"keep_proxy": false,
|
"keep_proxy": false,
|
||||||
"created": "2019-01-01T15:00:00.654321Z"
|
"created": "2019-01-01T15:00:00.654321Z",
|
||||||
|
"privacy": "public"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -385,7 +412,11 @@ Some fields may be set to `null` if unauthenticated and the system has chosen to
|
|||||||
"tag": "[MySys]",
|
"tag": "[MySys]",
|
||||||
"avatar_url": "https://path/to/avatar/image.png",
|
"avatar_url": "https://path/to/avatar/image.png",
|
||||||
"tz": "Europe/Copenhagen",
|
"tz": "Europe/Copenhagen",
|
||||||
"created": "2019-01-01T14:30:00.987654Z"
|
"created": "2019-01-01T14:30:00.987654Z",
|
||||||
|
"description_privacy": null,
|
||||||
|
"member_list_privacy": null,
|
||||||
|
"front_privacy": null,
|
||||||
|
"front_history_privacy": null
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -433,6 +464,7 @@ The returned system and member's privacy settings will be respected, and as such
|
|||||||
## Version history
|
## Version history
|
||||||
* 2020-02-10
|
* 2020-02-10
|
||||||
* Birthdates with no year can now be stored using `0004` as a year, for better leap year support. Both options remain valid and either may be returned by the API.
|
* Birthdates with no year can now be stored using `0004` as a year, for better leap year support. Both options remain valid and either may be returned by the API.
|
||||||
|
* Added privacy set/get support, meaning you will now see privacy values in authed requests and can set them.
|
||||||
* 2020-01-08
|
* 2020-01-08
|
||||||
* Added privacy support, meaning some responses will now lack information or return 403s, depending on the specific system and member's privacy settings.
|
* Added privacy support, meaning some responses will now lack information or return 403s, depending on the specific system and member's privacy settings.
|
||||||
* 2019-12-28
|
* 2019-12-28
|
||||||
|
Loading…
Reference in New Issue
Block a user