mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 08:12:26 -05:00 
			
		
		
		
	[bugfix] Log + ignore unknown notification types (#3577)
* [bugfix] Log + ignore unknown notification types * pass context to ParseNotificationTypes
This commit is contained in:
		
					parent
					
						
							
								61f8f1e0e3
							
						
					
				
			
			
				commit
				
					
						65917f5bb9
					
				
			
		
					 4 changed files with 106 additions and 63 deletions
				
			
		|  | @ -18,11 +18,14 @@ | ||||||
| package notifications | package notifications | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"context" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"github.com/gin-gonic/gin" | 	"github.com/gin-gonic/gin" | ||||||
| 	apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" | 	apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | ||||||
|  | 	"github.com/superseriousbusiness/gotosocial/internal/log" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/oauth" | 	"github.com/superseriousbusiness/gotosocial/internal/oauth" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/paging" | 	"github.com/superseriousbusiness/gotosocial/internal/paging" | ||||||
| ) | ) | ||||||
|  | @ -151,18 +154,6 @@ func (m *Module) NotificationsGETHandler(c *gin.Context) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	types, errWithCode := apiutil.ParseNotificationTypes(c.QueryArray(TypesKey)) |  | ||||||
| 	if errWithCode != nil { |  | ||||||
| 		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	exclTypes, errWithCode := apiutil.ParseNotificationTypes(c.QueryArray(ExcludeTypesKey)) |  | ||||||
| 	if errWithCode != nil { |  | ||||||
| 		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) |  | ||||||
| 		return |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	page, errWithCode := paging.ParseIDPage(c, | 	page, errWithCode := paging.ParseIDPage(c, | ||||||
| 		1,  // min limit | 		1,  // min limit | ||||||
| 		80, // max limit | 		80, // max limit | ||||||
|  | @ -173,12 +164,13 @@ func (m *Module) NotificationsGETHandler(c *gin.Context) { | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	ctx := c.Request.Context() | ||||||
| 	resp, errWithCode := m.processor.Timeline().NotificationsGet( | 	resp, errWithCode := m.processor.Timeline().NotificationsGet( | ||||||
| 		c.Request.Context(), | 		ctx, | ||||||
| 		authed, | 		authed, | ||||||
| 		page, | 		page, | ||||||
| 		types, | 		ParseNotificationTypes(ctx, c.QueryArray(TypesKey)),        // Include types. | ||||||
| 		exclTypes, | 		ParseNotificationTypes(ctx, c.QueryArray(ExcludeTypesKey)), // Exclude types. | ||||||
| 	) | 	) | ||||||
| 	if errWithCode != nil { | 	if errWithCode != nil { | ||||||
| 		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) | 		apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1) | ||||||
|  | @ -191,3 +183,28 @@ func (m *Module) NotificationsGETHandler(c *gin.Context) { | ||||||
| 
 | 
 | ||||||
| 	apiutil.JSON(c, http.StatusOK, resp.Items) | 	apiutil.JSON(c, http.StatusOK, resp.Items) | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // ParseNotificationTypes converts the given slice of string values | ||||||
|  | // to gtsmodel notification types, logging + skipping unknown types. | ||||||
|  | func ParseNotificationTypes( | ||||||
|  | 	ctx context.Context, | ||||||
|  | 	values []string, | ||||||
|  | ) []gtsmodel.NotificationType { | ||||||
|  | 	if len(values) == 0 { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ntypes := make([]gtsmodel.NotificationType, 0, len(values)) | ||||||
|  | 	for _, value := range values { | ||||||
|  | 		ntype := gtsmodel.NewNotificationType(value) | ||||||
|  | 		if ntype == gtsmodel.NotificationUnknown { | ||||||
|  | 			// Type we don't know about (yet), log and ignore it. | ||||||
|  | 			log.Debugf(ctx, "ignoring unknown type %s", value) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ntypes = append(ntypes, ntype) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ntypes | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -248,6 +248,45 @@ func (suite *NotificationsTestSuite) TestGetNotificationsIncludeOneType() { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // Test including an unknown notification type, it should be ignored. | ||||||
|  | func (suite *NotificationsTestSuite) TestGetNotificationsIncludeUnknownType() { | ||||||
|  | 	testAccount := suite.testAccounts["local_account_1"] | ||||||
|  | 	testToken := suite.testTokens["local_account_1"] | ||||||
|  | 	testUser := suite.testUsers["local_account_1"] | ||||||
|  | 
 | ||||||
|  | 	suite.addMoreNotifications(testAccount) | ||||||
|  | 
 | ||||||
|  | 	maxID := "" | ||||||
|  | 	minID := "" | ||||||
|  | 	limit := 10 | ||||||
|  | 	types := []string{"favourite", "something.weird"} | ||||||
|  | 	excludeTypes := []string(nil) | ||||||
|  | 	expectedHTTPStatus := http.StatusOK | ||||||
|  | 	expectedBody := "" | ||||||
|  | 
 | ||||||
|  | 	notifications, _, err := suite.getNotifications( | ||||||
|  | 		testAccount, | ||||||
|  | 		testToken, | ||||||
|  | 		testUser, | ||||||
|  | 		maxID, | ||||||
|  | 		minID, | ||||||
|  | 		limit, | ||||||
|  | 		types, | ||||||
|  | 		excludeTypes, | ||||||
|  | 		expectedHTTPStatus, | ||||||
|  | 		expectedBody, | ||||||
|  | 	) | ||||||
|  | 	if err != nil { | ||||||
|  | 		suite.FailNow(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// This should only include the fav notification. | ||||||
|  | 	suite.Len(notifications, 1) | ||||||
|  | 	for _, notification := range notifications { | ||||||
|  | 		suite.Equal("favourite", notification.Type) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func TestBookmarkTestSuite(t *testing.T) { | func TestBookmarkTestSuite(t *testing.T) { | ||||||
| 	suite.Run(t, new(NotificationsTestSuite)) | 	suite.Run(t, new(NotificationsTestSuite)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -18,13 +18,11 @@ | ||||||
| package util | package util | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"errors" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | 	"github.com/superseriousbusiness/gotosocial/internal/gtserror" | ||||||
| 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | @ -218,51 +216,6 @@ func ParseInteractionReblogs(value string, defaultValue bool) (bool, gtserror.Wi | ||||||
| 	return parseBool(value, defaultValue, InteractionReblogsKey) | 	return parseBool(value, defaultValue, InteractionReblogsKey) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func ParseNotificationType(value string) (gtsmodel.NotificationType, gtserror.WithCode) { |  | ||||||
| 	switch strings.ToLower(value) { |  | ||||||
| 	case "follow": |  | ||||||
| 		return gtsmodel.NotificationFollow, nil |  | ||||||
| 	case "follow_request": |  | ||||||
| 		return gtsmodel.NotificationFollowRequest, nil |  | ||||||
| 	case "mention": |  | ||||||
| 		return gtsmodel.NotificationMention, nil |  | ||||||
| 	case "reblog": |  | ||||||
| 		return gtsmodel.NotificationReblog, nil |  | ||||||
| 	case "favourite": |  | ||||||
| 		return gtsmodel.NotificationFave, nil |  | ||||||
| 	case "poll": |  | ||||||
| 		return gtsmodel.NotificationPoll, nil |  | ||||||
| 	case "status": |  | ||||||
| 		return gtsmodel.NotificationStatus, nil |  | ||||||
| 	case "admin.sign_up": |  | ||||||
| 		return gtsmodel.NotificationSignup, nil |  | ||||||
| 	case "pending.favourite": |  | ||||||
| 		return gtsmodel.NotificationPendingFave, nil |  | ||||||
| 	case "pending.reply": |  | ||||||
| 		return gtsmodel.NotificationPendingReply, nil |  | ||||||
| 	case "pending.reblog": |  | ||||||
| 		return gtsmodel.NotificationPendingReblog, nil |  | ||||||
| 	default: |  | ||||||
| 		text := fmt.Sprintf("unrecognized notification type %s", value) |  | ||||||
| 		return 0, gtserror.NewErrorBadRequest(errors.New(text), text) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func ParseNotificationTypes(values []string) ([]gtsmodel.NotificationType, gtserror.WithCode) { |  | ||||||
| 	if len(values) == 0 { |  | ||||||
| 		return nil, nil |  | ||||||
| 	} |  | ||||||
| 	ntypes := make([]gtsmodel.NotificationType, len(values)) |  | ||||||
| 	for i, value := range values { |  | ||||||
| 		ntype, errWithCode := ParseNotificationType(value) |  | ||||||
| 		if errWithCode != nil { |  | ||||||
| 			return nil, errWithCode |  | ||||||
| 		} |  | ||||||
| 		ntypes[i] = ntype |  | ||||||
| 	} |  | ||||||
| 	return ntypes, nil |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* | /* | ||||||
| 	Parse functions for *REQUIRED* parameters. | 	Parse functions for *REQUIRED* parameters. | ||||||
| */ | */ | ||||||
|  |  | ||||||
|  | @ -17,7 +17,10 @@ | ||||||
| 
 | 
 | ||||||
| package gtsmodel | package gtsmodel | ||||||
| 
 | 
 | ||||||
| import "time" | import ( | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| // Notification models an alert/notification sent to an account about something like a reblog, like, new follow request, etc. | // Notification models an alert/notification sent to an account about something like a reblog, like, new follow request, etc. | ||||||
| type Notification struct { | type Notification struct { | ||||||
|  | @ -40,6 +43,7 @@ type NotificationType enumType | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
| 	// Notification Types | 	// Notification Types | ||||||
|  | 	NotificationUnknown       NotificationType = 0  // NotificationUnknown -- unknown notification type, error if this occurs | ||||||
| 	NotificationFollow        NotificationType = 1  // NotificationFollow -- someone followed you | 	NotificationFollow        NotificationType = 1  // NotificationFollow -- someone followed you | ||||||
| 	NotificationFollowRequest NotificationType = 2  // NotificationFollowRequest -- someone requested to follow you | 	NotificationFollowRequest NotificationType = 2  // NotificationFollowRequest -- someone requested to follow you | ||||||
| 	NotificationMention       NotificationType = 3  // NotificationMention -- someone mentioned you in their status | 	NotificationMention       NotificationType = 3  // NotificationMention -- someone mentioned you in their status | ||||||
|  | @ -82,3 +86,33 @@ func (t NotificationType) String() string { | ||||||
| 		panic("invalid notification type") | 		panic("invalid notification type") | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // NewNotificationType returns a notification type from the given value. | ||||||
|  | func NewNotificationType(in string) NotificationType { | ||||||
|  | 	switch strings.ToLower(in) { | ||||||
|  | 	case "follow": | ||||||
|  | 		return NotificationFollow | ||||||
|  | 	case "follow_request": | ||||||
|  | 		return NotificationFollowRequest | ||||||
|  | 	case "mention": | ||||||
|  | 		return NotificationMention | ||||||
|  | 	case "reblog": | ||||||
|  | 		return NotificationReblog | ||||||
|  | 	case "favourite": | ||||||
|  | 		return NotificationFave | ||||||
|  | 	case "poll": | ||||||
|  | 		return NotificationPoll | ||||||
|  | 	case "status": | ||||||
|  | 		return NotificationStatus | ||||||
|  | 	case "admin.sign_up": | ||||||
|  | 		return NotificationSignup | ||||||
|  | 	case "pending.favourite": | ||||||
|  | 		return NotificationPendingFave | ||||||
|  | 	case "pending.reply": | ||||||
|  | 		return NotificationPendingReply | ||||||
|  | 	case "pending.reblog": | ||||||
|  | 		return NotificationPendingReblog | ||||||
|  | 	default: | ||||||
|  | 		return NotificationUnknown | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue