Browse Source

Added geodb locale converter

Toby Chui 5 months ago
parent
commit
b9f5f15c72
3 changed files with 113 additions and 11 deletions
  1. 13 4
      mod/auth/sso/openid.go
  2. 33 7
      mod/auth/sso/users.go
  3. 67 0
      mod/geodb/locale.go

+ 13 - 4
mod/auth/sso/openid.go

@@ -3,6 +3,7 @@ package sso
 import (
 	"encoding/json"
 	"net/http"
+	"strings"
 )
 
 type OpenIDConfiguration struct {
@@ -17,12 +18,19 @@ type OpenIDConfiguration struct {
 }
 
 func (h *SSOHandler) HandleDiscoveryRequest(w http.ResponseWriter, r *http.Request) {
+
+	//Prepend https:// if not present
+	authBaseURL := h.Config.AuthURL
+	if !strings.HasPrefix(authBaseURL, "http://") && !strings.HasPrefix(authBaseURL, "https://") {
+		authBaseURL = "https://" + authBaseURL
+	}
+
 	//Handle the discovery request
 	discovery := OpenIDConfiguration{
-		Issuer:                 "https://" + h.Config.AuthURL,
-		AuthorizationEndpoint:  "https://" + h.Config.AuthURL + "/oauth2/auth",
-		TokenEndpoint:          "https://" + h.Config.AuthURL + "/oauth2/token",
-		JwksUri:                "https://" + h.Config.AuthURL + "/jwks.json",
+		Issuer:                 authBaseURL,
+		AuthorizationEndpoint:  authBaseURL + "/oauth2/authorize",
+		TokenEndpoint:          authBaseURL + "/oauth2/token",
+		JwksUri:                authBaseURL + "/jwks.json",
 		ResponseTypesSupported: []string{"code", "token"},
 		SubjectTypesSupported:  []string{"public"},
 		IDTokenSigningAlgValuesSupported: []string{
@@ -45,5 +53,6 @@ func (h *SSOHandler) HandleDiscoveryRequest(w http.ResponseWriter, r *http.Reque
 
 	//Write the response
 	js, _ := json.Marshal(discovery)
+	w.Header().Set("Content-Type", "application/json")
 	w.Write(js)
 }

+ 33 - 7
mod/auth/sso/users.go

@@ -23,13 +23,27 @@ type SubdomainAccessRule struct {
 }
 
 type UserEntry struct {
-	UserID       string                          //User ID, in UUIDv4 format
-	Username     string                          //Username
-	PasswordHash string                          //Password hash
-	TOTPCode     string                          //2FA TOTP code
-	Enable2FA    bool                            //Enable 2FA for this user
-	Subdomains   map[string]*SubdomainAccessRule //Subdomain and access rule
-	parent       *SSOHandler                     //Parent SSO handler
+	UserID           string                          `json:sub`                //User ID
+	Username         string                          `json:"name"`             //Username
+	Email            string                          `json:"email"`            //Email
+	PasswordHash     string                          `json:"passwordhash"`     //Password hash
+	TOTPCode         string                          `json:"totpcode"`         //TOTP code
+	Enable2FA        bool                            `json:"enable2fa"`        //Enable 2FA
+	Subdomains       map[string]*SubdomainAccessRule `json:"subdomains"`       //Subdomain access rules
+	LastLogin        int64                           `json:"lastlogin"`        //Last login time
+	LastLoginIP      string                          `json:"lastloginip"`      //Last login IP
+	LastLoginCountry string                          `json:"lastlogincountry"` //Last login country
+	parent           *SSOHandler                     //Parent SSO handler
+}
+
+type ClientResponse struct {
+	Sub               string `json:"sub"`                //User ID
+	Name              string `json:"name"`               //Username
+	Nickname          string `json:"nickname"`           //Nickname
+	PreferredUsername string `json:"preferred_username"` //Preferred Username
+	Email             string `json:"email"`              //Email
+	Locale            string `json:"locale"`             //Locale
+	Website           string `json:"website"`            //Website
 }
 
 func (s *SSOHandler) SSOUserExists(userid string) bool {
@@ -113,3 +127,15 @@ func (u *UserEntry) VerifyTotp(enteredCode string) bool {
 	totp := gotp.NewDefaultTOTP(u.TOTPCode)
 	return totp.Verify(enteredCode, time.Now().Unix())
 }
+
+func (u *UserEntry) GetClientResponse() ClientResponse {
+	return ClientResponse{
+		Sub:               u.UserID,
+		Name:              u.Username,
+		Nickname:          u.Username,
+		PreferredUsername: u.Username,
+		Email:             u.Email,
+		Locale:            "en",
+		Website:           "",
+	}
+}

+ 67 - 0
mod/geodb/locale.go

@@ -0,0 +1,67 @@
+package geodb
+
+import "net/http"
+
+// GetRequesterCountryISOCode get the locale of the requester
+func (s *Store) GetLocaleFromRequest(r *http.Request) (string, error) {
+	cc := s.GetRequesterCountryISOCode(r)
+	return GetLocaleFromCountryCode(cc), nil
+}
+
+// GetLocaleFromCountryCode get the locale given the country code
+func GetLocaleFromCountryCode(cc string) string {
+	//If you find your country is not in the list, please add it here
+	mapCountryToLocale := map[string]string{
+		"aa": "ar_AA",
+		"by": "be_BY",
+		"bg": "bg_BG",
+		"es": "ca_ES",
+		"cz": "cs_CZ",
+		"dk": "da_DK",
+		"ch": "de_CH",
+		"de": "de_DE",
+		"gr": "el_GR",
+		"au": "en_AU",
+		"be": "en_BE",
+		"gb": "en_GB",
+		"jp": "en_JP",
+		"us": "en_US",
+		"za": "en_ZA",
+		"fi": "fi_FI",
+		"ca": "fr_CA",
+		"fr": "fr_FR",
+		"hr": "hr_HR",
+		"hu": "hu_HU",
+		"is": "is_IS",
+		"it": "it_IT",
+		"il": "iw_IL",
+		"kr": "ko_KR",
+		"lt": "lt_LT",
+		"lv": "lv_LV",
+		"mk": "mk_MK",
+		"nl": "nl_NL",
+		"no": "no_NO",
+		"pl": "pl_PL",
+		"br": "pt_BR",
+		"pt": "pt_PT",
+		"ro": "ro_RO",
+		"ru": "ru_RU",
+		"sp": "sh_SP",
+		"sk": "sk_SK",
+		"sl": "sl_SL",
+		"al": "sq_AL",
+		"se": "sv_SE",
+		"th": "th_TH",
+		"tr": "tr_TR",
+		"ua": "uk_UA",
+		"cn": "zh_CN",
+		"tw": "zh_TW",
+		"hk": "zh_HK",
+	}
+	locale, ok := mapCountryToLocale[cc]
+	if !ok {
+		return "en-US"
+	}
+
+	return locale
+}