undo temp fix and clean out some warnings

This commit is contained in:
Gordon Pedersen 2024-05-02 14:54:14 +10:00
parent dcf599bf1e
commit 8223bf8d34
9 changed files with 80 additions and 11 deletions

View file

@ -6,11 +6,23 @@ using Object = KristofferStrube.ActivityStreams.Object;
namespace ActivityPub; namespace ActivityPub;
/// <summary>
/// An enum to differentiate inbox and outbox data stores
/// </summary>
public enum ActivityStoreType { public enum ActivityStoreType {
/// <summary>
/// For indicating an Inbox activity store
/// </summary>
Inbox, Inbox,
/// <summary>
/// For indicating an Outbox activity store
/// </summary>
Outbox Outbox
} }
/// <summary>
/// A class representing the data store for activities
/// </summary>
public class ActivityStore { public class ActivityStore {
private static Dictionary<string, Activity> _outbox = new(); private static Dictionary<string, Activity> _outbox = new();
private static Dictionary<string, Activity> _inbox = new(); private static Dictionary<string, Activity> _inbox = new();
@ -96,7 +108,7 @@ public class ActivityStore {
public Activity InsertActivity(Activity newActivity, bool runSideEffects = true, bool runDelivery = true) { public Activity InsertActivity(Activity newActivity, bool runSideEffects = true, bool runDelivery = true) {
string id = NewId; string id = NewId;
string uriId = this.Url.AbsoluteRouteUrl(ActivityStoreType == ActivityStoreType.Inbox ? "GetInboxById" : "GetOutboxById", new { id }).ToLower(); string? uriId = Url.AbsoluteRouteUrl(ActivityStoreType == ActivityStoreType.Inbox ? "GetInboxById" : "GetOutboxById", new { id })?.ToLower();
List<Uri> recipients = runDelivery ? ExtractRecipients(newActivity) : new List<Uri>(); List<Uri> recipients = runDelivery ? ExtractRecipients(newActivity) : new List<Uri>();
newActivity.Id = uriId; newActivity.Id = uriId;
newActivity.Bto = newActivity.Bcc = null; newActivity.Bto = newActivity.Bcc = null;
@ -156,7 +168,7 @@ public class ActivityStore {
IntransitiveActivity activity = (IntransitiveActivity)newActivity; IntransitiveActivity activity = (IntransitiveActivity)newActivity;
if (activity is Arrive) return Arrive((Arrive)activity); if (activity is Arrive) return Arrive((Arrive)activity);
else if (activity is Travel) return Travel((Travel)activity); else if (activity is Travel) return Travel((Travel)activity);
// else if (activity is Question) return Question((Question)activity); // TODO: Temporary until question is intransitory again else if (activity is Question) return Question((Question)activity);
else throw new InvalidOperationException($"Activity type '{activity.Type?.FirstOrDefault()}' is unrecognized"); else throw new InvalidOperationException($"Activity type '{activity.Type?.FirstOrDefault()}' is unrecognized");
} }
@ -188,7 +200,6 @@ public class ActivityStore {
else if (activity is TentativeReject) return TentativeReject((TentativeReject)activity); else if (activity is TentativeReject) return TentativeReject((TentativeReject)activity);
else if (activity is TentativeAccept) return TentativeAccept((TentativeAccept)activity); else if (activity is TentativeAccept) return TentativeAccept((TentativeAccept)activity);
else if (activity is View) return View((View)activity); else if (activity is View) return View((View)activity);
else if (activity is Question) return Question((Question)activity); // TODO: Temporary until question is intransitory again
else throw new InvalidOperationException($"Activity type '{activity.Type?.FirstOrDefault()}' is unrecognized"); else throw new InvalidOperationException($"Activity type '{activity.Type?.FirstOrDefault()}' is unrecognized");
} }
} }

View file

@ -1,9 +1,18 @@
namespace ActivityPub; namespace ActivityPub;
/// <summary>
/// The context urls for JSON-LD
/// </summary>
public class Context { public class Context {
/// <summary>
/// The ActivityStreams context
/// </summary>
public static readonly Uri ActivityStreams = new("https://www.w3.org/ns/activitystreams"); public static readonly Uri ActivityStreams = new("https://www.w3.org/ns/activitystreams");
} }
/// <summary>
/// Known collection urls
/// </summary>
public class Collections { public class Collections {
/// <summary> /// <summary>
/// The public address for delivery. /// The public address for delivery.

View file

@ -26,7 +26,7 @@ public class OutboxController : ControllerBase {
/// Method to create and process a new object. /// Method to create and process a new object.
/// See https://www.w3.org/TR/activitypub/#client-to-server-interactions /// See https://www.w3.org/TR/activitypub/#client-to-server-interactions
/// </summary> /// </summary>
/// <param name="newData">The data for the Activity or Object to create</param> /// <param name="newObjectOrLink">The data for the Activity or Object to create</param>
/// <returns> /// <returns>
/// 201 (Created) on success with the new id in the Location header /// 201 (Created) on success with the new id in the Location header
/// TODO: Also currently returns the newly created Action to assist in debugging. /// TODO: Also currently returns the newly created Action to assist in debugging.
@ -44,7 +44,7 @@ public class OutboxController : ControllerBase {
return this.BadRequest($"No valid Activity or Object found in the request body"); return this.BadRequest($"No valid Activity or Object found in the request body");
Activity newActivity = (newObjectOrLink is Activity) ? (Activity)newObjectOrLink Activity newActivity = (newObjectOrLink is Activity) ? (Activity)newObjectOrLink
: Outbox.WrapObjectInCreate(newObjectOrLink as Object); : Outbox.WrapObjectInCreate((Object)newObjectOrLink);
//// Validate the activity //// Validate the activity
//try { //try {

View file

@ -7,6 +7,9 @@ using Object = KristofferStrube.ActivityStreams.Object;
namespace ActivityPub; namespace ActivityPub;
/// <summary>
/// A Data layer to store objects
/// </summary>
public class ObjectStore { public class ObjectStore {
private static Dictionary<string, Dictionary<string, Object>> _objects = new(); private static Dictionary<string, Dictionary<string, Object>> _objects = new();
private IUrlHelper Url { get; set; } private IUrlHelper Url { get; set; }

View file

@ -43,6 +43,10 @@ public class ActivityPubContext : DbContext {
options.UseSqlite($"Data Source={DbPath}"); options.UseSqlite($"Data Source={DbPath}");
} }
/// <summary>
/// configuration for these models
/// </summary>
/// <param name="modelBuilder">the model builder to configure</param>
protected override void OnModelCreating(ModelBuilder modelBuilder) { protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder.Entity<Activity>().HasMany(_ => _.Actor as IEnumerable<Actor>); modelBuilder.Entity<Activity>().HasMany(_ => _.Actor as IEnumerable<Actor>);
modelBuilder.Entity<Activity>().HasMany(_ => _.Object as IEnumerable<ObjectOrLink>); modelBuilder.Entity<Activity>().HasMany(_ => _.Object as IEnumerable<ObjectOrLink>);

View file

@ -185,14 +185,43 @@ public static class Types {
"Mention" "Mention"
]; ];
/// <summary>
/// Checks if the object type is an activity type
/// </summary>
/// <param name="type">The type of the object</param>
/// <returns>A boolean indicating whether the object is an activity type</returns>
public static bool IsActivity(string type) => Activity.Contains(type); public static bool IsActivity(string type) => Activity.Contains(type);
//public static bool IsActivity(this Object obj) => obj.Type == null ? false : IsActivity(obj.Type); //public static bool IsActivity(this Object obj) => obj.Type == null ? false : IsActivity(obj.Type);
/// <summary>
/// Checks if the object type is an actor type
/// </summary>
/// <param name="type">The type of the object</param>
/// <returns>A boolean indicating whether the object is an actor type</returns>
public static bool IsActor(string type) => Actor.Contains(type); public static bool IsActor(string type) => Actor.Contains(type);
//public static bool IsActor(this Object obj) => obj.Type == null ? false : IsActor(obj.Type); //public static bool IsActor(this Object obj) => obj.Type == null ? false : IsActor(obj.Type);
/// <summary>
/// Checks if the object type is an object type
/// </summary>
/// <param name="type">The type of the object</param>
/// <returns>A boolean indicating whether the object is an object type</returns>
public static bool IsObject(string type) => Object.Contains(type); public static bool IsObject(string type) => Object.Contains(type);
//public static bool IsObject(this Object obj) => obj.Type == null ? false : IsObject(obj.Type); //public static bool IsObject(this Object obj) => obj.Type == null ? false : IsObject(obj.Type);
/// <summary>
/// Checks if the object type is a link type
/// </summary>
/// <param name="type">The type of the object</param>
/// <returns>A boolean indicating whether the object is a link type</returns>
public static bool IsLink(string type) => Link.Contains(type); public static bool IsLink(string type) => Link.Contains(type);
//public static bool IsLink(this Object obj) => obj.Type == null ? false : IsLink(obj.Type); //public static bool IsLink(this Object obj) => obj.Type == null ? false : IsLink(obj.Type);
/// <summary>
/// Checks if the object type is an object or link type
/// </summary>
/// <param name="type">The type of the object</param>
/// <returns>A boolean indicating whether the object is an object or link type</returns>
public static bool IsObjectOrLink(string type) => Object.Concat(Link).Contains(type); public static bool IsObjectOrLink(string type) => Object.Concat(Link).Contains(type);
//public static bool IsObjectOrLink(this Object obj) => obj.Type == null ? false : IsObjectOrLink(obj.Type); //public static bool IsObjectOrLink(this Object obj) => obj.Type == null ? false : IsObjectOrLink(obj.Type);

View file

@ -1,6 +1,9 @@
namespace ActivityPub.Utils; namespace ActivityPub.Utils;
// https://stackoverflow.com/a/35004409 /// <summary>
/// Helper class for converting numbers to and from Base36 strings
/// https://stackoverflow.com/a/35004409
/// </summary>
public class Base36 public class Base36
{ {
private static readonly char[] BaseChars = private static readonly char[] BaseChars =
@ -9,6 +12,11 @@ public class Base36
.Select((c, i) => new { Char = c, Index = i }) .Select((c, i) => new { Char = c, Index = i })
.ToDictionary(c => c.Char, c => c.Index); .ToDictionary(c => c.Char, c => c.Index);
/// <summary>
/// Convert a long to a Base36 string
/// </summary>
/// <param name="value">The number to convert</param>
/// <returns>A string representing the number in Base36</returns>
public static string ToString(long value) public static string ToString(long value)
{ {
long targetBase = BaseChars.Length; long targetBase = BaseChars.Length;
@ -27,6 +35,11 @@ public class Base36
return new string(buffer, i, buffer.Length - i); return new string(buffer, i, buffer.Length - i);
} }
/// <summary>
/// Converts a Base64 string back into a number
/// </summary>
/// <param name="number">The string to convert</param>
/// <returns>The number resulting from converting the string</returns>
public static long FromString(string number) public static long FromString(string number)
{ {
char[] chrs = number.ToLower().ToCharArray(); char[] chrs = number.ToLower().ToCharArray();

View file

@ -16,11 +16,11 @@ public static class UrlHelperExtensions
/// <param name="controllerName">The name of the controller.</param> /// <param name="controllerName">The name of the controller.</param>
/// <param name="routeValues">The route values.</param> /// <param name="routeValues">The route values.</param>
/// <returns>The absolute URL.</returns> /// <returns>The absolute URL.</returns>
public static string AbsoluteAction( public static string? AbsoluteAction(
this IUrlHelper url, this IUrlHelper url,
string actionName, string actionName,
string controllerName, string controllerName,
object routeValues = null) object? routeValues = null)
{ {
return url.Action(actionName, controllerName, routeValues, url.ActionContext.HttpContext.Request.Scheme); return url.Action(actionName, controllerName, routeValues, url.ActionContext.HttpContext.Request.Scheme);
} }
@ -47,10 +47,10 @@ public static class UrlHelperExtensions
/// <param name="routeName">Name of the route.</param> /// <param name="routeName">Name of the route.</param>
/// <param name="routeValues">The route values.</param> /// <param name="routeValues">The route values.</param>
/// <returns>The absolute URL.</returns> /// <returns>The absolute URL.</returns>
public static string AbsoluteRouteUrl( public static string? AbsoluteRouteUrl(
this IUrlHelper url, this IUrlHelper url,
string routeName, string routeName,
object routeValues = null) object? routeValues = null)
{ {
return url.RouteUrl(routeName, routeValues, url.ActionContext.HttpContext.Request.Scheme); return url.RouteUrl(routeName, routeValues, url.ActionContext.HttpContext.Request.Scheme);
} }

View file

@ -15,7 +15,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="KristofferStrube.ActivityStreams" Version="0.2.2" /> <PackageReference Include="KristofferStrube.ActivityStreams" Version="0.2.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.3" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.3"> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.3">