mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-29 19:52:24 -05:00 
			
		
		
		
	[feature] Implement /api/v1/instance/peers endpoint (#660)
		
	* add missing license headers * start adding instance peers get * rename domainblock.go * embed domain in domainblock so it can be reused * update swagger docs * add test instances to db * update tests * add/update instancepeersget * update domain model * add getinstancepeers to db * instance-expose-peers, instance-expose-suspended * add auth checks for both current filters * attach endpoint to router * include public comment * obfuscate domain if required * go mod tidy * update swagger docs * remove unnecessary comment * return 'flat' peerlist if no query params provided
This commit is contained in:
		
					parent
					
						
							
								604600c391
							
						
					
				
			
			
				commit
				
					
						5f00d4980b
					
				
			
		
					 27 changed files with 819 additions and 29 deletions
				
			
		|  | @ -784,6 +784,35 @@ definitions: | ||||||
|     type: object |     type: object | ||||||
|     x-go-name: Card |     x-go-name: Card | ||||||
|     x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model |     x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model | ||||||
|  |   domain: | ||||||
|  |     description: Domain represents a remote domain | ||||||
|  |     properties: | ||||||
|  |       domain: | ||||||
|  |         description: The hostname of the domain. | ||||||
|  |         example: example.org | ||||||
|  |         type: string | ||||||
|  |         x-go-name: Domain | ||||||
|  |       public_comment: | ||||||
|  |         description: If the domain is blocked, what's the publicly-stated reason for | ||||||
|  |           the block. | ||||||
|  |         example: they smell | ||||||
|  |         type: string | ||||||
|  |         x-go-name: PublicComment | ||||||
|  |       silenced_at: | ||||||
|  |         description: Time at which this domain was silenced. Key will not be present | ||||||
|  |           on open domains. | ||||||
|  |         example: "2021-07-30T09:20:25+00:00" | ||||||
|  |         type: string | ||||||
|  |         x-go-name: SilencedAt | ||||||
|  |       suspended_at: | ||||||
|  |         description: Time at which this domain was suspended. Key will not be present | ||||||
|  |           on open domains. | ||||||
|  |         example: "2021-07-30T09:20:25+00:00" | ||||||
|  |         type: string | ||||||
|  |         x-go-name: SuspendedAt | ||||||
|  |     type: object | ||||||
|  |     x-go-name: Domain | ||||||
|  |     x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model | ||||||
|   domainBlock: |   domainBlock: | ||||||
|     description: DomainBlock represents a block on one domain |     description: DomainBlock represents a block on one domain | ||||||
|     properties: |     properties: | ||||||
|  | @ -798,7 +827,7 @@ definitions: | ||||||
|         type: string |         type: string | ||||||
|         x-go-name: CreatedBy |         x-go-name: CreatedBy | ||||||
|       domain: |       domain: | ||||||
|         description: The hostname of the blocked domain. |         description: The hostname of the domain. | ||||||
|         example: example.org |         example: example.org | ||||||
|         type: string |         type: string | ||||||
|         x-go-name: Domain |         x-go-name: Domain | ||||||
|  | @ -822,16 +851,28 @@ definitions: | ||||||
|         type: string |         type: string | ||||||
|         x-go-name: PrivateComment |         x-go-name: PrivateComment | ||||||
|       public_comment: |       public_comment: | ||||||
|         description: Public comment for this block, visible if domain blocks are served |         description: If the domain is blocked, what's the publicly-stated reason for | ||||||
|           publicly. |           the block. | ||||||
|         example: they smell |         example: they smell | ||||||
|         type: string |         type: string | ||||||
|         x-go-name: PublicComment |         x-go-name: PublicComment | ||||||
|  |       silenced_at: | ||||||
|  |         description: Time at which this domain was silenced. Key will not be present | ||||||
|  |           on open domains. | ||||||
|  |         example: "2021-07-30T09:20:25+00:00" | ||||||
|  |         type: string | ||||||
|  |         x-go-name: SilencedAt | ||||||
|       subscription_id: |       subscription_id: | ||||||
|         description: The ID of the subscription that created/caused this domain block. |         description: The ID of the subscription that created/caused this domain block. | ||||||
|         example: 01FBW25TF5J67JW3HFHZCSD23K |         example: 01FBW25TF5J67JW3HFHZCSD23K | ||||||
|         type: string |         type: string | ||||||
|         x-go-name: SubscriptionID |         x-go-name: SubscriptionID | ||||||
|  |       suspended_at: | ||||||
|  |         description: Time at which this domain was suspended. Key will not be present | ||||||
|  |           on open domains. | ||||||
|  |         example: "2021-07-30T09:20:25+00:00" | ||||||
|  |         type: string | ||||||
|  |         x-go-name: SuspendedAt | ||||||
|     type: object |     type: object | ||||||
|     x-go-name: DomainBlock |     x-go-name: DomainBlock | ||||||
|     x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model |     x-go-package: github.com/superseriousbusiness/gotosocial/internal/api/model | ||||||
|  | @ -3038,6 +3079,60 @@ paths: | ||||||
|         for the instance. |         for the instance. | ||||||
|       tags: |       tags: | ||||||
|       - instance |       - instance | ||||||
|  |   /api/v1/instance/peers: | ||||||
|  |     get: | ||||||
|  |       operationId: instancePeersGet | ||||||
|  |       parameters: | ||||||
|  |       - description: |- | ||||||
|  |           Comma-separated list of filters to apply to results. Recognized values are: | ||||||
|  |           'open' -- include peers that are not suspended or silenced | ||||||
|  |           'suspended' -- include peers that have been suspended. | ||||||
|  |           If filter is 'open', only instances that haven't been suspended or silenced will be returned. | ||||||
|  |           If filter is 'suspended', only suspended instances will be shown. | ||||||
|  |           If filter is 'open,suspended', then all known instances will be returned. | ||||||
|  |           If filter is an empty string or not set, then 'open' will be assumed as the default. | ||||||
|  |         in: query | ||||||
|  |         name: filter | ||||||
|  |         type: string | ||||||
|  |       produces: | ||||||
|  |       - application/json | ||||||
|  |       responses: | ||||||
|  |         "200": | ||||||
|  |           description: |- | ||||||
|  |             If no filter parameter is provided, or filter is empty, then a legacy, | ||||||
|  |             Mastodon-API compatible response will be returned. This will consist of | ||||||
|  |             just a 'flat' array of strings like `["example.com", "example.org"]`. | ||||||
|  | 
 | ||||||
|  |             If a filter parameter is provided, then an array of objects with at least | ||||||
|  |             a `domain` key set on each object will be returned. | ||||||
|  | 
 | ||||||
|  |             Domains that are silenced or suspended will also have a key | ||||||
|  |             'suspended_at' or 'silenced_at' that contains an iso8601 date string. | ||||||
|  |             If one of these keys is not present on the domain object, it is open. | ||||||
|  |             Suspended instances may in some cases be obfuscated, which means they | ||||||
|  |             will have some letters replaced by '*' to make it more difficult for | ||||||
|  |             bad actors to target instances with harassment. | ||||||
|  | 
 | ||||||
|  |             Whether a flat response or a more detailed response is returned, domains | ||||||
|  |             will be sorted alphabetically by hostname. | ||||||
|  |           schema: | ||||||
|  |             items: | ||||||
|  |               $ref: '#/definitions/domain' | ||||||
|  |             type: array | ||||||
|  |         "400": | ||||||
|  |           description: bad request | ||||||
|  |         "401": | ||||||
|  |           description: unauthorized | ||||||
|  |         "403": | ||||||
|  |           description: forbidden | ||||||
|  |         "404": | ||||||
|  |           description: not found | ||||||
|  |         "406": | ||||||
|  |           description: not acceptable | ||||||
|  |         "500": | ||||||
|  |           description: internal server error | ||||||
|  |       tags: | ||||||
|  |       - instance | ||||||
|   /api/v1/media: |   /api/v1/media: | ||||||
|     post: |     post: | ||||||
|       consumes: |       consumes: | ||||||
|  |  | ||||||
							
								
								
									
										26
									
								
								docs/configuration/instance.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								docs/configuration/instance.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | ||||||
|  | # Instance | ||||||
|  | 
 | ||||||
|  | ## Settings | ||||||
|  | 
 | ||||||
|  | ```yaml | ||||||
|  | ########################### | ||||||
|  | ##### INSTANCE CONFIG ##### | ||||||
|  | ########################### | ||||||
|  | 
 | ||||||
|  | # Config pertaining to instance federation settings, pages to hide/expose, etc. | ||||||
|  | 
 | ||||||
|  | # Bool. Allow unauthenticated users to make queries to /api/v1/instance/peers?filter=open in order | ||||||
|  | # to see a list of instances that this instance 'peers' with. Even if set to 'false', then authenticated | ||||||
|  | # users (members of the instance) will still be able to query the endpoint. | ||||||
|  | # Options: [true, false] | ||||||
|  | # Default: false | ||||||
|  | instance-expose-peers: false | ||||||
|  | 
 | ||||||
|  | # Bool. Allow unauthenticated users to make queries to /api/v1/instance/peers?filter=suspended in order | ||||||
|  | # to see a list of instances that this instance blocks/suspends. This will also allow unauthenticated | ||||||
|  | # users to see the list through the web UI. Even if set to 'false', then authenticated users (members | ||||||
|  | # of the instance) will still be able to query the endpoint. | ||||||
|  | # Options: [true, false] | ||||||
|  | # Default: false | ||||||
|  | instance-expose-suspended: false | ||||||
|  | ``` | ||||||
|  | @ -165,6 +165,27 @@ web-template-base-dir: "./web/template/" | ||||||
| # Default: "./web/assets/" | # Default: "./web/assets/" | ||||||
| web-asset-base-dir: "./web/assets/" | web-asset-base-dir: "./web/assets/" | ||||||
| 
 | 
 | ||||||
|  | ########################### | ||||||
|  | ##### INSTANCE CONFIG ##### | ||||||
|  | ########################### | ||||||
|  | 
 | ||||||
|  | # Config pertaining to instance federation settings, pages to hide/expose, etc. | ||||||
|  | 
 | ||||||
|  | # Bool. Allow unauthenticated users to make queries to /api/v1/instance/peers?filter=open in order | ||||||
|  | # to see a list of instances that this instance 'peers' with. Even if set to 'false', then authenticated | ||||||
|  | # users (members of the instance) will still be able to query the endpoint. | ||||||
|  | # Options: [true, false] | ||||||
|  | # Default: false | ||||||
|  | instance-expose-peers: false | ||||||
|  | 
 | ||||||
|  | # Bool. Allow unauthenticated users to make queries to /api/v1/instance/peers?filter=suspended in order | ||||||
|  | # to see a list of instances that this instance blocks/suspends. This will also allow unauthenticated | ||||||
|  | # users to see the list through the web UI. Even if set to 'false', then authenticated users (members | ||||||
|  | # of the instance) will still be able to query the endpoint. | ||||||
|  | # Options: [true, false] | ||||||
|  | # Default: false | ||||||
|  | instance-expose-suspended: false | ||||||
|  | 
 | ||||||
| ########################### | ########################### | ||||||
| ##### ACCOUNTS CONFIG ##### | ##### ACCOUNTS CONFIG ##### | ||||||
| ########################### | ########################### | ||||||
|  |  | ||||||
|  | @ -1,3 +1,21 @@ | ||||||
|  | /* | ||||||
|  |    GoToSocial | ||||||
|  |    Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org | ||||||
|  | 
 | ||||||
|  |    This program is free software: you can redistribute it and/or modify | ||||||
|  |    it under the terms of the GNU Affero General Public License as published by | ||||||
|  |    the Free Software Foundation, either version 3 of the License, or | ||||||
|  |    (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |    This program is distributed in the hope that it will be useful, | ||||||
|  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |    GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  |    You should have received a copy of the GNU Affero General Public License | ||||||
|  |    along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
| package instance | package instance | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | @ -11,6 +29,10 @@ import ( | ||||||
| const ( | const ( | ||||||
| 	// InstanceInformationPath is for serving instance info requests | 	// InstanceInformationPath is for serving instance info requests | ||||||
| 	InstanceInformationPath = "api/v1/instance" | 	InstanceInformationPath = "api/v1/instance" | ||||||
|  | 	// InstancePeersPath is for serving instance peers requests. | ||||||
|  | 	InstancePeersPath = InstanceInformationPath + "/peers" | ||||||
|  | 	// PeersFilterKey is used to provide filters to /api/v1/instance/peers | ||||||
|  | 	PeersFilterKey = "filter" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Module implements the ClientModule interface | // Module implements the ClientModule interface | ||||||
|  | @ -29,5 +51,6 @@ func New(processor processing.Processor) api.ClientModule { | ||||||
| func (m *Module) Route(s router.Router) error { | func (m *Module) Route(s router.Router) error { | ||||||
| 	s.AttachHandler(http.MethodGet, InstanceInformationPath, m.InstanceInformationGETHandler) | 	s.AttachHandler(http.MethodGet, InstanceInformationPath, m.InstanceInformationGETHandler) | ||||||
| 	s.AttachHandler(http.MethodPatch, InstanceInformationPath, m.InstanceUpdatePATCHHandler) | 	s.AttachHandler(http.MethodPatch, InstanceInformationPath, m.InstanceUpdatePATCHHandler) | ||||||
|  | 	s.AttachHandler(http.MethodGet, InstancePeersPath, m.InstancePeersGETHandler) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -21,7 +21,6 @@ package instance_test | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"net/http" |  | ||||||
| 	"net/http/httptest" | 	"net/http/httptest" | ||||||
| 
 | 
 | ||||||
| 	"codeberg.org/gruf/go-store/kv" | 	"codeberg.org/gruf/go-store/kv" | ||||||
|  | @ -113,7 +112,7 @@ func (suite *InstanceStandardTestSuite) newContext(recorder *httptest.ResponseRe | ||||||
| 	baseURI := fmt.Sprintf("%s://%s", protocol, host) | 	baseURI := fmt.Sprintf("%s://%s", protocol, host) | ||||||
| 	requestURI := fmt.Sprintf("%s/%s", baseURI, requestPath) | 	requestURI := fmt.Sprintf("%s/%s", baseURI, requestPath) | ||||||
| 
 | 
 | ||||||
| 	ctx.Request = httptest.NewRequest(http.MethodPatch, requestURI, bytes.NewReader(requestBody)) // the endpoint we're hitting | 	ctx.Request = httptest.NewRequest(requestMethod, requestURI, bytes.NewReader(requestBody)) // the endpoint we're hitting | ||||||
| 
 | 
 | ||||||
| 	if bodyContentType != "" { | 	if bodyContentType != "" { | ||||||
| 		ctx.Request.Header.Set("Content-Type", bodyContentType) | 		ctx.Request.Header.Set("Content-Type", bodyContentType) | ||||||
|  |  | ||||||
|  | @ -1,3 +1,21 @@ | ||||||
|  | /* | ||||||
|  |    GoToSocial | ||||||
|  |    Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org | ||||||
|  | 
 | ||||||
|  |    This program is free software: you can redistribute it and/or modify | ||||||
|  |    it under the terms of the GNU Affero General Public License as published by | ||||||
|  |    the Free Software Foundation, either version 3 of the License, or | ||||||
|  |    (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |    This program is distributed in the hope that it will be useful, | ||||||
|  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |    GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  |    You should have received a copy of the GNU Affero General Public License | ||||||
|  |    along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
| package instance | package instance | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  |  | ||||||
|  | @ -1,3 +1,21 @@ | ||||||
|  | /* | ||||||
|  |    GoToSocial | ||||||
|  |    Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org | ||||||
|  | 
 | ||||||
|  |    This program is free software: you can redistribute it and/or modify | ||||||
|  |    it under the terms of the GNU Affero General Public License as published by | ||||||
|  |    the Free Software Foundation, either version 3 of the License, or | ||||||
|  |    (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |    This program is distributed in the hope that it will be useful, | ||||||
|  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |    GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  |    You should have received a copy of the GNU Affero General Public License | ||||||
|  |    along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
| package instance | package instance | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  |  | ||||||
|  | @ -63,7 +63,7 @@ func (suite *InstancePatchTestSuite) TestInstancePatch1() { | ||||||
| 	b, err := io.ReadAll(result.Body) | 	b, err := io.ReadAll(result.Body) | ||||||
| 	suite.NoError(err) | 	suite.NoError(err) | ||||||
| 
 | 
 | ||||||
| 	suite.Equal(`{"uri":"http://localhost:8080","title":"Example Instance","description":"","short_description":"","email":"someone@example.org","version":"","registrations":true,"approval_required":true,"invites_enabled":false,"urls":{"streaming_api":"wss://localhost:8080"},"stats":{"domain_count":0,"status_count":16,"user_count":4},"thumbnail":"","contact_account":{"id":"01F8MH17FWEB39HZJ76B6VXSKF","username":"admin","acct":"admin","display_name":"","locked":false,"bot":false,"created_at":"2022-05-17T13:10:59.000Z","note":"","url":"http://localhost:8080/@admin","avatar":"","avatar_static":"","header":"","header_static":"","followers_count":1,"following_count":1,"statuses_count":4,"last_status_at":"2021-10-20T10:41:37.000Z","emojis":[],"fields":[]},"max_toot_chars":5000}`, string(b)) | 	suite.Equal(`{"uri":"http://localhost:8080","title":"Example Instance","description":"","short_description":"","email":"someone@example.org","version":"","registrations":true,"approval_required":true,"invites_enabled":false,"urls":{"streaming_api":"wss://localhost:8080"},"stats":{"domain_count":2,"status_count":16,"user_count":4},"thumbnail":"","contact_account":{"id":"01F8MH17FWEB39HZJ76B6VXSKF","username":"admin","acct":"admin","display_name":"","locked":false,"bot":false,"created_at":"2022-05-17T13:10:59.000Z","note":"","url":"http://localhost:8080/@admin","avatar":"","avatar_static":"","header":"","header_static":"","followers_count":1,"following_count":1,"statuses_count":4,"last_status_at":"2021-10-20T10:41:37.000Z","emojis":[],"fields":[]},"max_toot_chars":5000}`, string(b)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *InstancePatchTestSuite) TestInstancePatch2() { | func (suite *InstancePatchTestSuite) TestInstancePatch2() { | ||||||
|  | @ -93,7 +93,7 @@ func (suite *InstancePatchTestSuite) TestInstancePatch2() { | ||||||
| 	b, err := io.ReadAll(result.Body) | 	b, err := io.ReadAll(result.Body) | ||||||
| 	suite.NoError(err) | 	suite.NoError(err) | ||||||
| 
 | 
 | ||||||
| 	suite.Equal(`{"uri":"http://localhost:8080","title":"Geoff's Instance","description":"","short_description":"","email":"","version":"","registrations":true,"approval_required":true,"invites_enabled":false,"urls":{"streaming_api":"wss://localhost:8080"},"stats":{"domain_count":0,"status_count":16,"user_count":4},"thumbnail":"","max_toot_chars":5000}`, string(b)) | 	suite.Equal(`{"uri":"http://localhost:8080","title":"Geoff's Instance","description":"","short_description":"","email":"","version":"","registrations":true,"approval_required":true,"invites_enabled":false,"urls":{"streaming_api":"wss://localhost:8080"},"stats":{"domain_count":2,"status_count":16,"user_count":4},"thumbnail":"","max_toot_chars":5000}`, string(b)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *InstancePatchTestSuite) TestInstancePatch3() { | func (suite *InstancePatchTestSuite) TestInstancePatch3() { | ||||||
|  | @ -123,7 +123,7 @@ func (suite *InstancePatchTestSuite) TestInstancePatch3() { | ||||||
| 	b, err := io.ReadAll(result.Body) | 	b, err := io.ReadAll(result.Body) | ||||||
| 	suite.NoError(err) | 	suite.NoError(err) | ||||||
| 
 | 
 | ||||||
| 	suite.Equal(`{"uri":"http://localhost:8080","title":"localhost:8080","description":"","short_description":"\u003cp\u003eThis is some html, which is \u003cem\u003eallowed\u003c/em\u003e in short descriptions.\u003c/p\u003e","email":"","version":"","registrations":true,"approval_required":true,"invites_enabled":false,"urls":{"streaming_api":"wss://localhost:8080"},"stats":{"domain_count":0,"status_count":16,"user_count":4},"thumbnail":"","max_toot_chars":5000}`, string(b)) | 	suite.Equal(`{"uri":"http://localhost:8080","title":"localhost:8080","description":"","short_description":"\u003cp\u003eThis is some html, which is \u003cem\u003eallowed\u003c/em\u003e in short descriptions.\u003c/p\u003e","email":"","version":"","registrations":true,"approval_required":true,"invites_enabled":false,"urls":{"streaming_api":"wss://localhost:8080"},"stats":{"domain_count":2,"status_count":16,"user_count":4},"thumbnail":"","max_toot_chars":5000}`, string(b)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *InstancePatchTestSuite) TestInstancePatch4() { | func (suite *InstancePatchTestSuite) TestInstancePatch4() { | ||||||
|  |  | ||||||
							
								
								
									
										136
									
								
								internal/api/client/instance/instancepeersget.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								internal/api/client/instance/instancepeersget.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,136 @@ | ||||||
|  | /* | ||||||
|  |    GoToSocial | ||||||
|  |    Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org | ||||||
|  | 
 | ||||||
|  |    This program is free software: you can redistribute it and/or modify | ||||||
|  |    it under the terms of the GNU Affero General Public License as published by | ||||||
|  |    the Free Software Foundation, either version 3 of the License, or | ||||||
|  |    (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |    This program is distributed in the hope that it will be useful, | ||||||
|  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |    GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  |    You should have received a copy of the GNU Affero General Public License | ||||||
|  |    along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | package instance | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"net/http" | ||||||
|  | 	"strings" | ||||||
|  | 
 | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/api" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/oauth" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gin-gonic/gin" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // InstancePeersGETHandler swagger:operation GET /api/v1/instance/peers instancePeersGet | ||||||
|  | // | ||||||
|  | // --- | ||||||
|  | // tags: | ||||||
|  | // - instance | ||||||
|  | // | ||||||
|  | // produces: | ||||||
|  | // - application/json | ||||||
|  | // | ||||||
|  | // parameters: | ||||||
|  | // - name: filter | ||||||
|  | //   type: string | ||||||
|  | //   description: |- | ||||||
|  | //     Comma-separated list of filters to apply to results. Recognized values are: | ||||||
|  | //     'open' -- include peers that are not suspended or silenced | ||||||
|  | //     'suspended' -- include peers that have been suspended. | ||||||
|  | //     If filter is 'open', only instances that haven't been suspended or silenced will be returned. | ||||||
|  | //     If filter is 'suspended', only suspended instances will be shown. | ||||||
|  | //     If filter is 'open,suspended', then all known instances will be returned. | ||||||
|  | //     If filter is an empty string or not set, then 'open' will be assumed as the default. | ||||||
|  | //   in: query | ||||||
|  | //   required: false | ||||||
|  | // | ||||||
|  | // responses: | ||||||
|  | //   '200': | ||||||
|  | //     description: |- | ||||||
|  | //       If no filter parameter is provided, or filter is empty, then a legacy, | ||||||
|  | //       Mastodon-API compatible response will be returned. This will consist of | ||||||
|  | //       just a 'flat' array of strings like `["example.com", "example.org"]`. | ||||||
|  | // | ||||||
|  | //       If a filter parameter is provided, then an array of objects with at least | ||||||
|  | //       a `domain` key set on each object will be returned. | ||||||
|  | // | ||||||
|  | //       Domains that are silenced or suspended will also have a key | ||||||
|  | //       'suspended_at' or 'silenced_at' that contains an iso8601 date string. | ||||||
|  | //       If one of these keys is not present on the domain object, it is open. | ||||||
|  | //       Suspended instances may in some cases be obfuscated, which means they | ||||||
|  | //       will have some letters replaced by '*' to make it more difficult for | ||||||
|  | //       bad actors to target instances with harassment. | ||||||
|  | // | ||||||
|  | //       Whether a flat response or a more detailed response is returned, domains | ||||||
|  | //       will be sorted alphabetically by hostname. | ||||||
|  | //     schema: | ||||||
|  | //       type: array | ||||||
|  | //       items: | ||||||
|  | //         "$ref": "#/definitions/domain" | ||||||
|  | //   '400': | ||||||
|  | //      description: bad request | ||||||
|  | //   '401': | ||||||
|  | //      description: unauthorized | ||||||
|  | //   '403': | ||||||
|  | //      description: forbidden | ||||||
|  | //   '404': | ||||||
|  | //      description: not found | ||||||
|  | //   '406': | ||||||
|  | //      description: not acceptable | ||||||
|  | //   '500': | ||||||
|  | //      description: internal server error | ||||||
|  | func (m *Module) InstancePeersGETHandler(c *gin.Context) { | ||||||
|  | 	authed, err := oauth.Authed(c, false, false, false, false) | ||||||
|  | 	if err != nil { | ||||||
|  | 		api.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGet) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if _, err := api.NegotiateAccept(c, api.JSONAcceptHeaders...); err != nil { | ||||||
|  | 		api.ErrorHandler(c, gtserror.NewErrorNotAcceptable(err, err.Error()), m.processor.InstanceGet) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var includeSuspended bool | ||||||
|  | 	var includeOpen bool | ||||||
|  | 	var flat bool | ||||||
|  | 	if filterParam := c.Query(PeersFilterKey); filterParam != "" { | ||||||
|  | 		filters := strings.Split(filterParam, ",") | ||||||
|  | 		for _, f := range filters { | ||||||
|  | 			trimmed := strings.TrimSpace(f) | ||||||
|  | 			switch { | ||||||
|  | 			case strings.EqualFold(trimmed, "suspended"): | ||||||
|  | 				includeSuspended = true | ||||||
|  | 			case strings.EqualFold(trimmed, "open"): | ||||||
|  | 				includeOpen = true | ||||||
|  | 			default: | ||||||
|  | 				err := fmt.Errorf("filter %s not recognized; accepted values are 'open', 'suspended'", trimmed) | ||||||
|  | 				api.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGet) | ||||||
|  | 				return | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} else { | ||||||
|  | 		// default is to only include open domains, and present | ||||||
|  | 		// them in a 'flat' manner (just an array of strings), | ||||||
|  | 		// to maintain compatibility with mastodon API | ||||||
|  | 		includeOpen = true | ||||||
|  | 		flat = true | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	data, errWithCode := m.processor.InstancePeersGet(c.Request.Context(), authed, includeSuspended, includeOpen, flat) | ||||||
|  | 	if errWithCode != nil { | ||||||
|  | 		api.ErrorHandler(c, errWithCode, m.processor.InstanceGet) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	c.JSON(http.StatusOK, data) | ||||||
|  | } | ||||||
							
								
								
									
										247
									
								
								internal/api/client/instance/instancepeersget_test.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										247
									
								
								internal/api/client/instance/instancepeersget_test.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,247 @@ | ||||||
|  | /* | ||||||
|  |    GoToSocial | ||||||
|  |    Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org | ||||||
|  | 
 | ||||||
|  |    This program is free software: you can redistribute it and/or modify | ||||||
|  |    it under the terms of the GNU Affero General Public License as published by | ||||||
|  |    the Free Software Foundation, either version 3 of the License, or | ||||||
|  |    (at your option) any later version. | ||||||
|  | 
 | ||||||
|  |    This program is distributed in the hope that it will be useful, | ||||||
|  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |    GNU Affero General Public License for more details. | ||||||
|  | 
 | ||||||
|  |    You should have received a copy of the GNU Affero General Public License | ||||||
|  |    along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | package instance_test | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io" | ||||||
|  | 	"net/http" | ||||||
|  | 	"net/http/httptest" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gin-gonic/gin" | ||||||
|  | 	"github.com/stretchr/testify/suite" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/api/client/instance" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/config" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/testrig" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type InstancePeersGetTestSuite struct { | ||||||
|  | 	InstanceStandardTestSuite | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (suite *InstancePeersGetTestSuite) TestInstancePeersGetNoParams() { | ||||||
|  | 	recorder := httptest.NewRecorder() | ||||||
|  | 	ctx, _ := gin.CreateTestContext(recorder) | ||||||
|  | 
 | ||||||
|  | 	baseURI := fmt.Sprintf("%s://%s", config.GetProtocol(), config.GetHost()) | ||||||
|  | 	requestURI := fmt.Sprintf("%s/%s", baseURI, instance.InstancePeersPath) | ||||||
|  | 	ctx.Request = httptest.NewRequest(http.MethodGet, requestURI, nil) | ||||||
|  | 
 | ||||||
|  | 	suite.instanceModule.InstancePeersGETHandler(ctx) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(http.StatusOK, recorder.Code) | ||||||
|  | 
 | ||||||
|  | 	result := recorder.Result() | ||||||
|  | 	defer result.Body.Close() | ||||||
|  | 
 | ||||||
|  | 	b, err := io.ReadAll(result.Body) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(`["example.org","fossbros-anonymous.io"]`, string(b)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (suite *InstancePeersGetTestSuite) TestInstancePeersGetNoParamsUnauthorized() { | ||||||
|  | 	config.SetInstanceExposePeers(false) | ||||||
|  | 
 | ||||||
|  | 	recorder := httptest.NewRecorder() | ||||||
|  | 	ctx, _ := gin.CreateTestContext(recorder) | ||||||
|  | 
 | ||||||
|  | 	baseURI := fmt.Sprintf("%s://%s", config.GetProtocol(), config.GetHost()) | ||||||
|  | 	requestURI := fmt.Sprintf("%s/%s", baseURI, instance.InstancePeersPath) | ||||||
|  | 	ctx.Request = httptest.NewRequest(http.MethodGet, requestURI, nil) | ||||||
|  | 
 | ||||||
|  | 	suite.instanceModule.InstancePeersGETHandler(ctx) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(http.StatusUnauthorized, recorder.Code) | ||||||
|  | 
 | ||||||
|  | 	result := recorder.Result() | ||||||
|  | 	defer result.Body.Close() | ||||||
|  | 
 | ||||||
|  | 	b, err := io.ReadAll(result.Body) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(`{"error":"Unauthorized: peers open query requires an authenticated account/user"}`, string(b)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (suite *InstancePeersGetTestSuite) TestInstancePeersGetNoParamsAuthorized() { | ||||||
|  | 	config.SetInstanceExposePeers(false) | ||||||
|  | 
 | ||||||
|  | 	recorder := httptest.NewRecorder() | ||||||
|  | 	baseURI := fmt.Sprintf("%s://%s", config.GetProtocol(), config.GetHost()) | ||||||
|  | 	requestURI := fmt.Sprintf("%s/%s", baseURI, instance.InstancePeersPath) | ||||||
|  | 	ctx := suite.newContext(recorder, http.MethodGet, []byte{}, requestURI, "") | ||||||
|  | 
 | ||||||
|  | 	suite.instanceModule.InstancePeersGETHandler(ctx) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(http.StatusOK, recorder.Code) | ||||||
|  | 
 | ||||||
|  | 	result := recorder.Result() | ||||||
|  | 	defer result.Body.Close() | ||||||
|  | 
 | ||||||
|  | 	b, err := io.ReadAll(result.Body) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(`["example.org","fossbros-anonymous.io"]`, string(b)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (suite *InstancePeersGetTestSuite) TestInstancePeersGetOnlySuspended() { | ||||||
|  | 	recorder := httptest.NewRecorder() | ||||||
|  | 	ctx, _ := gin.CreateTestContext(recorder) | ||||||
|  | 
 | ||||||
|  | 	baseURI := fmt.Sprintf("%s://%s", config.GetProtocol(), config.GetHost()) | ||||||
|  | 	requestURI := fmt.Sprintf("%s/%s?filter=suspended", baseURI, instance.InstancePeersPath) | ||||||
|  | 	ctx.Request = httptest.NewRequest(http.MethodGet, requestURI, nil) | ||||||
|  | 
 | ||||||
|  | 	suite.instanceModule.InstancePeersGETHandler(ctx) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(http.StatusOK, recorder.Code) | ||||||
|  | 
 | ||||||
|  | 	result := recorder.Result() | ||||||
|  | 	defer result.Body.Close() | ||||||
|  | 
 | ||||||
|  | 	b, err := io.ReadAll(result.Body) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(`[{"domain":"replyguys.com","suspended_at":"2020-05-13T13:29:12.000Z","public_comment":"reply-guying to tech posts"}]`, string(b)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (suite *InstancePeersGetTestSuite) TestInstancePeersGetOnlySuspendedUnauthorized() { | ||||||
|  | 	config.SetInstanceExposeSuspended(false) | ||||||
|  | 
 | ||||||
|  | 	recorder := httptest.NewRecorder() | ||||||
|  | 	ctx, _ := gin.CreateTestContext(recorder) | ||||||
|  | 
 | ||||||
|  | 	baseURI := fmt.Sprintf("%s://%s", config.GetProtocol(), config.GetHost()) | ||||||
|  | 	requestURI := fmt.Sprintf("%s/%s?filter=suspended", baseURI, instance.InstancePeersPath) | ||||||
|  | 	ctx.Request = httptest.NewRequest(http.MethodGet, requestURI, nil) | ||||||
|  | 
 | ||||||
|  | 	suite.instanceModule.InstancePeersGETHandler(ctx) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(http.StatusUnauthorized, recorder.Code) | ||||||
|  | 
 | ||||||
|  | 	result := recorder.Result() | ||||||
|  | 	defer result.Body.Close() | ||||||
|  | 
 | ||||||
|  | 	b, err := io.ReadAll(result.Body) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(`{"error":"Unauthorized: peers suspended query requires an authenticated account/user"}`, string(b)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (suite *InstancePeersGetTestSuite) TestInstancePeersGetOnlySuspendedAuthorized() { | ||||||
|  | 	config.SetInstanceExposeSuspended(false) | ||||||
|  | 
 | ||||||
|  | 	recorder := httptest.NewRecorder() | ||||||
|  | 	baseURI := fmt.Sprintf("%s://%s", config.GetProtocol(), config.GetHost()) | ||||||
|  | 	requestURI := fmt.Sprintf("%s/%s?filter=suspended", baseURI, instance.InstancePeersPath) | ||||||
|  | 	ctx := suite.newContext(recorder, http.MethodGet, []byte{}, requestURI, "") | ||||||
|  | 
 | ||||||
|  | 	suite.instanceModule.InstancePeersGETHandler(ctx) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(http.StatusOK, recorder.Code) | ||||||
|  | 
 | ||||||
|  | 	result := recorder.Result() | ||||||
|  | 	defer result.Body.Close() | ||||||
|  | 
 | ||||||
|  | 	b, err := io.ReadAll(result.Body) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(`[{"domain":"replyguys.com","suspended_at":"2020-05-13T13:29:12.000Z","public_comment":"reply-guying to tech posts"}]`, string(b)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (suite *InstancePeersGetTestSuite) TestInstancePeersGetAll() { | ||||||
|  | 	recorder := httptest.NewRecorder() | ||||||
|  | 	ctx, _ := gin.CreateTestContext(recorder) | ||||||
|  | 
 | ||||||
|  | 	baseURI := fmt.Sprintf("%s://%s", config.GetProtocol(), config.GetHost()) | ||||||
|  | 	requestURI := fmt.Sprintf("%s/%s?filter=suspended,open", baseURI, instance.InstancePeersPath) | ||||||
|  | 	ctx.Request = httptest.NewRequest(http.MethodGet, requestURI, nil) | ||||||
|  | 
 | ||||||
|  | 	suite.instanceModule.InstancePeersGETHandler(ctx) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(http.StatusOK, recorder.Code) | ||||||
|  | 
 | ||||||
|  | 	result := recorder.Result() | ||||||
|  | 	defer result.Body.Close() | ||||||
|  | 
 | ||||||
|  | 	b, err := io.ReadAll(result.Body) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(`[{"domain":"example.org"},{"domain":"fossbros-anonymous.io"},{"domain":"replyguys.com","suspended_at":"2020-05-13T13:29:12.000Z","public_comment":"reply-guying to tech posts"}]`, string(b)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (suite *InstancePeersGetTestSuite) TestInstancePeersGetAllWithObfuscated() { | ||||||
|  | 	err := suite.db.Put(context.Background(), >smodel.DomainBlock{ | ||||||
|  | 		ID:                 "01G633XTNK51GBADQZFZQDP6WR", | ||||||
|  | 		CreatedAt:          testrig.TimeMustParse("2021-06-09T12:34:55+02:00"), | ||||||
|  | 		UpdatedAt:          testrig.TimeMustParse("2021-06-09T12:34:55+02:00"), | ||||||
|  | 		Domain:             "omg.just.the.worst.org.ever", | ||||||
|  | 		CreatedByAccountID: "01F8MH17FWEB39HZJ76B6VXSKF", | ||||||
|  | 		PublicComment:      "just absolutely the worst, wowza", | ||||||
|  | 		Obfuscate:          true, | ||||||
|  | 	}) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	recorder := httptest.NewRecorder() | ||||||
|  | 	ctx, _ := gin.CreateTestContext(recorder) | ||||||
|  | 
 | ||||||
|  | 	baseURI := fmt.Sprintf("%s://%s", config.GetProtocol(), config.GetHost()) | ||||||
|  | 	requestURI := fmt.Sprintf("%s/%s?filter=suspended,open", baseURI, instance.InstancePeersPath) | ||||||
|  | 	ctx.Request = httptest.NewRequest(http.MethodGet, requestURI, nil) | ||||||
|  | 
 | ||||||
|  | 	suite.instanceModule.InstancePeersGETHandler(ctx) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(http.StatusOK, recorder.Code) | ||||||
|  | 
 | ||||||
|  | 	result := recorder.Result() | ||||||
|  | 	defer result.Body.Close() | ||||||
|  | 
 | ||||||
|  | 	b, err := io.ReadAll(result.Body) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(`[{"domain":"example.org"},{"domain":"fossbros-anonymous.io"},{"domain":"o*g.*u**.t**.*or*t.*r**ev**","suspended_at":"2021-06-09T10:34:55.000Z","public_comment":"just absolutely the worst, wowza"},{"domain":"replyguys.com","suspended_at":"2020-05-13T13:29:12.000Z","public_comment":"reply-guying to tech posts"}]`, string(b)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (suite *InstancePeersGetTestSuite) TestInstancePeersGetFunkyParams() { | ||||||
|  | 	recorder := httptest.NewRecorder() | ||||||
|  | 	ctx, _ := gin.CreateTestContext(recorder) | ||||||
|  | 
 | ||||||
|  | 	baseURI := fmt.Sprintf("%s://%s", config.GetProtocol(), config.GetHost()) | ||||||
|  | 	requestURI := fmt.Sprintf("%s/%s?filter=aaaaaaaaaaaaaaaaa,open", baseURI, instance.InstancePeersPath) | ||||||
|  | 	ctx.Request = httptest.NewRequest(http.MethodGet, requestURI, nil) | ||||||
|  | 
 | ||||||
|  | 	suite.instanceModule.InstancePeersGETHandler(ctx) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(http.StatusBadRequest, recorder.Code) | ||||||
|  | 
 | ||||||
|  | 	result := recorder.Result() | ||||||
|  | 	defer result.Body.Close() | ||||||
|  | 
 | ||||||
|  | 	b, err := io.ReadAll(result.Body) | ||||||
|  | 	suite.NoError(err) | ||||||
|  | 
 | ||||||
|  | 	suite.Equal(`{"error":"Bad Request: filter aaaaaaaaaaaaaaaaa not recognized; accepted values are 'open', 'suspended'"}`, string(b)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestInstancePeersGetTestSuite(t *testing.T) { | ||||||
|  | 	suite.Run(t, &InstancePeersGetTestSuite{}) | ||||||
|  | } | ||||||
|  | @ -20,17 +20,33 @@ package model | ||||||
| 
 | 
 | ||||||
| import "mime/multipart" | import "mime/multipart" | ||||||
| 
 | 
 | ||||||
|  | // Domain represents a remote domain | ||||||
|  | // | ||||||
|  | // swagger:model domain | ||||||
|  | type Domain struct { | ||||||
|  | 	// The hostname of the domain. | ||||||
|  | 	// example: example.org | ||||||
|  | 	Domain string `form:"domain" json:"domain" validate:"required"` | ||||||
|  | 	// Time at which this domain was suspended. Key will not be present on open domains. | ||||||
|  | 	// example: 2021-07-30T09:20:25+00:00 | ||||||
|  | 	SuspendedAt string `json:"suspended_at,omitempty"` | ||||||
|  | 	// Time at which this domain was silenced. Key will not be present on open domains. | ||||||
|  | 	// example: 2021-07-30T09:20:25+00:00 | ||||||
|  | 	SilencedAt string `json:"silenced_at,omitempty"` | ||||||
|  | 	// If the domain is blocked, what's the publicly-stated reason for the block. | ||||||
|  | 	// example: they smell | ||||||
|  | 	PublicComment string `form:"public_comment" json:"public_comment,omitempty"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // DomainBlock represents a block on one domain | // DomainBlock represents a block on one domain | ||||||
| // | // | ||||||
| // swagger:model domainBlock | // swagger:model domainBlock | ||||||
| type DomainBlock struct { | type DomainBlock struct { | ||||||
|  | 	Domain | ||||||
| 	// The ID of the domain block. | 	// The ID of the domain block. | ||||||
| 	// example: 01FBW21XJA09XYX51KV5JVBW0F | 	// example: 01FBW21XJA09XYX51KV5JVBW0F | ||||||
| 	// readonly: true | 	// readonly: true | ||||||
| 	ID string `json:"id,omitempty"` | 	ID string `json:"id,omitempty"` | ||||||
| 	// The hostname of the blocked domain. |  | ||||||
| 	// example: example.org |  | ||||||
| 	Domain string `form:"domain" json:"domain" validation:"required"` |  | ||||||
| 	// Obfuscate the domain name when serving this domain block publicly. | 	// Obfuscate the domain name when serving this domain block publicly. | ||||||
| 	// A useful anti-harassment tool. | 	// A useful anti-harassment tool. | ||||||
| 	// example: false | 	// example: false | ||||||
|  | @ -38,9 +54,6 @@ type DomainBlock struct { | ||||||
| 	// Private comment for this block, visible to our instance admins only. | 	// Private comment for this block, visible to our instance admins only. | ||||||
| 	// example: they are poopoo | 	// example: they are poopoo | ||||||
| 	PrivateComment string `json:"private_comment,omitempty"` | 	PrivateComment string `json:"private_comment,omitempty"` | ||||||
| 	// Public comment for this block, visible if domain blocks are served publicly. |  | ||||||
| 	// example: they smell |  | ||||||
| 	PublicComment string `form:"public_comment" json:"public_comment,omitempty"` |  | ||||||
| 	// The ID of the subscription that created/caused this domain block. | 	// The ID of the subscription that created/caused this domain block. | ||||||
| 	// example: 01FBW25TF5J67JW3HFHZCSD23K | 	// example: 01FBW25TF5J67JW3HFHZCSD23K | ||||||
| 	SubscriptionID string `json:"subscription_id,omitempty"` | 	SubscriptionID string `json:"subscription_id,omitempty"` | ||||||
|  | @ -67,6 +67,9 @@ type Configuration struct { | ||||||
| 	WebTemplateBaseDir string `name:"web-template-base-dir" usage:"Basedir for html templating files for rendering pages and composing emails."` | 	WebTemplateBaseDir string `name:"web-template-base-dir" usage:"Basedir for html templating files for rendering pages and composing emails."` | ||||||
| 	WebAssetBaseDir    string `name:"web-asset-base-dir" usage:"Directory to serve static assets from, accessible at example.org/assets/"` | 	WebAssetBaseDir    string `name:"web-asset-base-dir" usage:"Directory to serve static assets from, accessible at example.org/assets/"` | ||||||
| 
 | 
 | ||||||
|  | 	InstanceExposePeers     bool `name:"instance-expose-peers" usage:"Allow unauthenticated users to query /api/v1/instance/peers?filter=open"` | ||||||
|  | 	InstanceExposeSuspended bool `name:"instance-expose-suspended" usage:"Expose suspended instances via web UI, and allow unauthenticated users to query /api/v1/instance/peers?filter=suspended"` | ||||||
|  | 
 | ||||||
| 	AccountsRegistrationOpen bool `name:"accounts-registration-open" usage:"Allow anyone to submit an account signup request. If false, server will be invite-only."` | 	AccountsRegistrationOpen bool `name:"accounts-registration-open" usage:"Allow anyone to submit an account signup request. If false, server will be invite-only."` | ||||||
| 	AccountsApprovalRequired bool `name:"accounts-approval-required" usage:"Do account signups require approval by an admin or moderator before user can log in? If false, new registrations will be automatically approved."` | 	AccountsApprovalRequired bool `name:"accounts-approval-required" usage:"Do account signups require approval by an admin or moderator before user can log in? If false, new registrations will be automatically approved."` | ||||||
| 	AccountsReasonRequired   bool `name:"accounts-reason-required" usage:"Do new account signups require a reason to be submitted on registration?"` | 	AccountsReasonRequired   bool `name:"accounts-reason-required" usage:"Do new account signups require a reason to be submitted on registration?"` | ||||||
|  |  | ||||||
|  | @ -46,6 +46,9 @@ var Defaults = Configuration{ | ||||||
| 	WebTemplateBaseDir: "./web/template/", | 	WebTemplateBaseDir: "./web/template/", | ||||||
| 	WebAssetBaseDir:    "./web/assets/", | 	WebAssetBaseDir:    "./web/assets/", | ||||||
| 
 | 
 | ||||||
|  | 	InstanceExposePeers:     false, | ||||||
|  | 	InstanceExposeSuspended: false, | ||||||
|  | 
 | ||||||
| 	AccountsRegistrationOpen: true, | 	AccountsRegistrationOpen: true, | ||||||
| 	AccountsApprovalRequired: true, | 	AccountsApprovalRequired: true, | ||||||
| 	AccountsReasonRequired:   true, | 	AccountsReasonRequired:   true, | ||||||
|  |  | ||||||
|  | @ -60,6 +60,10 @@ func AddServerFlags(cmd *cobra.Command) { | ||||||
| 		cmd.Flags().String(WebTemplateBaseDirFlag(), cfg.WebTemplateBaseDir, fieldtag("WebTemplateBaseDir", "usage")) | 		cmd.Flags().String(WebTemplateBaseDirFlag(), cfg.WebTemplateBaseDir, fieldtag("WebTemplateBaseDir", "usage")) | ||||||
| 		cmd.Flags().String(WebAssetBaseDirFlag(), cfg.WebAssetBaseDir, fieldtag("WebAssetBaseDir", "usage")) | 		cmd.Flags().String(WebAssetBaseDirFlag(), cfg.WebAssetBaseDir, fieldtag("WebAssetBaseDir", "usage")) | ||||||
| 
 | 
 | ||||||
|  | 		// Instance | ||||||
|  | 		cmd.Flags().Bool(InstanceExposePeersFlag(), cfg.InstanceExposePeers, fieldtag("InstanceExposePeers", "usage")) | ||||||
|  | 		cmd.Flags().Bool(InstanceExposeSuspendedFlag(), cfg.InstanceExposeSuspended, fieldtag("InstanceExposeSuspended", "usage")) | ||||||
|  | 
 | ||||||
| 		// Accounts | 		// Accounts | ||||||
| 		cmd.Flags().Bool(AccountsRegistrationOpenFlag(), cfg.AccountsRegistrationOpen, fieldtag("AccountsRegistrationOpen", "usage")) | 		cmd.Flags().Bool(AccountsRegistrationOpenFlag(), cfg.AccountsRegistrationOpen, fieldtag("AccountsRegistrationOpen", "usage")) | ||||||
| 		cmd.Flags().Bool(AccountsApprovalRequiredFlag(), cfg.AccountsApprovalRequired, fieldtag("AccountsApprovalRequired", "usage")) | 		cmd.Flags().Bool(AccountsApprovalRequiredFlag(), cfg.AccountsApprovalRequired, fieldtag("AccountsApprovalRequired", "usage")) | ||||||
|  |  | ||||||
|  | @ -543,6 +543,56 @@ func GetWebAssetBaseDir() string { return global.GetWebAssetBaseDir() } | ||||||
| // SetWebAssetBaseDir safely sets the value for global configuration 'WebAssetBaseDir' field | // SetWebAssetBaseDir safely sets the value for global configuration 'WebAssetBaseDir' field | ||||||
| func SetWebAssetBaseDir(v string) { global.SetWebAssetBaseDir(v) } | func SetWebAssetBaseDir(v string) { global.SetWebAssetBaseDir(v) } | ||||||
| 
 | 
 | ||||||
|  | // GetInstanceExposePeers safely fetches the Configuration value for state's 'InstanceExposePeers' field | ||||||
|  | func (st *ConfigState) GetInstanceExposePeers() (v bool) { | ||||||
|  | 	st.mutex.Lock() | ||||||
|  | 	v = st.config.InstanceExposePeers | ||||||
|  | 	st.mutex.Unlock() | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetInstanceExposePeers safely sets the Configuration value for state's 'InstanceExposePeers' field | ||||||
|  | func (st *ConfigState) SetInstanceExposePeers(v bool) { | ||||||
|  | 	st.mutex.Lock() | ||||||
|  | 	defer st.mutex.Unlock() | ||||||
|  | 	st.config.InstanceExposePeers = v | ||||||
|  | 	st.reloadToViper() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // InstanceExposePeersFlag returns the flag name for the 'InstanceExposePeers' field | ||||||
|  | func InstanceExposePeersFlag() string { return "instance-expose-peers" } | ||||||
|  | 
 | ||||||
|  | // GetInstanceExposePeers safely fetches the value for global configuration 'InstanceExposePeers' field | ||||||
|  | func GetInstanceExposePeers() bool { return global.GetInstanceExposePeers() } | ||||||
|  | 
 | ||||||
|  | // SetInstanceExposePeers safely sets the value for global configuration 'InstanceExposePeers' field | ||||||
|  | func SetInstanceExposePeers(v bool) { global.SetInstanceExposePeers(v) } | ||||||
|  | 
 | ||||||
|  | // GetInstanceExposeSuspended safely fetches the Configuration value for state's 'InstanceExposeSuspended' field | ||||||
|  | func (st *ConfigState) GetInstanceExposeSuspended() (v bool) { | ||||||
|  | 	st.mutex.Lock() | ||||||
|  | 	v = st.config.InstanceExposeSuspended | ||||||
|  | 	st.mutex.Unlock() | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetInstanceExposeSuspended safely sets the Configuration value for state's 'InstanceExposeSuspended' field | ||||||
|  | func (st *ConfigState) SetInstanceExposeSuspended(v bool) { | ||||||
|  | 	st.mutex.Lock() | ||||||
|  | 	defer st.mutex.Unlock() | ||||||
|  | 	st.config.InstanceExposeSuspended = v | ||||||
|  | 	st.reloadToViper() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // InstanceExposeSuspendedFlag returns the flag name for the 'InstanceExposeSuspended' field | ||||||
|  | func InstanceExposeSuspendedFlag() string { return "instance-expose-suspended" } | ||||||
|  | 
 | ||||||
|  | // GetInstanceExposeSuspended safely fetches the value for global configuration 'InstanceExposeSuspended' field | ||||||
|  | func GetInstanceExposeSuspended() bool { return global.GetInstanceExposeSuspended() } | ||||||
|  | 
 | ||||||
|  | // SetInstanceExposeSuspended safely sets the value for global configuration 'InstanceExposeSuspended' field | ||||||
|  | func SetInstanceExposeSuspended(v bool) { global.SetInstanceExposeSuspended(v) } | ||||||
|  | 
 | ||||||
| // GetAccountsRegistrationOpen safely fetches the Configuration value for state's 'AccountsRegistrationOpen' field | // GetAccountsRegistrationOpen safely fetches the Configuration value for state's 'AccountsRegistrationOpen' field | ||||||
| func (st *ConfigState) GetAccountsRegistrationOpen() (v bool) { | func (st *ConfigState) GetAccountsRegistrationOpen() (v bool) { | ||||||
| 	st.mutex.Lock() | 	st.mutex.Lock() | ||||||
|  |  | ||||||
|  | @ -98,6 +98,25 @@ func (i *instanceDB) CountInstanceDomains(ctx context.Context, domain string) (i | ||||||
| 	return count, nil | 	return count, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (i *instanceDB) GetInstancePeers(ctx context.Context, includeSuspended bool) ([]*gtsmodel.Instance, db.Error) { | ||||||
|  | 	instances := []*gtsmodel.Instance{} | ||||||
|  | 
 | ||||||
|  | 	q := i.conn. | ||||||
|  | 		NewSelect(). | ||||||
|  | 		Model(&instances). | ||||||
|  | 		Where("domain != ?", config.GetHost()) | ||||||
|  | 
 | ||||||
|  | 	if !includeSuspended { | ||||||
|  | 		q = q.Where("? IS NULL", bun.Ident("suspended_at")) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if err := q.Scan(ctx); err != nil { | ||||||
|  | 		return nil, i.conn.ProcessError(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return instances, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (i *instanceDB) GetInstanceAccounts(ctx context.Context, domain string, maxID string, limit int) ([]*gtsmodel.Account, db.Error) { | func (i *instanceDB) GetInstanceAccounts(ctx context.Context, domain string, maxID string, limit int) ([]*gtsmodel.Account, db.Error) { | ||||||
| 	logrus.Debug("GetAccountsForInstance") | 	logrus.Debug("GetAccountsForInstance") | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,4 +37,7 @@ type Instance interface { | ||||||
| 
 | 
 | ||||||
| 	// GetInstanceAccounts returns a slice of accounts from the given instance, arranged by ID. | 	// GetInstanceAccounts returns a slice of accounts from the given instance, arranged by ID. | ||||||
| 	GetInstanceAccounts(ctx context.Context, domain string, maxID string, limit int) ([]*gtsmodel.Account, Error) | 	GetInstanceAccounts(ctx context.Context, domain string, maxID string, limit int) ([]*gtsmodel.Account, Error) | ||||||
|  | 
 | ||||||
|  | 	// GetInstancePeers returns a slice of instances that the host instance knows about. | ||||||
|  | 	GetInstancePeers(ctx context.Context, includeSuspended bool) ([]*gtsmodel.Instance, Error) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -55,7 +55,7 @@ func (p *processor) DomainBlocksImport(ctx context.Context, account *gtsmodel.Ac | ||||||
| 
 | 
 | ||||||
| 	blocks := []*apimodel.DomainBlock{} | 	blocks := []*apimodel.DomainBlock{} | ||||||
| 	for _, d := range d { | 	for _, d := range d { | ||||||
| 		block, err := p.DomainBlockCreate(ctx, account, d.Domain, false, d.PublicComment, "", "") | 		block, err := p.DomainBlockCreate(ctx, account, d.Domain.Domain, false, d.PublicComment, "", "") | ||||||
| 
 | 
 | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, err | ||||||
|  |  | ||||||
|  | @ -21,13 +21,16 @@ package processing | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"sort" | ||||||
| 
 | 
 | ||||||
| 	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" | 	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/config" | 	"github.com/superseriousbusiness/gotosocial/internal/config" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/db" | 	"github.com/superseriousbusiness/gotosocial/internal/db" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/oauth" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/text" | 	"github.com/superseriousbusiness/gotosocial/internal/text" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/util" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/validate" | 	"github.com/superseriousbusiness/gotosocial/internal/validate" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -45,6 +48,67 @@ func (p *processor) InstanceGet(ctx context.Context, domain string) (*apimodel.I | ||||||
| 	return ai, nil | 	return ai, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (p *processor) InstancePeersGet(ctx context.Context, authed *oauth.Auth, includeSuspended bool, includeOpen bool, flat bool) (interface{}, gtserror.WithCode) { | ||||||
|  | 	domains := []*apimodel.Domain{} | ||||||
|  | 
 | ||||||
|  | 	if includeOpen { | ||||||
|  | 		if !config.GetInstanceExposePeers() && (authed.Account == nil || authed.User == nil) { | ||||||
|  | 			err := fmt.Errorf("peers open query requires an authenticated account/user") | ||||||
|  | 			return nil, gtserror.NewErrorUnauthorized(err, err.Error()) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		instances, err := p.db.GetInstancePeers(ctx, false) | ||||||
|  | 		if err != nil && err != db.ErrNoEntries { | ||||||
|  | 			err = fmt.Errorf("error selecting instance peers: %s", err) | ||||||
|  | 			return nil, gtserror.NewErrorInternalError(err) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for _, i := range instances { | ||||||
|  | 			domain := &apimodel.Domain{Domain: i.Domain} | ||||||
|  | 			domains = append(domains, domain) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if includeSuspended { | ||||||
|  | 		if !config.GetInstanceExposeSuspended() && (authed.Account == nil || authed.User == nil) { | ||||||
|  | 			err := fmt.Errorf("peers suspended query requires an authenticated account/user") | ||||||
|  | 			return nil, gtserror.NewErrorUnauthorized(err, err.Error()) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		domainBlocks := []*gtsmodel.DomainBlock{} | ||||||
|  | 		if err := p.db.GetAll(ctx, &domainBlocks); err != nil && err != db.ErrNoEntries { | ||||||
|  | 			return nil, gtserror.NewErrorInternalError(err) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for _, d := range domainBlocks { | ||||||
|  | 			if d.Obfuscate { | ||||||
|  | 				d.Domain = obfuscate(d.Domain) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			domain := &apimodel.Domain{ | ||||||
|  | 				Domain:        d.Domain, | ||||||
|  | 				SuspendedAt:   util.FormatISO8601(d.CreatedAt), | ||||||
|  | 				PublicComment: d.PublicComment, | ||||||
|  | 			} | ||||||
|  | 			domains = append(domains, domain) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	sort.Slice(domains, func(i, j int) bool { | ||||||
|  | 		return domains[i].Domain < domains[j].Domain | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	if flat { | ||||||
|  | 		flattened := []string{} | ||||||
|  | 		for _, d := range domains { | ||||||
|  | 			flattened = append(flattened, d.Domain) | ||||||
|  | 		} | ||||||
|  | 		return flattened, nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return domains, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSettingsUpdateRequest) (*apimodel.Instance, gtserror.WithCode) { | func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSettingsUpdateRequest) (*apimodel.Instance, gtserror.WithCode) { | ||||||
| 	// fetch the instance entry from the db for processing | 	// fetch the instance entry from the db for processing | ||||||
| 	i := >smodel.Instance{} | 	i := >smodel.Instance{} | ||||||
|  | @ -160,3 +224,15 @@ func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe | ||||||
| 
 | 
 | ||||||
| 	return ai, nil | 	return ai, nil | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func obfuscate(domain string) string { | ||||||
|  | 	obfuscated := make([]rune, len(domain)) | ||||||
|  | 	for i, r := range domain { | ||||||
|  | 		if i%3 == 1 || i%5 == 1 { | ||||||
|  | 			obfuscated[i] = '*' | ||||||
|  | 		} else { | ||||||
|  | 			obfuscated[i] = r | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return string(obfuscated) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -137,6 +137,7 @@ type Processor interface { | ||||||
| 
 | 
 | ||||||
| 	// InstanceGet retrieves instance information for serving at api/v1/instance | 	// InstanceGet retrieves instance information for serving at api/v1/instance | ||||||
| 	InstanceGet(ctx context.Context, domain string) (*apimodel.Instance, gtserror.WithCode) | 	InstanceGet(ctx context.Context, domain string) (*apimodel.Instance, gtserror.WithCode) | ||||||
|  | 	InstancePeersGet(ctx context.Context, authed *oauth.Auth, includeSuspended bool, includeOpen bool, flat bool) (interface{}, gtserror.WithCode) | ||||||
| 	// InstancePatch updates this instance according to the given form. | 	// InstancePatch updates this instance according to the given form. | ||||||
| 	// | 	// | ||||||
| 	// It should already be ascertained that the requesting account is authenticated and an admin. | 	// It should already be ascertained that the requesting account is authenticated and an admin. | ||||||
|  |  | ||||||
|  | @ -701,8 +701,10 @@ func (c *converter) NotificationToAPINotification(ctx context.Context, n *gtsmod | ||||||
| 
 | 
 | ||||||
| func (c *converter) DomainBlockToAPIDomainBlock(ctx context.Context, b *gtsmodel.DomainBlock, export bool) (*model.DomainBlock, error) { | func (c *converter) DomainBlockToAPIDomainBlock(ctx context.Context, b *gtsmodel.DomainBlock, export bool) (*model.DomainBlock, error) { | ||||||
| 	domainBlock := &model.DomainBlock{ | 	domainBlock := &model.DomainBlock{ | ||||||
|  | 		Domain: model.Domain{ | ||||||
| 			Domain:        b.Domain, | 			Domain:        b.Domain, | ||||||
| 			PublicComment: b.PublicComment, | 			PublicComment: b.PublicComment, | ||||||
|  | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// if we're exporting a domain block, return it with minimal information attached | 	// if we're exporting a domain block, return it with minimal information attached | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ nav: | ||||||
|     - "configuration/general.md" |     - "configuration/general.md" | ||||||
|     - "configuration/database.md" |     - "configuration/database.md" | ||||||
|     - "configuration/web.md" |     - "configuration/web.md" | ||||||
|  |     - "configuration/instance.md" | ||||||
|     - "configuration/accounts.md" |     - "configuration/accounts.md" | ||||||
|     - "configuration/media.md" |     - "configuration/media.md" | ||||||
|     - "configuration/storage.md" |     - "configuration/storage.md" | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ set -e | ||||||
| echo "STARTING CLI TESTS" | echo "STARTING CLI TESTS" | ||||||
| 
 | 
 | ||||||
| echo "TEST_1 Make sure defaults are set correctly." | echo "TEST_1 Make sure defaults are set correctly." | ||||||
| TEST_1_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | TEST_1_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","instance-expose-peers":false,"instance-expose-suspended":false,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | ||||||
| TEST_1="$(go run ./cmd/gotosocial/... debug config)" | TEST_1="$(go run ./cmd/gotosocial/... debug config)" | ||||||
| if [ "${TEST_1}" != "${TEST_1_EXPECTED}" ]; then | if [ "${TEST_1}" != "${TEST_1_EXPECTED}" ]; then | ||||||
|     echo "TEST_1 not equal TEST_1_EXPECTED" |     echo "TEST_1 not equal TEST_1_EXPECTED" | ||||||
|  | @ -15,7 +15,7 @@ else | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| echo "TEST_2 Override db-address from default using cli flag." | echo "TEST_2 Override db-address from default using cli flag." | ||||||
| TEST_2_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.db.address","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | TEST_2_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.db.address","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","instance-expose-peers":false,"instance-expose-suspended":false,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | ||||||
| TEST_2="$(go run ./cmd/gotosocial/... --db-address some.db.address debug config)" | TEST_2="$(go run ./cmd/gotosocial/... --db-address some.db.address debug config)" | ||||||
| if [ "${TEST_2}" != "${TEST_2_EXPECTED}" ]; then | if [ "${TEST_2}" != "${TEST_2_EXPECTED}" ]; then | ||||||
|     echo "TEST_2 not equal TEST_2_EXPECTED" |     echo "TEST_2 not equal TEST_2_EXPECTED" | ||||||
|  | @ -25,7 +25,7 @@ else | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| echo "TEST_3 Override db-address from default using env var." | echo "TEST_3 Override db-address from default using env var." | ||||||
| TEST_3_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.db.address","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | TEST_3_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.db.address","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","instance-expose-peers":false,"instance-expose-suspended":false,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | ||||||
| TEST_3="$(GTS_DB_ADDRESS=some.db.address go run ./cmd/gotosocial/... debug config)" | TEST_3="$(GTS_DB_ADDRESS=some.db.address go run ./cmd/gotosocial/... debug config)" | ||||||
| if [ "${TEST_3}" != "${TEST_3_EXPECTED}" ]; then | if [ "${TEST_3}" != "${TEST_3_EXPECTED}" ]; then | ||||||
|     echo "TEST_3 not equal TEST_3_EXPECTED" |     echo "TEST_3 not equal TEST_3_EXPECTED" | ||||||
|  | @ -35,7 +35,7 @@ else | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| echo "TEST_4 Override db-address from default using both env var and cli flag. The cli flag should take priority." | echo "TEST_4 Override db-address from default using both env var and cli flag. The cli flag should take priority." | ||||||
| TEST_4_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.other.db.address","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | TEST_4_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.other.db.address","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","instance-expose-peers":false,"instance-expose-suspended":false,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | ||||||
| TEST_4="$(GTS_DB_ADDRESS=some.db.address go run ./cmd/gotosocial/... --db-address some.other.db.address debug config)" | TEST_4="$(GTS_DB_ADDRESS=some.db.address go run ./cmd/gotosocial/... --db-address some.other.db.address debug config)" | ||||||
| if [ "${TEST_4}" != "${TEST_4_EXPECTED}" ]; then | if [ "${TEST_4}" != "${TEST_4_EXPECTED}" ]; then | ||||||
|     echo "TEST_4 not equal TEST_4_EXPECTED" |     echo "TEST_4 not equal TEST_4_EXPECTED" | ||||||
|  | @ -45,7 +45,7 @@ else | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| echo "TEST_5 Test loading a config file by passing an env var." | echo "TEST_5 Test loading a config file by passing an env var." | ||||||
| TEST_5_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | TEST_5_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","instance-expose-peers":false,"instance-expose-suspended":false,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | ||||||
| TEST_5="$(GTS_CONFIG_PATH=./test/test.yaml go run ./cmd/gotosocial/... debug config)" | TEST_5="$(GTS_CONFIG_PATH=./test/test.yaml go run ./cmd/gotosocial/... debug config)" | ||||||
| if [ "${TEST_5}" != "${TEST_5_EXPECTED}" ]; then | if [ "${TEST_5}" != "${TEST_5_EXPECTED}" ]; then | ||||||
|     echo "TEST_5 not equal TEST_5_EXPECTED" |     echo "TEST_5 not equal TEST_5_EXPECTED" | ||||||
|  | @ -55,7 +55,7 @@ else | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| echo "TEST_6 Test loading a config file by passing cli flag." | echo "TEST_6 Test loading a config file by passing cli flag." | ||||||
| TEST_6_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | TEST_6_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","instance-expose-peers":false,"instance-expose-suspended":false,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | ||||||
| TEST_6="$(go run ./cmd/gotosocial/... --config-path ./test/test.yaml debug config)" | TEST_6="$(go run ./cmd/gotosocial/... --config-path ./test/test.yaml debug config)" | ||||||
| if [ "${TEST_6}" != "${TEST_6_EXPECTED}" ]; then | if [ "${TEST_6}" != "${TEST_6_EXPECTED}" ]; then | ||||||
|     echo "TEST_6 not equal TEST_6_EXPECTED" |     echo "TEST_6 not equal TEST_6_EXPECTED" | ||||||
|  | @ -65,7 +65,7 @@ else | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| echo "TEST_7 Test loading a config file and overriding one of the variables with a cli flag." | echo "TEST_7 Test loading a config file and overriding one of the variables with a cli flag." | ||||||
| TEST_7_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | TEST_7_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","instance-expose-peers":false,"instance-expose-suspended":false,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | ||||||
| TEST_7="$(go run ./cmd/gotosocial/... --config-path ./test/test.yaml --account-domain '' debug config)" | TEST_7="$(go run ./cmd/gotosocial/... --config-path ./test/test.yaml --account-domain '' debug config)" | ||||||
| if [ "${TEST_7}" != "${TEST_7_EXPECTED}" ]; then | if [ "${TEST_7}" != "${TEST_7_EXPECTED}" ]; then | ||||||
|     echo "TEST_7 not equal TEST_7_EXPECTED" |     echo "TEST_7 not equal TEST_7_EXPECTED" | ||||||
|  | @ -75,7 +75,7 @@ else | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| echo "TEST_8 Test loading a config file and overriding one of the variables with an env var." | echo "TEST_8 Test loading a config file and overriding one of the variables with an env var." | ||||||
| TEST_8_EXPECTED='{"account-domain":"peepee","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | TEST_8_EXPECTED='{"account-domain":"peepee","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","instance-expose-peers":false,"instance-expose-suspended":false,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | ||||||
| TEST_8="$(GTS_ACCOUNT_DOMAIN='peepee' go run ./cmd/gotosocial/... --config-path ./test/test.yaml debug config)" | TEST_8="$(GTS_ACCOUNT_DOMAIN='peepee' go run ./cmd/gotosocial/... --config-path ./test/test.yaml debug config)" | ||||||
| if [ "${TEST_8}" != "${TEST_8_EXPECTED}" ]; then | if [ "${TEST_8}" != "${TEST_8_EXPECTED}" ]; then | ||||||
|     echo "TEST_8 not equal TEST_8_EXPECTED" |     echo "TEST_8 not equal TEST_8_EXPECTED" | ||||||
|  | @ -85,7 +85,7 @@ else | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| echo "TEST_9 Test loading a config file and overriding one of the variables with both an env var and a cli flag. The cli flag should have priority." | echo "TEST_9 Test loading a config file and overriding one of the variables with both an env var and a cli flag. The cli flag should have priority." | ||||||
| TEST_9_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | TEST_9_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","instance-expose-peers":false,"instance-expose-suspended":false,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | ||||||
| TEST_9="$(GTS_ACCOUNT_DOMAIN='peepee' go run ./cmd/gotosocial/... --config-path ./test/test.yaml --account-domain '' debug config)" | TEST_9="$(GTS_ACCOUNT_DOMAIN='peepee' go run ./cmd/gotosocial/... --config-path ./test/test.yaml --account-domain '' debug config)" | ||||||
| if [ "${TEST_9}" != "${TEST_9_EXPECTED}" ]; then | if [ "${TEST_9}" != "${TEST_9_EXPECTED}" ]; then | ||||||
|     echo "TEST_9 not equal TEST_9_EXPECTED" |     echo "TEST_9 not equal TEST_9_EXPECTED" | ||||||
|  | @ -95,7 +95,7 @@ else | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| echo "TEST_10 Test loading a config file from json." | echo "TEST_10 Test loading a config file from json." | ||||||
| TEST_10_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.json","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | TEST_10_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.json","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","instance-expose-peers":false,"instance-expose-suspended":false,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | ||||||
| TEST_10="$(go run ./cmd/gotosocial/... --config-path ./test/test.json debug config)" | TEST_10="$(go run ./cmd/gotosocial/... --config-path ./test/test.json debug config)" | ||||||
| if [ "${TEST_10}" != "${TEST_10_EXPECTED}" ]; then | if [ "${TEST_10}" != "${TEST_10_EXPECTED}" ]; then | ||||||
|     echo "TEST_10 not equal TEST_10_EXPECTED" |     echo "TEST_10 not equal TEST_10_EXPECTED" | ||||||
|  | @ -105,7 +105,7 @@ else | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| echo "TEST_11 Test loading a partial config file. Default values should be used apart from those set in the config file." | echo "TEST_11 Test loading a partial config file. Default values should be used apart from those set in the config file." | ||||||
| TEST_11_EXPECTED='{"account-domain":"peepee.poopoo","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test2.yaml","db-address":"","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"trace","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | TEST_11_EXPECTED='{"account-domain":"peepee.poopoo","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"advanced-cookies-samesite":"lax","application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test2.yaml","db-address":"","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","instance-expose-peers":false,"instance-expose-suspended":false,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"trace","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}' | ||||||
| TEST_11="$(go run ./cmd/gotosocial/... --config-path ./test/test2.yaml debug config)" | TEST_11="$(go run ./cmd/gotosocial/... --config-path ./test/test2.yaml debug config)" | ||||||
| if [ "${TEST_11}" != "${TEST_11_EXPECTED}" ]; then | if [ "${TEST_11}" != "${TEST_11_EXPECTED}" ]; then | ||||||
|     echo "TEST_11 not equal TEST_11_EXPECTED" |     echo "TEST_11 not equal TEST_11_EXPECTED" | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ | ||||||
| 
 | 
 | ||||||
| set -eu | set -eu | ||||||
| 
 | 
 | ||||||
| EXPECTED='{"account-domain":"peepee","accounts-approval-required":false,"accounts-reason-required":false,"accounts-registration-open":true,"advanced-cookies-samesite":"strict","application-name":"gts","bind-address":"127.0.0.1","config-path":"./test/test.yaml","db-address":":memory:","db-database":"gotosocial_prod","db-password":"hunter2","db-port":6969,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"sqlite","db-user":"sex-haver","email":"","host":"example.com","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":true,"log-level":"info","media-description-max-chars":5000,"media-description-min-chars":69,"media-image-max-size":420,"media-remote-cache-days":30,"media-video-max-size":420,"oidc-client-id":"1234","oidc-client-secret":"shhhh its a secret","oidc-enabled":true,"oidc-idp-name":"sex-haver","oidc-issuer":"whoknows","oidc-scopes":["read","write"],"oidc-skip-verification":true,"password":"","path":"","port":6969,"protocol":"http","smtp-from":"queen@terfisland.org","smtp-host":"example.com","smtp-password":"hunter2","smtp-port":4269,"smtp-username":"sex-haver","software-version":"","statuses-cw-max-chars":420,"statuses-max-chars":69,"statuses-media-max-files":1,"statuses-poll-max-options":1,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/root/store","syslog-address":"127.0.0.1:6969","syslog-enabled":true,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"/root","web-template-base-dir":"/root"}' | EXPECTED='{"account-domain":"peepee","accounts-approval-required":false,"accounts-reason-required":false,"accounts-registration-open":true,"advanced-cookies-samesite":"strict","application-name":"gts","bind-address":"127.0.0.1","config-path":"./test/test.yaml","db-address":":memory:","db-database":"gotosocial_prod","db-password":"hunter2","db-port":6969,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"sqlite","db-user":"sex-haver","email":"","host":"example.com","instance-expose-peers":true,"instance-expose-suspended":true,"letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":true,"log-level":"info","media-description-max-chars":5000,"media-description-min-chars":69,"media-image-max-size":420,"media-remote-cache-days":30,"media-video-max-size":420,"oidc-client-id":"1234","oidc-client-secret":"shhhh its a secret","oidc-enabled":true,"oidc-idp-name":"sex-haver","oidc-issuer":"whoknows","oidc-scopes":["read","write"],"oidc-skip-verification":true,"password":"","path":"","port":6969,"protocol":"http","smtp-from":"queen@terfisland.org","smtp-host":"example.com","smtp-password":"hunter2","smtp-port":4269,"smtp-username":"sex-haver","software-version":"","statuses-cw-max-chars":420,"statuses-max-chars":69,"statuses-media-max-files":1,"statuses-poll-max-options":1,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/root/store","syslog-address":"127.0.0.1:6969","syslog-enabled":true,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"/root","web-template-base-dir":"/root"}' | ||||||
| 
 | 
 | ||||||
| # Set all the environment variables to  | # Set all the environment variables to  | ||||||
| # ensure that these are parsed without panic | # ensure that these are parsed without panic | ||||||
|  | @ -25,6 +25,8 @@ GTS_TLS_MODE='' \ | ||||||
| GTS_DB_TLS_CA_CERT='' \ | GTS_DB_TLS_CA_CERT='' \ | ||||||
| GTS_WEB_TEMPLATE_BASE_DIR='/root' \ | GTS_WEB_TEMPLATE_BASE_DIR='/root' \ | ||||||
| GTS_WEB_ASSET_BASE_DIR='/root' \ | GTS_WEB_ASSET_BASE_DIR='/root' \ | ||||||
|  | GTS_INSTANCE_EXPOSE_PEERS=true \ | ||||||
|  | GTS_INSTANCE_EXPOSE_SUSPENDED=true \ | ||||||
| GTS_ACCOUNTS_REGISTRATION_OPEN=true \ | GTS_ACCOUNTS_REGISTRATION_OPEN=true \ | ||||||
| GTS_ACCOUNTS_APPROVAL_REQUIRED=false \ | GTS_ACCOUNTS_APPROVAL_REQUIRED=false \ | ||||||
| GTS_ACCOUNTS_REASON_REQUIRED=false \ | GTS_ACCOUNTS_REASON_REQUIRED=false \ | ||||||
|  |  | ||||||
|  | @ -56,6 +56,9 @@ var TestDefaults = config.Configuration{ | ||||||
| 	WebTemplateBaseDir: "./web/template/", | 	WebTemplateBaseDir: "./web/template/", | ||||||
| 	WebAssetBaseDir:    "./web/assets/", | 	WebAssetBaseDir:    "./web/assets/", | ||||||
| 
 | 
 | ||||||
|  | 	InstanceExposePeers:     true, | ||||||
|  | 	InstanceExposeSuspended: true, | ||||||
|  | 
 | ||||||
| 	AccountsRegistrationOpen: true, | 	AccountsRegistrationOpen: true, | ||||||
| 	AccountsApprovalRequired: true, | 	AccountsApprovalRequired: true, | ||||||
| 	AccountsReasonRequired:   true, | 	AccountsReasonRequired:   true, | ||||||
|  |  | ||||||
|  | @ -153,6 +153,12 @@ func StandardDBSetup(db db.DB, accounts map[string]*gtsmodel.Account) { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	for _, v := range NewTestInstances() { | ||||||
|  | 		if err := db.Put(ctx, v); err != nil { | ||||||
|  | 			logrus.Panic(err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	for _, v := range NewTestUsers() { | 	for _, v := range NewTestUsers() { | ||||||
| 		if err := db.Put(ctx, v); err != nil { | 		if err := db.Put(ctx, v); err != nil { | ||||||
| 			logrus.Panic(err) | 			logrus.Panic(err) | ||||||
|  |  | ||||||
|  | @ -936,10 +936,31 @@ func NewTestEmojis() map[string]*gtsmodel.Emoji { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func NewTestInstances() map[string]*gtsmodel.Instance { | ||||||
|  | 	return map[string]*gtsmodel.Instance{ | ||||||
|  | 		"fossbros-anonymous.io": { | ||||||
|  | 			ID:        "01G5H6YMJQKR86QZKXXQ2S95FZ", | ||||||
|  | 			CreatedAt: TimeMustParse("2021-09-20T12:40:37+02:00"), | ||||||
|  | 			UpdatedAt: TimeMustParse("2021-09-20T12:40:37+02:00"), | ||||||
|  | 			Domain:    "fossbros-anonymous.io", | ||||||
|  | 			URI:       "http://fossbros-anonymous.io", | ||||||
|  | 		}, | ||||||
|  | 		"example.org": { | ||||||
|  | 			ID:        "01G5H71G52DJKVBYKXPNPNDN1G", | ||||||
|  | 			CreatedAt: TimeMustParse("2020-05-13T15:29:12+02:00"), | ||||||
|  | 			UpdatedAt: TimeMustParse("2020-05-13T15:29:12+02:00"), | ||||||
|  | 			Domain:    "example.org", | ||||||
|  | 			URI:       "http://example.org", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func NewTestDomainBlocks() map[string]*gtsmodel.DomainBlock { | func NewTestDomainBlocks() map[string]*gtsmodel.DomainBlock { | ||||||
| 	return map[string]*gtsmodel.DomainBlock{ | 	return map[string]*gtsmodel.DomainBlock{ | ||||||
| 		"replyguys.com": { | 		"replyguys.com": { | ||||||
| 			ID:                 "01FF22EQM7X8E3RX1XGPN7S87D", | 			ID:                 "01FF22EQM7X8E3RX1XGPN7S87D", | ||||||
|  | 			CreatedAt:          TimeMustParse("2020-05-13T15:29:12+02:00"), | ||||||
|  | 			UpdatedAt:          TimeMustParse("2020-05-13T15:29:12+02:00"), | ||||||
| 			Domain:             "replyguys.com", | 			Domain:             "replyguys.com", | ||||||
| 			CreatedByAccountID: "01F8MH17FWEB39HZJ76B6VXSKF", | 			CreatedByAccountID: "01F8MH17FWEB39HZJ76B6VXSKF", | ||||||
| 			PrivateComment:     "i blocked this domain because they keep replying with pushy + unwarranted linux advice", | 			PrivateComment:     "i blocked this domain because they keep replying with pushy + unwarranted linux advice", | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue