Преглед на файлове

fix(go): allow id to be string or int;

Vishal Dalwadi преди 3 месеца
родител
ревизия
6092207f17
променени са 6 файла, в които са добавени 43 реда и са изтрити 16 реда
  1. 34 6
      pro/auth/auth.go
  2. 2 3
      pro/auth/azure-ad.go
  3. 2 2
      pro/auth/github.go
  4. 1 1
      pro/auth/google.go
  5. 1 1
      pro/auth/headless_callback.go
  6. 3 3
      pro/auth/oidc.go

+ 34 - 6
pro/auth/auth.go

@@ -1,9 +1,11 @@
 package auth
 
 import (
+	"encoding/json"
 	"errors"
 	"fmt"
 	"net/http"
+	"strconv"
 	"strings"
 	"time"
 
@@ -34,12 +36,38 @@ const (
 
 // OAuthUser - generic OAuth strategy user
 type OAuthUser struct {
-	ID                string `json:"id" bson:"id"`
-	Name              string `json:"name" bson:"name"`
-	Email             string `json:"email" bson:"email"`
-	Login             string `json:"login" bson:"login"`
-	UserPrincipalName string `json:"userPrincipalName" bson:"userPrincipalName"`
-	AccessToken       string `json:"accesstoken" bson:"accesstoken"`
+	ID                StringOrInt `json:"id" bson:"id"`
+	Name              string      `json:"name" bson:"name"`
+	Email             string      `json:"email" bson:"email"`
+	Login             string      `json:"login" bson:"login"`
+	UserPrincipalName string      `json:"userPrincipalName" bson:"userPrincipalName"`
+	AccessToken       string      `json:"accesstoken" bson:"accesstoken"`
+}
+
+// TODO: this is a very poor solution.
+// We should not return the same OAuthUser for different
+// IdPs. They should have the user that their APIs return.
+// But that's a very big change. So, making do with this
+// for now.
+
+type StringOrInt string
+
+func (s *StringOrInt) UnmarshalJSON(data []byte) error {
+	// Try to unmarshal as string directly
+	var strVal string
+	if err := json.Unmarshal(data, &strVal); err == nil {
+		*s = StringOrInt(strVal)
+		return nil
+	}
+
+	// Try to unmarshal as int and convert to string
+	var intVal int
+	if err := json.Unmarshal(data, &intVal); err == nil {
+		*s = StringOrInt(strconv.Itoa(intVal))
+		return nil
+	}
+
+	return fmt.Errorf("cannot unmarshal %s into StringOrInt", string(data))
 }
 
 var (

+ 2 - 3
pro/auth/azure-ad.go

@@ -111,7 +111,7 @@ func handleAzureCallback(w http.ResponseWriter, r *http.Request) {
 					logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
 					return
 				}
-				user.ExternalIdentityProviderID = content.ID
+				user.ExternalIdentityProviderID = string(content.ID)
 				if err = logic.CreateUser(&user); err != nil {
 					handleSomethingWentWrong(w)
 					return
@@ -125,7 +125,7 @@ func handleAzureCallback(w http.ResponseWriter, r *http.Request) {
 				}
 				err = logic.InsertPendingUser(&models.User{
 					UserName:                   content.Email,
-					ExternalIdentityProviderID: content.ID,
+					ExternalIdentityProviderID: string(content.ID),
 					AuthType:                   models.OAuth,
 				})
 				if err != nil {
@@ -243,7 +243,6 @@ func getAzureUserInfo(state string, code string) (*OAuthUser, error) {
 	}
 	if userInfo.Email == "" && userInfo.UserPrincipalName != "" {
 		userInfo.Email = userInfo.UserPrincipalName
-
 	}
 	if userInfo.Email == "" {
 		err = errors.New("failed to fetch user email from SSO state")

+ 2 - 2
pro/auth/github.go

@@ -111,7 +111,7 @@ func handleGithubCallback(w http.ResponseWriter, r *http.Request) {
 					logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
 					return
 				}
-				user.ExternalIdentityProviderID = content.ID
+				user.ExternalIdentityProviderID = string(content.ID)
 				if err = logic.CreateUser(&user); err != nil {
 					handleSomethingWentWrong(w)
 					return
@@ -125,7 +125,7 @@ func handleGithubCallback(w http.ResponseWriter, r *http.Request) {
 				}
 				err = logic.InsertPendingUser(&models.User{
 					UserName:                   content.Email,
-					ExternalIdentityProviderID: content.ID,
+					ExternalIdentityProviderID: string(content.ID),
 					AuthType:                   models.OAuth,
 				})
 				if err != nil {

+ 1 - 1
pro/auth/google.go

@@ -106,7 +106,7 @@ func handleGoogleCallback(w http.ResponseWriter, r *http.Request) {
 				}
 				err = logic.InsertPendingUser(&models.User{
 					UserName:                   content.Email,
-					ExternalIdentityProviderID: content.ID,
+					ExternalIdentityProviderID: string(content.ID),
 					AuthType:                   models.OAuth,
 				})
 				if err != nil {

+ 1 - 1
pro/auth/headless_callback.go

@@ -65,7 +65,7 @@ func HandleHeadlessSSOCallback(w http.ResponseWriter, r *http.Request) {
 		if database.IsEmptyRecord(err) { // user must not exist, so try to make one
 			err = logic.InsertPendingUser(&models.User{
 				UserName:                   userClaims.getUserName(),
-				ExternalIdentityProviderID: userClaims.ID,
+				ExternalIdentityProviderID: string(userClaims.ID),
 				AuthType:                   models.OAuth,
 			})
 			if err != nil {

+ 3 - 3
pro/auth/oidc.go

@@ -102,7 +102,7 @@ func handleOIDCCallback(w http.ResponseWriter, r *http.Request) {
 					logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
 					return
 				}
-				user.ExternalIdentityProviderID = content.ID
+				user.ExternalIdentityProviderID = string(content.ID)
 				if err = logic.CreateUser(&user); err != nil {
 					handleSomethingWentWrong(w)
 					return
@@ -116,7 +116,7 @@ func handleOIDCCallback(w http.ResponseWriter, r *http.Request) {
 				}
 				err = logic.InsertPendingUser(&models.User{
 					UserName:                   content.Email,
-					ExternalIdentityProviderID: content.ID,
+					ExternalIdentityProviderID: string(content.ID),
 					AuthType:                   models.OAuth,
 				})
 				if err != nil {
@@ -232,7 +232,7 @@ func getOIDCUserInfo(state string, code string) (u *OAuthUser, e error) {
 		e = fmt.Errorf("error when claiming OIDCUser: \"%s\"", err.Error())
 	}
 
-	u.ID = idToken.Subject
+	u.ID = StringOrInt(idToken.Subject)
 
 	return
 }