diff --git a/greataped/components/api/handlers/factory.go b/greataped/components/api/handlers/factory.go index 1063de2..238800f 100644 --- a/greataped/components/api/handlers/factory.go +++ b/greataped/components/api/handlers/factory.go @@ -14,6 +14,7 @@ func (factory *httpHandlerFactory) Handlers() []IHttpHandler { UpdateProfileByUserHandler(), // │ P . /api/v1/profile LogoutHandler(), // │ P . /api/v1/logout WebfingerHandler(), // │ G . /.well-known/webfinger + GetActorHandler(), // │ G . /u/:username } } diff --git a/greataped/components/api/handlers/get_actor_handler.go b/greataped/components/api/handlers/get_actor_handler.go new file mode 100644 index 0000000..481d492 --- /dev/null +++ b/greataped/components/api/handlers/get_actor_handler.go @@ -0,0 +1,45 @@ +package handlers + +import ( + "net/http" + + . "github.com/xeronith/diamante/contracts/network/http" + pipeline "github.com/xeronith/diamante/network/http" + . "rail.town/infrastructure/components/api/protobuf" + . "rail.town/infrastructure/components/contracts" +) + +type getActorHandler struct { +} + +func GetActorHandler() IHttpHandler { + return &getActorHandler{} +} + +func (handler *getActorHandler) Method() string { + return http.MethodGet +} + +func (handler *getActorHandler) Path() string { + return "/u/:username" +} + +func (handler *getActorHandler) HandlerFunc() HttpHandlerFunc { + return func(x IServerDispatcher) error { + request := &GetActorRequest{} + result := &GetActorResult{} + + onRequestUnmarshalled := func(request *GetActorRequest) { + request.Username = x.Param("username") + } + + return pipeline.Handle(x, + "get_actor", + GET_ACTOR_REQUEST, + GET_ACTOR_RESULT, + request, result, + onRequestUnmarshalled, + false, + ) + } +} diff --git a/greataped/components/api/operations/factory.go b/greataped/components/api/operations/factory.go index 4eaa642..8419ebb 100644 --- a/greataped/components/api/operations/factory.go +++ b/greataped/components/api/operations/factory.go @@ -15,6 +15,7 @@ func (factory *operationFactory) Operations() []IOperation { UpdateProfileByUserOperation(), LogoutOperation(), WebfingerOperation(), + GetActorOperation(), } } diff --git a/greataped/components/api/operations/get_actor_operation.go b/greataped/components/api/operations/get_actor_operation.go new file mode 100644 index 0000000..a4901d9 --- /dev/null +++ b/greataped/components/api/operations/get_actor_operation.go @@ -0,0 +1,51 @@ +package operations + +import ( + . "github.com/xeronith/diamante/contracts/operation" + . "github.com/xeronith/diamante/contracts/service" + . "github.com/xeronith/diamante/contracts/system" + . "github.com/xeronith/diamante/operation" + . "rail.town/infrastructure/components/api/protobuf" + . "rail.town/infrastructure/components/api/services" + . "rail.town/infrastructure/components/contracts" +) + +type getActorOperation struct { + Operation + + run func(IContext, *GetActorRequest) (*GetActorResult, error) +} + +func GetActorOperation() IOperation { + return &getActorOperation{ + run: GetActorService, + } +} + +func (operation *getActorOperation) Id() (ID, ID) { + return GET_ACTOR_REQUEST, GET_ACTOR_RESULT +} + +func (operation *getActorOperation) InputContainer() Pointer { + return new(GetActorRequest) +} + +func (operation *getActorOperation) OutputContainer() Pointer { + return new(GetActorResult) +} + +func (operation *getActorOperation) Execute(context IContext, payload Pointer) (Pointer, error) { + return operation.run(context, payload.(*GetActorRequest)) +} + +/* +func (operation *getActorOperation) ExecutionTimeLimits() (Duration, Duration, Duration) { + var ( + TIME_LIMIT_WARNING Duration = 20_000_000 + TIME_LIMIT_ALERT Duration = 35_000_000 + TIME_LIMIT_CRITICAL Duration = 50_000_000 + ) + + return TIME_LIMIT_WARNING, TIME_LIMIT_ALERT, TIME_LIMIT_CRITICAL +} +*/ diff --git a/greataped/components/api/protobuf/spis.pb.go b/greataped/components/api/protobuf/spis.pb.go index 42d1237..477bf82 100644 --- a/greataped/components/api/protobuf/spis.pb.go +++ b/greataped/components/api/protobuf/spis.pb.go @@ -1024,6 +1024,214 @@ func (x *WebfingerResult) GetSubject() string { return "" } +// API: GetActor +// ----------------------------------------------------------- +type GetActorRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` +} + +func (x *GetActorRequest) Reset() { + *x = GetActorRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_spis_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetActorRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetActorRequest) ProtoMessage() {} + +func (x *GetActorRequest) ProtoReflect() protoreflect.Message { + mi := &file_spis_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetActorRequest.ProtoReflect.Descriptor instead. +func (*GetActorRequest) Descriptor() ([]byte, []int) { + return file_spis_proto_rawDescGZIP(), []int{18} +} + +func (x *GetActorRequest) GetUsername() string { + if x != nil { + return x.Username + } + return "" +} + +type GetActorResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Context []string `protobuf:"bytes,1,rep,name=context,json=@context,proto3" json:"context,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + Followers string `protobuf:"bytes,3,opt,name=followers,proto3" json:"followers,omitempty"` + Following string `protobuf:"bytes,4,opt,name=following,proto3" json:"following,omitempty"` + Inbox string `protobuf:"bytes,5,opt,name=inbox,proto3" json:"inbox,omitempty"` + Outbox string `protobuf:"bytes,6,opt,name=outbox,proto3" json:"outbox,omitempty"` + Name string `protobuf:"bytes,7,opt,name=name,proto3" json:"name,omitempty"` + PreferredUsername string `protobuf:"bytes,8,opt,name=preferredUsername,proto3" json:"preferredUsername,omitempty"` + Type string `protobuf:"bytes,9,opt,name=type,proto3" json:"type,omitempty"` + Url string `protobuf:"bytes,10,opt,name=url,proto3" json:"url,omitempty"` + Icon *ActivityPubMedia `protobuf:"bytes,11,opt,name=icon,proto3" json:"icon,omitempty"` + Image *ActivityPubMedia `protobuf:"bytes,12,opt,name=image,proto3" json:"image,omitempty"` + PublicKey *ActivityPubPublicKey `protobuf:"bytes,13,opt,name=publicKey,proto3" json:"publicKey,omitempty"` + Summary string `protobuf:"bytes,14,opt,name=summary,proto3" json:"summary,omitempty"` + Published string `protobuf:"bytes,15,opt,name=published,proto3" json:"published,omitempty"` +} + +func (x *GetActorResult) Reset() { + *x = GetActorResult{} + if protoimpl.UnsafeEnabled { + mi := &file_spis_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetActorResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetActorResult) ProtoMessage() {} + +func (x *GetActorResult) ProtoReflect() protoreflect.Message { + mi := &file_spis_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetActorResult.ProtoReflect.Descriptor instead. +func (*GetActorResult) Descriptor() ([]byte, []int) { + return file_spis_proto_rawDescGZIP(), []int{19} +} + +func (x *GetActorResult) GetContext() []string { + if x != nil { + return x.Context + } + return nil +} + +func (x *GetActorResult) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *GetActorResult) GetFollowers() string { + if x != nil { + return x.Followers + } + return "" +} + +func (x *GetActorResult) GetFollowing() string { + if x != nil { + return x.Following + } + return "" +} + +func (x *GetActorResult) GetInbox() string { + if x != nil { + return x.Inbox + } + return "" +} + +func (x *GetActorResult) GetOutbox() string { + if x != nil { + return x.Outbox + } + return "" +} + +func (x *GetActorResult) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *GetActorResult) GetPreferredUsername() string { + if x != nil { + return x.PreferredUsername + } + return "" +} + +func (x *GetActorResult) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *GetActorResult) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *GetActorResult) GetIcon() *ActivityPubMedia { + if x != nil { + return x.Icon + } + return nil +} + +func (x *GetActorResult) GetImage() *ActivityPubMedia { + if x != nil { + return x.Image + } + return nil +} + +func (x *GetActorResult) GetPublicKey() *ActivityPubPublicKey { + if x != nil { + return x.PublicKey + } + return nil +} + +func (x *GetActorResult) GetSummary() string { + if x != nil { + return x.Summary + } + return "" +} + +func (x *GetActorResult) GetPublished() string { + if x != nil { + return x.Published + } + return "" +} + var File_spis_proto protoreflect.FileDescriptor var file_spis_proto_rawDesc = []byte{ @@ -1112,8 +1320,42 @@ var file_spis_proto_rawDesc = []byte{ 0x32, 0x19, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x50, 0x75, 0x62, 0x4c, 0x69, 0x6e, 0x6b, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x6b, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x42, 0x04, 0x5a, 0x02, - 0x2e, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x2d, 0x0a, 0x0f, + 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xe5, 0x03, 0x0a, 0x0e, + 0x47, 0x65, 0x74, 0x41, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x19, + 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x08, 0x40, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x6f, 0x6c, + 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x6f, + 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x6f, 0x6c, 0x6c, + 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x62, 0x6f, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x6f, + 0x75, 0x74, 0x62, 0x6f, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, + 0x62, 0x6f, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x70, 0x72, 0x65, 0x66, 0x65, + 0x72, 0x72, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x11, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x55, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x2e, 0x0a, 0x04, 0x69, + 0x63, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x50, 0x75, 0x62, + 0x4d, 0x65, 0x64, 0x69, 0x61, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x05, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x50, 0x75, + 0x62, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, 0x3c, 0x0a, + 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x69, 0x74, 0x79, 0x50, 0x75, 0x62, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x73, + 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x75, + 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, + 0x65, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, + 0x68, 0x65, 0x64, 0x42, 0x04, 0x5a, 0x02, 0x2e, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( @@ -1128,7 +1370,7 @@ func file_spis_proto_rawDescGZIP() []byte { return file_spis_proto_rawDescData } -var file_spis_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_spis_proto_msgTypes = make([]protoimpl.MessageInfo, 20) var file_spis_proto_goTypes = []interface{}{ (*SystemCallRequest)(nil), // 0: protobuf.SystemCallRequest (*SystemCallResult)(nil), // 1: protobuf.SystemCallResult @@ -1148,18 +1390,25 @@ var file_spis_proto_goTypes = []interface{}{ (*LogoutResult)(nil), // 15: protobuf.LogoutResult (*WebfingerRequest)(nil), // 16: protobuf.WebfingerRequest (*WebfingerResult)(nil), // 17: protobuf.WebfingerResult - (*Document)(nil), // 18: protobuf.Document - (*ActivityPubLink)(nil), // 19: protobuf.ActivityPubLink + (*GetActorRequest)(nil), // 18: protobuf.GetActorRequest + (*GetActorResult)(nil), // 19: protobuf.GetActorResult + (*Document)(nil), // 20: protobuf.Document + (*ActivityPubLink)(nil), // 21: protobuf.ActivityPubLink + (*ActivityPubMedia)(nil), // 22: protobuf.ActivityPubMedia + (*ActivityPubPublicKey)(nil), // 23: protobuf.ActivityPubPublicKey } var file_spis_proto_depIdxs = []int32{ - 18, // 0: protobuf.EchoRequest.document:type_name -> protobuf.Document - 18, // 1: protobuf.EchoResult.document:type_name -> protobuf.Document - 19, // 2: protobuf.WebfingerResult.links:type_name -> protobuf.ActivityPubLink - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 20, // 0: protobuf.EchoRequest.document:type_name -> protobuf.Document + 20, // 1: protobuf.EchoResult.document:type_name -> protobuf.Document + 21, // 2: protobuf.WebfingerResult.links:type_name -> protobuf.ActivityPubLink + 22, // 3: protobuf.GetActorResult.icon:type_name -> protobuf.ActivityPubMedia + 22, // 4: protobuf.GetActorResult.image:type_name -> protobuf.ActivityPubMedia + 23, // 5: protobuf.GetActorResult.publicKey:type_name -> protobuf.ActivityPubPublicKey + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_spis_proto_init() } @@ -1385,6 +1634,30 @@ func file_spis_proto_init() { return nil } } + file_spis_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetActorRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_spis_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetActorResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -1392,7 +1665,7 @@ func file_spis_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_spis_proto_rawDesc, NumEnums: 0, - NumMessages: 18, + NumMessages: 20, NumExtensions: 0, NumServices: 0, }, diff --git a/greataped/components/api/protobuf/spis.proto b/greataped/components/api/protobuf/spis.proto index 477427a..bfbde09 100644 --- a/greataped/components/api/protobuf/spis.proto +++ b/greataped/components/api/protobuf/spis.proto @@ -114,4 +114,28 @@ message WebfingerResult { string subject = 0x00000003; } +// API: GetActor +//----------------------------------------------------------- +message GetActorRequest { + string username = 0x00000001; +} + +message GetActorResult { + repeated string context = 0x00000001 [json_name = "@context"]; + string id = 0x00000002; + string followers = 0x00000003; + string following = 0x00000004; + string inbox = 0x00000005; + string outbox = 0x00000006; + string name = 0x00000007; + string preferredUsername = 0x00000008; + string type = 0x00000009; + string url = 0x0000000A; + ActivityPubMedia icon = 0x0000000B; + ActivityPubMedia image = 0x0000000C; + ActivityPubPublicKey publicKey = 0x0000000D; + string summary = 0x0000000E; + string published = 0x0000000F; +} + //----------------------------------------------------------- diff --git a/greataped/components/api/services/get_actor_service.go b/greataped/components/api/services/get_actor_service.go new file mode 100644 index 0000000..906e2ab --- /dev/null +++ b/greataped/components/api/services/get_actor_service.go @@ -0,0 +1,74 @@ +package services + +import ( + . "github.com/xeronith/diamante/contracts/service" + . "rail.town/infrastructure/components/api/protobuf" + . "rail.town/infrastructure/components/contracts" + "rail.town/infrastructure/components/core" +) + +// noinspection GoUnusedParameter +func GetActorService(context IContext, input *GetActorRequest) (result *GetActorResult, err error) { + conductor := core.Conductor + _ = GET_ACTOR_REQUEST + + conductor.LogRemoteCall(context, INITIALIZE, "get_actor", input, result, err) + defer func() { conductor.LogRemoteCall(context, FINALIZE, "get_actor", input, result, err) }() + + _result, _err := conductor.GetActor(input.Username, context.Identity()) + if _err != nil { + err = _err + return nil, err + } + + _ = _result + + var outputIcon *ActivityPubMedia = nil + if _result.Icon() != nil { + outputIcon = &ActivityPubMedia{ + MediaType: _result.Icon().MediaType(), + Type: _result.Icon().Type(), + Url: _result.Icon().Url(), + Width: _result.Icon().Width(), + Height: _result.Icon().Height(), + } + } + + var outputImage *ActivityPubMedia = nil + if _result.Image() != nil { + outputImage = &ActivityPubMedia{ + MediaType: _result.Image().MediaType(), + Type: _result.Image().Type(), + Url: _result.Image().Url(), + Width: _result.Image().Width(), + Height: _result.Image().Height(), + } + } + + var outputPublicKey *ActivityPubPublicKey = nil + if _result.PublicKey() != nil { + outputPublicKey = &ActivityPubPublicKey{ + Id: _result.PublicKey().Id(), + Owner: _result.PublicKey().Owner(), + PublicKeyPem: _result.PublicKey().PublicKeyPem(), + } + } + + result = context.ResultContainer().(*GetActorResult) + result.Context = _result.Context() + result.Id = _result.Id() + result.Followers = _result.Followers() + result.Following = _result.Following() + result.Inbox = _result.Inbox() + result.Outbox = _result.Outbox() + result.Name = _result.Name() + result.PreferredUsername = _result.PreferredUsername() + result.Type = _result.Type() + result.Url = _result.Url() + result.Icon = outputIcon + result.Image = outputImage + result.PublicKey = outputPublicKey + result.Summary = _result.Summary() + result.Published = _result.Published() + return result, nil +} diff --git a/greataped/components/contracts/api.go b/greataped/components/contracts/api.go index da65cfa..595eaba 100644 --- a/greataped/components/contracts/api.go +++ b/greataped/components/contracts/api.go @@ -15,4 +15,5 @@ type IApi interface { UpdateProfileByUser(*UpdateProfileByUserRequest) (*UpdateProfileByUserResult, error) Logout(*LogoutRequest) (*LogoutResult, error) Webfinger(*WebfingerRequest) (*WebfingerResult, error) + GetActor(*GetActorRequest) (*GetActorResult, error) } diff --git a/greataped/components/contracts/opcodes.go b/greataped/components/contracts/opcodes.go index 8514227..c5e5b4f 100644 --- a/greataped/components/contracts/opcodes.go +++ b/greataped/components/contracts/opcodes.go @@ -39,6 +39,10 @@ const ( //WebfingerOperation WEBFINGER_REQUEST = 0x01FD357C WEBFINGER_RESULT = 0xCC81EC52 + + //GetActorOperation + GET_ACTOR_REQUEST = 0x5C4AC410 + GET_ACTOR_RESULT = 0x136B82A8 ) var OPCODES = Opcodes{ @@ -59,4 +63,6 @@ var OPCODES = Opcodes{ 0x9412D17F: "Logout", 0x01FD357C: "WEBFINGER", 0xCC81EC52: "Webfinger", + 0x5C4AC410: "GET_ACTOR", + 0x136B82A8: "GetActor", } diff --git a/greataped/components/contracts/spi.go b/greataped/components/contracts/spi.go index 8f92f16..5c09fbb 100644 --- a/greataped/components/contracts/spi.go +++ b/greataped/components/contracts/spi.go @@ -62,6 +62,7 @@ type ( UpdateProfileByUser(displayName string, avatar string, banner string, summary string, github string, editor Identity) (IUpdateProfileByUserResult, error) Logout(editor Identity) (ILogoutResult, error) Webfinger(resource string, editor Identity) (IWebfingerResult, error) + GetActor(username string, editor Identity) (IGetActorResult, error) } IEchoResult interface { @@ -107,4 +108,22 @@ type ( Links() []IActivityPubLink Subject() string } + + IGetActorResult interface { + Context() []string + Id() string + Followers() string + Following() string + Inbox() string + Outbox() string + Name() string + PreferredUsername() string + Type() string + Url() string + Icon() IActivityPubMedia + Image() IActivityPubMedia + PublicKey() IActivityPubPublicKey + Summary() string + Published() string + } ) diff --git a/greataped/components/contracts/system_dispatcher.go b/greataped/components/contracts/system_dispatcher.go index b4b87c2..14b7dcc 100644 --- a/greataped/components/contracts/system_dispatcher.go +++ b/greataped/components/contracts/system_dispatcher.go @@ -1039,6 +1039,7 @@ type IDispatcher interface { UpdateProfileByUser(displayName string, avatar string, banner string, summary string, github string) (IUpdateProfileByUserResult, error) Logout() (ILogoutResult, error) Webfinger(resource string) (IWebfingerResult, error) + GetActor(username string) (IGetActorResult, error) // NewDocument creates a new 'Document' instance using the provided property values. NewDocument(id int64, content string) (IDocument, error) @@ -1124,6 +1125,8 @@ type IDispatcher interface { NewLogoutResult() ILogoutResult // NewWebfingerResult creates a new result container for 'Webfinger' system action. NewWebfingerResult(aliases []string, links []IActivityPubLink, subject string) IWebfingerResult + // NewGetActorResult creates a new result container for 'Get Actor' system action. + NewGetActorResult(context []string, id string, followers string, following string, inbox string, outbox string, name string, preferredUsername string, type_ string, url string, icon IActivityPubMedia, image IActivityPubMedia, publicKey IActivityPubPublicKey, summary string, published string) IGetActorResult // Assert asserts the provided condition and panics if the assertion is not valid. Assert(condition bool) IAssertionResult // AssertNoError panics if the provided error is not nil. diff --git a/greataped/components/core/api_methods.go b/greataped/components/core/api_methods.go index dcd7d98..ee925b0 100644 --- a/greataped/components/core/api_methods.go +++ b/greataped/components/core/api_methods.go @@ -95,6 +95,16 @@ func (api *api) Webfinger(request *WebfingerRequest) (*WebfingerResult, error) { } } +func (api *api) GetActor(request *GetActorRequest) (*GetActorResult, error) { + result, err := api.call(GET_ACTOR_REQUEST, request) + + if err != nil { + return nil, err + } else { + return result.(*GetActorResult), nil + } +} + func init() { API_RESULT[SYSTEM_CALL_RESULT] = SystemCallResult{} API_RESULT[ECHO_RESULT] = EchoResult{} @@ -105,4 +115,5 @@ func init() { API_RESULT[UPDATE_PROFILE_BY_USER_RESULT] = UpdateProfileByUserResult{} API_RESULT[LOGOUT_RESULT] = LogoutResult{} API_RESULT[WEBFINGER_RESULT] = WebfingerResult{} + API_RESULT[GET_ACTOR_RESULT] = GetActorResult{} } diff --git a/greataped/components/core/initializer.go b/greataped/components/core/initializer.go index b2e1050..b5465be 100644 --- a/greataped/components/core/initializer.go +++ b/greataped/components/core/initializer.go @@ -1127,6 +1127,10 @@ func (conductor *conductor) Webfinger(resource string, editor Identity) (IWebfin return conductor.spiManager.Webfinger(resource, editor) } +func (conductor *conductor) GetActor(username string, editor Identity) (IGetActorResult, error) { + return conductor.spiManager.GetActor(username, editor) +} + func (conductor *conductor) NewDocument(id int64, content string) (IDocument, error) { return NewDocument(id, content) } @@ -1227,6 +1231,10 @@ func (conductor *conductor) NewWebfingerResult(aliases []string, links []IActivi return NewWebfingerResult(aliases, links, subject, nil) } +func (conductor *conductor) NewGetActorResult(context []string, id string, followers string, following string, inbox string, outbox string, name string, preferredUsername string, type_ string, url string, icon IActivityPubMedia, image IActivityPubMedia, publicKey IActivityPubPublicKey, summary string, published string, _ interface{}) IGetActorResult { + return NewGetActorResult(context, id, followers, following, inbox, outbox, name, preferredUsername, type_, url, icon, image, publicKey, summary, published, nil) +} + func (conductor *conductor) LogRemoteCall(context IContext, eventType uint32, source string, input, result interface{}, err error) { errorMessage := "" if err != nil { diff --git a/greataped/components/core/spi.go b/greataped/components/core/spi.go index 701b60a..3b2968f 100644 --- a/greataped/components/core/spi.go +++ b/greataped/components/core/spi.go @@ -266,3 +266,7 @@ func (dispatcher *dispatcher) Logout() (ILogoutResult, error) { func (dispatcher *dispatcher) Webfinger(resource string) (IWebfingerResult, error) { return dispatcher.conductor.SpiManager().Webfinger(resource, dispatcher.identity) } + +func (dispatcher *dispatcher) GetActor(username string) (IGetActorResult, error) { + return dispatcher.conductor.SpiManager().GetActor(username, dispatcher.identity) +} diff --git a/greataped/components/core/spi_manager.go b/greataped/components/core/spi_manager.go index 7c32103..d80e537 100644 --- a/greataped/components/core/spi_manager.go +++ b/greataped/components/core/spi_manager.go @@ -584,3 +584,122 @@ func (manager *spiManager) Webfinger(resource string, editor Identity) (result I return result, nil } } + +//region IGetActorResult Implementation + +type getActorResult struct { + context []string + id string + followers string + following string + inbox string + outbox string + name string + preferredUsername string + type_ string + url string + icon IActivityPubMedia + image IActivityPubMedia + publicKey IActivityPubPublicKey + summary string + published string +} + +func NewGetActorResult(context []string, id string, followers string, following string, inbox string, outbox string, name string, preferredUsername string, type_ string, url string, icon IActivityPubMedia, image IActivityPubMedia, publicKey IActivityPubPublicKey, summary string, published string, _ interface{}) IGetActorResult { + return &getActorResult{ + context: context, + id: id, + followers: followers, + following: following, + inbox: inbox, + outbox: outbox, + name: name, + preferredUsername: preferredUsername, + type_: type_, + url: url, + icon: icon, + image: image, + publicKey: publicKey, + summary: summary, + published: published, + } +} + +func (result getActorResult) Context() []string { + return result.context +} + +func (result getActorResult) Id() string { + return result.id +} + +func (result getActorResult) Followers() string { + return result.followers +} + +func (result getActorResult) Following() string { + return result.following +} + +func (result getActorResult) Inbox() string { + return result.inbox +} + +func (result getActorResult) Outbox() string { + return result.outbox +} + +func (result getActorResult) Name() string { + return result.name +} + +func (result getActorResult) PreferredUsername() string { + return result.preferredUsername +} + +func (result getActorResult) Type() string { + return result.type_ +} + +func (result getActorResult) Url() string { + return result.url +} + +func (result getActorResult) Icon() IActivityPubMedia { + return result.icon +} + +func (result getActorResult) Image() IActivityPubMedia { + return result.image +} + +func (result getActorResult) PublicKey() IActivityPubPublicKey { + return result.publicKey +} + +func (result getActorResult) Summary() string { + return result.summary +} + +func (result getActorResult) Published() string { + return result.published +} + +//endregion + +func (manager *spiManager) GetActor(username string, editor Identity) (result IGetActorResult, err error) { + defer func() { + if reason := recover(); reason != nil { + err = manager.Error(reason) + } + }() + + editor.Lock(GET_ACTOR_REQUEST) + defer editor.Unlock(GET_ACTOR_REQUEST) + + if result, err = commands.GetActor(NewDispatcher(Conductor, editor), username); err != nil { + return nil, err + } else { + return result, nil + } +} diff --git a/greataped/components/core/system_results.go b/greataped/components/core/system_results.go index fcb848c..14a5a99 100644 --- a/greataped/components/core/system_results.go +++ b/greataped/components/core/system_results.go @@ -36,4 +36,8 @@ func (dispatcher *dispatcher) NewWebfingerResult(aliases []string, links []IActi return NewWebfingerResult(aliases, links, subject, nil) } +func (dispatcher *dispatcher) NewGetActorResult(context []string, id string, followers string, following string, inbox string, outbox string, name string, preferredUsername string, type_ string, url string, icon IActivityPubMedia, image IActivityPubMedia, publicKey IActivityPubPublicKey, summary string, published string) IGetActorResult { + return NewGetActorResult(context, id, followers, following, inbox, outbox, name, preferredUsername, type_, url, icon, image, publicKey, summary, published, nil) +} + //endregion