mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 14:32:24 -05:00 
			
		
		
		
	[chore] Add test for dereferencing Owncast service account (#613)
This commit is contained in:
		
					parent
					
						
							
								1cdc163276
							
						
					
				
			
			
				commit
				
					
						dc8cc7e364
					
				
			
		
					 5 changed files with 344 additions and 0 deletions
				
			
		|  | @ -51,6 +51,26 @@ func (suite *AccountTestSuite) TestDereferenceGroup() { | ||||||
| 	suite.Equal(ap.ActorGroup, dbGroup.ActorType) | 	suite.Equal(ap.ActorGroup, dbGroup.ActorType) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (suite *AccountTestSuite) TestDereferenceService() { | ||||||
|  | 	fetchingAccount := suite.testAccounts["local_account_1"] | ||||||
|  | 
 | ||||||
|  | 	serviceURL := testrig.URLMustParse("https://owncast.example.org/federation/user/rgh") | ||||||
|  | 	service, err := suite.dereferencer.GetRemoteAccount(context.Background(), fetchingAccount.Username, serviceURL, false, false) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 	suite.NotNil(service) | ||||||
|  | 	suite.NotNil(service) | ||||||
|  | 
 | ||||||
|  | 	// service values should be set | ||||||
|  | 	suite.Equal("https://owncast.example.org/federation/user/rgh", service.URI) | ||||||
|  | 	suite.Equal("https://owncast.example.org/federation/user/rgh", service.URL) | ||||||
|  | 
 | ||||||
|  | 	// service should be in the database | ||||||
|  | 	dbService, err := suite.db.GetAccountByURI(context.Background(), service.URI) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 	suite.Equal(service.ID, dbService.ID) | ||||||
|  | 	suite.Equal(ap.ActorService, dbService.ActorType) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func TestAccountTestSuite(t *testing.T) { | func TestAccountTestSuite(t *testing.T) { | ||||||
| 	suite.Run(t, new(AccountTestSuite)) | 	suite.Run(t, new(AccountTestSuite)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -46,6 +46,7 @@ type DereferencerStandardTestSuite struct { | ||||||
| 	testRemoteStatuses    map[string]vocab.ActivityStreamsNote | 	testRemoteStatuses    map[string]vocab.ActivityStreamsNote | ||||||
| 	testRemotePeople      map[string]vocab.ActivityStreamsPerson | 	testRemotePeople      map[string]vocab.ActivityStreamsPerson | ||||||
| 	testRemoteGroups      map[string]vocab.ActivityStreamsGroup | 	testRemoteGroups      map[string]vocab.ActivityStreamsGroup | ||||||
|  | 	testRemoteServices    map[string]vocab.ActivityStreamsService | ||||||
| 	testRemoteAttachments map[string]testrig.RemoteAttachmentFile | 	testRemoteAttachments map[string]testrig.RemoteAttachmentFile | ||||||
| 	testAccounts          map[string]*gtsmodel.Account | 	testAccounts          map[string]*gtsmodel.Account | ||||||
| 
 | 
 | ||||||
|  | @ -60,6 +61,7 @@ func (suite *DereferencerStandardTestSuite) SetupTest() { | ||||||
| 	suite.testRemoteStatuses = testrig.NewTestFediStatuses() | 	suite.testRemoteStatuses = testrig.NewTestFediStatuses() | ||||||
| 	suite.testRemotePeople = testrig.NewTestFediPeople() | 	suite.testRemotePeople = testrig.NewTestFediPeople() | ||||||
| 	suite.testRemoteGroups = testrig.NewTestFediGroups() | 	suite.testRemoteGroups = testrig.NewTestFediGroups() | ||||||
|  | 	suite.testRemoteServices = testrig.NewTestFediServices() | ||||||
| 	suite.testRemoteAttachments = testrig.NewTestFediAttachments("../../../testrig/media") | 	suite.testRemoteAttachments = testrig.NewTestFediAttachments("../../../testrig/media") | ||||||
| 
 | 
 | ||||||
| 	suite.db = testrig.NewTestDB() | 	suite.db = testrig.NewTestDB() | ||||||
|  | @ -126,6 +128,19 @@ func (suite *DereferencerStandardTestSuite) mockTransportController() transport. | ||||||
| 			responseType = "application/activity+json" | 			responseType = "application/activity+json" | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		if service, ok := suite.testRemoteServices[req.URL.String()]; ok { | ||||||
|  | 			serviceI, err := streams.Serialize(service) | ||||||
|  | 			if err != nil { | ||||||
|  | 				panic(err) | ||||||
|  | 			} | ||||||
|  | 			serviceJson, err := json.Marshal(serviceI) | ||||||
|  | 			if err != nil { | ||||||
|  | 				panic(err) | ||||||
|  | 			} | ||||||
|  | 			responseBytes = serviceJson | ||||||
|  | 			responseType = "application/activity+json" | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		if attachment, ok := suite.testRemoteAttachments[req.URL.String()]; ok { | 		if attachment, ok := suite.testRemoteAttachments[req.URL.String()]; ok { | ||||||
| 			responseBytes = attachment.Data | 			responseBytes = attachment.Data | ||||||
| 			responseType = attachment.ContentType | 			responseType = attachment.ContentType | ||||||
|  |  | ||||||
|  | @ -157,6 +157,49 @@ func (suite *ASToInternalTestSuite) TestParseReplyWithMention() { | ||||||
| 	suite.Equal(gtsmodel.VisibilityUnlocked, status.Visibility) | 	suite.Equal(gtsmodel.VisibilityUnlocked, status.Visibility) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (suite *ASToInternalTestSuite) TestParseOwncastService() { | ||||||
|  | 	m := make(map[string]interface{}) | ||||||
|  | 	err := json.Unmarshal([]byte(owncastService), &m) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	t, err := streams.ToType(context.Background(), m) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	rep, ok := t.(ap.Accountable) | ||||||
|  | 	suite.True(ok) | ||||||
|  | 
 | ||||||
|  | 	acct, err := suite.typeconverter.ASRepresentationToAccount(context.Background(), rep, false) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal("rgh", acct.Username) | ||||||
|  | 	suite.Equal("owncast.example.org", acct.Domain) | ||||||
|  | 	suite.Equal("https://owncast.example.org/logo/external", acct.AvatarRemoteURL) | ||||||
|  | 	suite.Equal("https://owncast.example.org/logo/external", acct.HeaderRemoteURL) | ||||||
|  | 	suite.Equal("Rob's Owncast Server", acct.DisplayName) | ||||||
|  | 	suite.Equal("linux audio stuff ", acct.Note) | ||||||
|  | 	suite.True(acct.Bot) | ||||||
|  | 	suite.False(acct.Locked) | ||||||
|  | 	suite.True(acct.Discoverable) | ||||||
|  | 	suite.Equal("https://owncast.example.org/federation/user/rgh", acct.URI) | ||||||
|  | 	suite.Equal("https://owncast.example.org/federation/user/rgh", acct.URL) | ||||||
|  | 	suite.Equal("https://owncast.example.org/federation/user/rgh/inbox", acct.InboxURI) | ||||||
|  | 	suite.Equal("https://owncast.example.org/federation/user/rgh/outbox", acct.OutboxURI) | ||||||
|  | 	suite.Equal("https://owncast.example.org/federation/user/rgh/followers", acct.FollowersURI) | ||||||
|  | 	suite.Equal("Service", acct.ActorType) | ||||||
|  | 	suite.Equal("https://owncast.example.org/federation/user/rgh#main-key", acct.PublicKeyURI) | ||||||
|  | 
 | ||||||
|  | 	acct.ID = "01G42D57DTCJQE8XT9KD4K88RK" | ||||||
|  | 
 | ||||||
|  | 	apiAcct, err := suite.typeconverter.AccountToAPIAccountPublic(context.Background(), acct) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 	suite.NotNil(apiAcct) | ||||||
|  | 
 | ||||||
|  | 	b, err := json.Marshal(apiAcct) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	fmt.Printf("\n\n\n%s\n\n\n", string(b)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func TestASToInternalTestSuite(t *testing.T) { | func TestASToInternalTestSuite(t *testing.T) { | ||||||
| 	suite.Run(t, new(ASToInternalTestSuite)) | 	suite.Run(t, new(ASToInternalTestSuite)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -414,6 +414,57 @@ const ( | ||||||
| 		} | 		} | ||||||
| 	  }	   | 	  }	   | ||||||
| 	` | 	` | ||||||
|  | 	owncastService = ` | ||||||
|  | 	{ | ||||||
|  | 		"@context": [ | ||||||
|  | 		  "https://www.w3.org/ns/activitystreams", | ||||||
|  | 		  "http://joinmastodon.org/ns", | ||||||
|  | 		  "https://w3id.org/security/v1" | ||||||
|  | 		], | ||||||
|  | 		"attachment": { | ||||||
|  | 		  "name": "Stream", | ||||||
|  | 		  "type": "PropertyValue", | ||||||
|  | 		  "value": "<a href=\"https://owncast.example.org\" rel=\"me nofollow noopener noreferrer\" target=\"_blank\">https://owncast.example.org</a>" | ||||||
|  | 		}, | ||||||
|  | 		"discoverable": true, | ||||||
|  | 		"followers": "https://owncast.example.org/federation/user/rgh/followers", | ||||||
|  | 		"icon": { | ||||||
|  | 		  "type": "Image", | ||||||
|  | 		  "url": "https://owncast.example.org/logo/external" | ||||||
|  | 		}, | ||||||
|  | 		"id": "https://owncast.example.org/federation/user/rgh", | ||||||
|  | 		"image": { | ||||||
|  | 		  "type": "Image", | ||||||
|  | 		  "url": "https://owncast.example.org/logo/external" | ||||||
|  | 		}, | ||||||
|  | 		"inbox": "https://owncast.example.org/federation/user/rgh/inbox", | ||||||
|  | 		"manuallyApprovesFollowers": false, | ||||||
|  | 		"name": "Rob's Owncast Server", | ||||||
|  | 		"outbox": "https://owncast.example.org/federation/user/rgh/outbox", | ||||||
|  | 		"preferredUsername": "rgh", | ||||||
|  | 		"publicKey": { | ||||||
|  | 		  "id": "https://owncast.example.org/federation/user/rgh#main-key", | ||||||
|  | 		  "owner": "https://owncast.example.org/federation/user/rgh", | ||||||
|  | 		  "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAurN+lUNwcGV2poLNtaoT\naRtJzN6s4SDcBmIFk82lxhdMKC6/Nssm+hvDuxWGqL0+dHwSvrG11rA6irGuSzRk\niHjYyVwYe/p1CxqJxzUfZVJAWdsCFWy+HtDrTWs5sggj1MiL59uGxvkCep+OYBuG\nBI8CvSOMLrDp8soCg3EY+zSgpXtGMuRaaUukavsfuglApShB61ny7W8LG252iKC5\nmyO8L7l8TNa5BrIi/pRHLzvv9aWiCa8VKtvmqj+mClEhpkRhImSk5GPJXgouTTgl\ntT28NYYciSf9YYgZ0SNWHdLUCdkMF592j4+BbkPvdgzc70G4yyu2GcWnTzBuvF5X\nYwIDAQAB\n-----END PUBLIC KEY-----\n" | ||||||
|  | 		}, | ||||||
|  | 		"published": "2022-05-22T18:44:57Z", | ||||||
|  | 		"summary": "linux audio stuff ", | ||||||
|  | 		"tag": [ | ||||||
|  | 		  { | ||||||
|  | 			"href": "https://directory.owncast.online/tags/owncast", | ||||||
|  | 			"name": "#owncast", | ||||||
|  | 			"type": "Hashtag" | ||||||
|  | 		  }, | ||||||
|  | 		  { | ||||||
|  | 			"href": "https://directory.owncast.online/tags/streaming", | ||||||
|  | 			"name": "#streaming", | ||||||
|  | 			"type": "Hashtag" | ||||||
|  | 		  } | ||||||
|  | 		], | ||||||
|  | 		"type": "Service", | ||||||
|  | 		"url": "https://owncast.example.org/federation/user/rgh" | ||||||
|  | 	}  | ||||||
|  | ` | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type TypeUtilsTestSuite struct { | type TypeUtilsTestSuite struct { | ||||||
|  |  | ||||||
|  | @ -1821,6 +1821,37 @@ func NewTestFediGroups() map[string]vocab.ActivityStreamsGroup { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func NewTestFediServices() map[string]vocab.ActivityStreamsService { | ||||||
|  | 	newService1Priv, err := rsa.GenerateKey(rand.Reader, 2048) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	newService1Pub := &newService1Priv.PublicKey | ||||||
|  | 
 | ||||||
|  | 	return map[string]vocab.ActivityStreamsService{ | ||||||
|  | 		"https://owncast.example.org/federation/user/rgh": newAPService( | ||||||
|  | 			URLMustParse("https://owncast.example.org/federation/user/rgh"), | ||||||
|  | 			nil, | ||||||
|  | 			URLMustParse("https://owncast.example.org/federation/user/rgh/followers"), | ||||||
|  | 			URLMustParse("https://owncast.example.org/federation/user/rgh/inbox"), | ||||||
|  | 			URLMustParse("https://owncast.example.org/federation/user/rgh/outbox"), | ||||||
|  | 			nil, | ||||||
|  | 			"rgh", | ||||||
|  | 			"linux audio stuff ", | ||||||
|  | 			"", | ||||||
|  | 			URLMustParse("https://owncast.example.org/federation/user/rgh"), | ||||||
|  | 			true, | ||||||
|  | 			URLMustParse("https://owncast.example.org/federation/user/rgh#main-key"), | ||||||
|  | 			newService1Pub, | ||||||
|  | 			nil, | ||||||
|  | 			"image/jpeg", | ||||||
|  | 			nil, | ||||||
|  | 			"image/png", | ||||||
|  | 			false, | ||||||
|  | 		), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // RemoteAttachmentFile mimics a remote (federated) attachment | // RemoteAttachmentFile mimics a remote (federated) attachment | ||||||
| type RemoteAttachmentFile struct { | type RemoteAttachmentFile struct { | ||||||
| 	Data        []byte | 	Data        []byte | ||||||
|  | @ -2459,6 +2490,190 @@ func newAPGroup( | ||||||
| 	return group | 	return group | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func newAPService( | ||||||
|  | 	profileIDURI *url.URL, | ||||||
|  | 	followingURI *url.URL, | ||||||
|  | 	followersURI *url.URL, | ||||||
|  | 	inboxURI *url.URL, | ||||||
|  | 	outboxURI *url.URL, | ||||||
|  | 	featuredURI *url.URL, | ||||||
|  | 	username string, | ||||||
|  | 	displayName string, | ||||||
|  | 	note string, | ||||||
|  | 	profileURL *url.URL, | ||||||
|  | 	discoverable bool, | ||||||
|  | 	publicKeyURI *url.URL, | ||||||
|  | 	pkey *rsa.PublicKey, | ||||||
|  | 	avatarURL *url.URL, | ||||||
|  | 	avatarContentType string, | ||||||
|  | 	headerURL *url.URL, | ||||||
|  | 	headerContentType string, | ||||||
|  | 	manuallyApprovesFollowers bool, | ||||||
|  | ) vocab.ActivityStreamsService { | ||||||
|  | 	service := streams.NewActivityStreamsService() | ||||||
|  | 
 | ||||||
|  | 	// id should be the activitypub URI of this group | ||||||
|  | 	// something like https://example.org/users/example_group | ||||||
|  | 	idProp := streams.NewJSONLDIdProperty() | ||||||
|  | 	idProp.SetIRI(profileIDURI) | ||||||
|  | 	service.SetJSONLDId(idProp) | ||||||
|  | 
 | ||||||
|  | 	// following | ||||||
|  | 	// The URI for retrieving a list of accounts this group is following | ||||||
|  | 	followingProp := streams.NewActivityStreamsFollowingProperty() | ||||||
|  | 	followingProp.SetIRI(followingURI) | ||||||
|  | 	service.SetActivityStreamsFollowing(followingProp) | ||||||
|  | 
 | ||||||
|  | 	// followers | ||||||
|  | 	// The URI for retrieving a list of this user's followers | ||||||
|  | 	followersProp := streams.NewActivityStreamsFollowersProperty() | ||||||
|  | 	followersProp.SetIRI(followersURI) | ||||||
|  | 	service.SetActivityStreamsFollowers(followersProp) | ||||||
|  | 
 | ||||||
|  | 	// inbox | ||||||
|  | 	// the activitypub inbox of this user for accepting messages | ||||||
|  | 	inboxProp := streams.NewActivityStreamsInboxProperty() | ||||||
|  | 	inboxProp.SetIRI(inboxURI) | ||||||
|  | 	service.SetActivityStreamsInbox(inboxProp) | ||||||
|  | 
 | ||||||
|  | 	// outbox | ||||||
|  | 	// the activitypub outbox of this user for serving messages | ||||||
|  | 	outboxProp := streams.NewActivityStreamsOutboxProperty() | ||||||
|  | 	outboxProp.SetIRI(outboxURI) | ||||||
|  | 	service.SetActivityStreamsOutbox(outboxProp) | ||||||
|  | 
 | ||||||
|  | 	// featured posts | ||||||
|  | 	// Pinned posts. | ||||||
|  | 	featuredProp := streams.NewTootFeaturedProperty() | ||||||
|  | 	featuredProp.SetIRI(featuredURI) | ||||||
|  | 	service.SetTootFeatured(featuredProp) | ||||||
|  | 
 | ||||||
|  | 	// featuredTags | ||||||
|  | 	// NOT IMPLEMENTED | ||||||
|  | 
 | ||||||
|  | 	// preferredUsername | ||||||
|  | 	// Used for Webfinger lookup. Must be unique on the domain, and must correspond to a Webfinger acct: URI. | ||||||
|  | 	preferredUsernameProp := streams.NewActivityStreamsPreferredUsernameProperty() | ||||||
|  | 	preferredUsernameProp.SetXMLSchemaString(username) | ||||||
|  | 	service.SetActivityStreamsPreferredUsername(preferredUsernameProp) | ||||||
|  | 
 | ||||||
|  | 	// name | ||||||
|  | 	// Used as profile display name. | ||||||
|  | 	nameProp := streams.NewActivityStreamsNameProperty() | ||||||
|  | 	if displayName != "" { | ||||||
|  | 		nameProp.AppendXMLSchemaString(displayName) | ||||||
|  | 	} else { | ||||||
|  | 		nameProp.AppendXMLSchemaString(username) | ||||||
|  | 	} | ||||||
|  | 	service.SetActivityStreamsName(nameProp) | ||||||
|  | 
 | ||||||
|  | 	// summary | ||||||
|  | 	// Used as profile bio. | ||||||
|  | 	if note != "" { | ||||||
|  | 		summaryProp := streams.NewActivityStreamsSummaryProperty() | ||||||
|  | 		summaryProp.AppendXMLSchemaString(note) | ||||||
|  | 		service.SetActivityStreamsSummary(summaryProp) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// url | ||||||
|  | 	// Used as profile link. | ||||||
|  | 	urlProp := streams.NewActivityStreamsUrlProperty() | ||||||
|  | 	urlProp.AppendIRI(profileURL) | ||||||
|  | 	service.SetActivityStreamsUrl(urlProp) | ||||||
|  | 
 | ||||||
|  | 	// manuallyApprovesFollowers | ||||||
|  | 	manuallyApprovesFollowersProp := streams.NewActivityStreamsManuallyApprovesFollowersProperty() | ||||||
|  | 	manuallyApprovesFollowersProp.Set(manuallyApprovesFollowers) | ||||||
|  | 	service.SetActivityStreamsManuallyApprovesFollowers(manuallyApprovesFollowersProp) | ||||||
|  | 
 | ||||||
|  | 	// discoverable | ||||||
|  | 	// Will be shown in the profile directory. | ||||||
|  | 	discoverableProp := streams.NewTootDiscoverableProperty() | ||||||
|  | 	discoverableProp.Set(discoverable) | ||||||
|  | 	service.SetTootDiscoverable(discoverableProp) | ||||||
|  | 
 | ||||||
|  | 	// devices | ||||||
|  | 	// NOT IMPLEMENTED, probably won't implement | ||||||
|  | 
 | ||||||
|  | 	// alsoKnownAs | ||||||
|  | 	// Required for Move activity. | ||||||
|  | 	// TODO: NOT IMPLEMENTED **YET** -- this needs to be added as an activitypub extension to https://github.com/go-fed/activity, see https://github.com/go-fed/activity/tree/master/astool | ||||||
|  | 
 | ||||||
|  | 	// publicKey | ||||||
|  | 	// Required for signatures. | ||||||
|  | 	publicKeyProp := streams.NewW3IDSecurityV1PublicKeyProperty() | ||||||
|  | 
 | ||||||
|  | 	// create the public key | ||||||
|  | 	publicKey := streams.NewW3IDSecurityV1PublicKey() | ||||||
|  | 
 | ||||||
|  | 	// set ID for the public key | ||||||
|  | 	publicKeyIDProp := streams.NewJSONLDIdProperty() | ||||||
|  | 	publicKeyIDProp.SetIRI(publicKeyURI) | ||||||
|  | 	publicKey.SetJSONLDId(publicKeyIDProp) | ||||||
|  | 
 | ||||||
|  | 	// set owner for the public key | ||||||
|  | 	publicKeyOwnerProp := streams.NewW3IDSecurityV1OwnerProperty() | ||||||
|  | 	publicKeyOwnerProp.SetIRI(profileIDURI) | ||||||
|  | 	publicKey.SetW3IDSecurityV1Owner(publicKeyOwnerProp) | ||||||
|  | 
 | ||||||
|  | 	// set the pem key itself | ||||||
|  | 	encodedPublicKey, err := x509.MarshalPKIXPublicKey(pkey) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	publicKeyBytes := pem.EncodeToMemory(&pem.Block{ | ||||||
|  | 		Type:  "PUBLIC KEY", | ||||||
|  | 		Bytes: encodedPublicKey, | ||||||
|  | 	}) | ||||||
|  | 	publicKeyPEMProp := streams.NewW3IDSecurityV1PublicKeyPemProperty() | ||||||
|  | 	publicKeyPEMProp.Set(string(publicKeyBytes)) | ||||||
|  | 	publicKey.SetW3IDSecurityV1PublicKeyPem(publicKeyPEMProp) | ||||||
|  | 
 | ||||||
|  | 	// append the public key to the public key property | ||||||
|  | 	publicKeyProp.AppendW3IDSecurityV1PublicKey(publicKey) | ||||||
|  | 
 | ||||||
|  | 	// set the public key property on the Person | ||||||
|  | 	service.SetW3IDSecurityV1PublicKey(publicKeyProp) | ||||||
|  | 
 | ||||||
|  | 	// tag | ||||||
|  | 	// TODO: Any tags used in the summary of this profile | ||||||
|  | 
 | ||||||
|  | 	// attachment | ||||||
|  | 	// Used for profile fields. | ||||||
|  | 	// TODO: The PropertyValue type has to be added: https://schema.org/PropertyValue | ||||||
|  | 
 | ||||||
|  | 	// endpoints | ||||||
|  | 	// NOT IMPLEMENTED -- this is for shared inbox which we don't use | ||||||
|  | 
 | ||||||
|  | 	// icon | ||||||
|  | 	// Used as profile avatar. | ||||||
|  | 	iconProperty := streams.NewActivityStreamsIconProperty() | ||||||
|  | 	iconImage := streams.NewActivityStreamsImage() | ||||||
|  | 	mediaType := streams.NewActivityStreamsMediaTypeProperty() | ||||||
|  | 	mediaType.Set(avatarContentType) | ||||||
|  | 	iconImage.SetActivityStreamsMediaType(mediaType) | ||||||
|  | 	avatarURLProperty := streams.NewActivityStreamsUrlProperty() | ||||||
|  | 	avatarURLProperty.AppendIRI(avatarURL) | ||||||
|  | 	iconImage.SetActivityStreamsUrl(avatarURLProperty) | ||||||
|  | 	iconProperty.AppendActivityStreamsImage(iconImage) | ||||||
|  | 	service.SetActivityStreamsIcon(iconProperty) | ||||||
|  | 
 | ||||||
|  | 	// image | ||||||
|  | 	// Used as profile header. | ||||||
|  | 	headerProperty := streams.NewActivityStreamsImageProperty() | ||||||
|  | 	headerImage := streams.NewActivityStreamsImage() | ||||||
|  | 	headerMediaType := streams.NewActivityStreamsMediaTypeProperty() | ||||||
|  | 	mediaType.Set(headerContentType) | ||||||
|  | 	headerImage.SetActivityStreamsMediaType(headerMediaType) | ||||||
|  | 	headerURLProperty := streams.NewActivityStreamsUrlProperty() | ||||||
|  | 	headerURLProperty.AppendIRI(headerURL) | ||||||
|  | 	headerImage.SetActivityStreamsUrl(headerURLProperty) | ||||||
|  | 	headerProperty.AppendActivityStreamsImage(headerImage) | ||||||
|  | 	service.SetActivityStreamsImage(headerProperty) | ||||||
|  | 
 | ||||||
|  | 	return service | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func newAPMention(uri *url.URL, namestring string) vocab.ActivityStreamsMention { | func newAPMention(uri *url.URL, namestring string) vocab.ActivityStreamsMention { | ||||||
| 	mention := streams.NewActivityStreamsMention() | 	mention := streams.NewActivityStreamsMention() | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue