[#5673] added check for empty OAuth2User.AvatarURL
This commit is contained in:
		
							parent
							
								
									ff3f4332ce
								
							
						
					
					
						commit
						56b756e16b
					
				| 
						 | 
					@ -5,6 +5,7 @@ import (
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"errors"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"log/slog"
 | 
				
			||||||
	"maps"
 | 
						"maps"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
| 
						 | 
					@ -236,7 +237,11 @@ func oauth2Submit(e *core.RecordAuthWithOAuth2RequestEvent, optExternalAuth *cor
 | 
				
			||||||
				oldCanAssignUsername(txApp, e.Collection, e.OAuth2User.Username) {
 | 
									oldCanAssignUsername(txApp, e.Collection, e.OAuth2User.Username) {
 | 
				
			||||||
				payload[e.Collection.OAuth2.MappedFields.Username] = e.OAuth2User.Username
 | 
									payload[e.Collection.OAuth2.MappedFields.Username] = e.OAuth2User.Username
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if _, ok := payload[e.Collection.OAuth2.MappedFields.AvatarURL]; !ok && e.Collection.OAuth2.MappedFields.AvatarURL != "" {
 | 
								if _, ok := payload[e.Collection.OAuth2.MappedFields.AvatarURL]; !ok &&
 | 
				
			||||||
 | 
									// no existing OAuth2 mapping
 | 
				
			||||||
 | 
									e.Collection.OAuth2.MappedFields.AvatarURL != "" &&
 | 
				
			||||||
 | 
									// non-empty OAuth2 avatar url
 | 
				
			||||||
 | 
									e.OAuth2User.AvatarURL != "" {
 | 
				
			||||||
				mappedField := e.Collection.Fields.GetByName(e.Collection.OAuth2.MappedFields.AvatarURL)
 | 
									mappedField := e.Collection.Fields.GetByName(e.Collection.OAuth2.MappedFields.AvatarURL)
 | 
				
			||||||
				if mappedField != nil && mappedField.Type() == core.FieldTypeFile {
 | 
									if mappedField != nil && mappedField.Type() == core.FieldTypeFile {
 | 
				
			||||||
					// download the avatar if the mapped field is a file
 | 
										// download the avatar if the mapped field is a file
 | 
				
			||||||
| 
						 | 
					@ -246,9 +251,10 @@ func oauth2Submit(e *core.RecordAuthWithOAuth2RequestEvent, optExternalAuth *cor
 | 
				
			||||||
						return filesystem.NewFileFromURL(ctx, e.OAuth2User.AvatarURL)
 | 
											return filesystem.NewFileFromURL(ctx, e.OAuth2User.AvatarURL)
 | 
				
			||||||
					}()
 | 
										}()
 | 
				
			||||||
					if err != nil {
 | 
										if err != nil {
 | 
				
			||||||
						return err
 | 
											txApp.Logger().Warn("Failed to retrieve OAuth2 avatar", slog.String("error", err.Error()))
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											payload[e.Collection.OAuth2.MappedFields.AvatarURL] = avatarFile
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					payload[e.Collection.OAuth2.MappedFields.AvatarURL] = avatarFile
 | 
					 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					// otherwise - assign the url string
 | 
										// otherwise - assign the url string
 | 
				
			||||||
					payload[e.Collection.OAuth2.MappedFields.AvatarURL] = e.OAuth2User.AvatarURL
 | 
										payload[e.Collection.OAuth2.MappedFields.AvatarURL] = e.OAuth2User.AvatarURL
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1109,6 +1109,85 @@ func TestRecordAuthWithOAuth2(t *testing.T) {
 | 
				
			||||||
				"OnRecordValidate": 4,
 | 
									"OnRecordValidate": 4,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name:   "creating user (with mapped OAuth2 avatarURL field but empty OAuth2User.avatarURL value)",
 | 
				
			||||||
 | 
								Method: http.MethodPost,
 | 
				
			||||||
 | 
								URL:    "/api/collections/users/auth-with-oauth2",
 | 
				
			||||||
 | 
								Body: strings.NewReader(`{
 | 
				
			||||||
 | 
									"provider": "test",
 | 
				
			||||||
 | 
									"code":"123",
 | 
				
			||||||
 | 
									"redirectURL": "https://example.com"
 | 
				
			||||||
 | 
								}`),
 | 
				
			||||||
 | 
								BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
 | 
				
			||||||
 | 
									usersCol, err := app.FindCollectionByNameOrId("users")
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										t.Fatal(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// register the test provider
 | 
				
			||||||
 | 
									auth.Providers["test"] = func() auth.Provider {
 | 
				
			||||||
 | 
										return &oauth2MockProvider{
 | 
				
			||||||
 | 
											AuthUser: &auth.AuthUser{
 | 
				
			||||||
 | 
												Id:        "oauth2_id",
 | 
				
			||||||
 | 
												Email:     "oauth2@example.com",
 | 
				
			||||||
 | 
												AvatarURL: "",
 | 
				
			||||||
 | 
											},
 | 
				
			||||||
 | 
											Token: &oauth2.Token{AccessToken: "abc"},
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// add the test provider in the collection
 | 
				
			||||||
 | 
									usersCol.MFA.Enabled = false
 | 
				
			||||||
 | 
									usersCol.OAuth2.Enabled = true
 | 
				
			||||||
 | 
									usersCol.OAuth2.Providers = []core.OAuth2ProviderConfig{{
 | 
				
			||||||
 | 
										Name:         "test",
 | 
				
			||||||
 | 
										ClientId:     "123",
 | 
				
			||||||
 | 
										ClientSecret: "456",
 | 
				
			||||||
 | 
									}}
 | 
				
			||||||
 | 
									usersCol.OAuth2.MappedFields = core.OAuth2KnownFields{
 | 
				
			||||||
 | 
										AvatarURL: "avatar",
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if err := app.Save(usersCol); err != nil {
 | 
				
			||||||
 | 
										t.Fatal(err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								ExpectedStatus: 200,
 | 
				
			||||||
 | 
								ExpectedContent: []string{
 | 
				
			||||||
 | 
									`"email":"oauth2@example.com"`,
 | 
				
			||||||
 | 
									`"emailVisibility":false`,
 | 
				
			||||||
 | 
									`"verified":true`,
 | 
				
			||||||
 | 
									`"avatar":""`,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								NotExpectedContent: []string{
 | 
				
			||||||
 | 
									// hidden fields
 | 
				
			||||||
 | 
									`"tokenKey"`,
 | 
				
			||||||
 | 
									`"password"`,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								ExpectedEvents: map[string]int{
 | 
				
			||||||
 | 
									"*":                             0,
 | 
				
			||||||
 | 
									"OnRecordAuthWithOAuth2Request": 1,
 | 
				
			||||||
 | 
									"OnRecordAuthRequest":           1,
 | 
				
			||||||
 | 
									"OnRecordCreateRequest":         1,
 | 
				
			||||||
 | 
									"OnRecordEnrich":                2, // the auth response and from the create request
 | 
				
			||||||
 | 
									// ---
 | 
				
			||||||
 | 
									"OnModelCreate":              3, // record + authOrigins + externalAuths
 | 
				
			||||||
 | 
									"OnModelCreateExecute":       3,
 | 
				
			||||||
 | 
									"OnModelAfterCreateSuccess":  3,
 | 
				
			||||||
 | 
									"OnRecordCreate":             3,
 | 
				
			||||||
 | 
									"OnRecordCreateExecute":      3,
 | 
				
			||||||
 | 
									"OnRecordAfterCreateSuccess": 3,
 | 
				
			||||||
 | 
									// ---
 | 
				
			||||||
 | 
									"OnModelUpdate":              1, // created record verified state change
 | 
				
			||||||
 | 
									"OnModelUpdateExecute":       1,
 | 
				
			||||||
 | 
									"OnModelAfterUpdateSuccess":  1,
 | 
				
			||||||
 | 
									"OnRecordUpdate":             1,
 | 
				
			||||||
 | 
									"OnRecordUpdateExecute":      1,
 | 
				
			||||||
 | 
									"OnRecordAfterUpdateSuccess": 1,
 | 
				
			||||||
 | 
									// ---
 | 
				
			||||||
 | 
									"OnModelValidate":  4,
 | 
				
			||||||
 | 
									"OnRecordValidate": 4,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Name:   "creating user (with mapped OAuth2 fields and avatarURL->non-file field)",
 | 
								Name:   "creating user (with mapped OAuth2 fields and avatarURL->non-file field)",
 | 
				
			||||||
			Method: http.MethodPost,
 | 
								Method: http.MethodPost,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue