From 77fff68e51f4e16fd5fde56f24240ba2b5dd2609 Mon Sep 17 00:00:00 2001 From: Ackermann Yuriy Date: Mon, 4 Dec 2023 20:48:49 +1300 Subject: [PATCH] Updated codebase. Test mode is onprem only now. --- api/admin.api.go | 58 --- api/buildsproxy.api.go | 91 ----- api/commonapi/common.go | 29 -- api/oauth2.api.go | 223 ----------- api/server.go | 66 ---- api/user.auth.api.go | 198 ---------- api/user.common.api.go | 2 - api/user.other.api.go | 123 +----- api/user.verify.api.go | 352 +----------------- core/shared/env.go | 17 - example.env | 28 -- frontend/src/App.svelte | 20 +- frontend/src/lib/User.api.ts | 215 ----------- frontend/src/routes/AdditionalInfo.svelte | 62 --- frontend/src/routes/Builds.svelte | 26 -- .../src/routes/ErrorEmailValidation.svelte | 41 -- frontend/src/routes/ErrorNotVerified.svelte | 8 - frontend/src/routes/Login.svelte | 68 +--- frontend/src/routes/Register.svelte | 80 ---- main.go | 20 +- services/github.oauth2.go | 161 -------- services/google.oauth2.go | 113 ------ services/notify.go | 153 -------- services/oauth2.go | 48 --- 24 files changed, 11 insertions(+), 2191 deletions(-) delete mode 100644 api/admin.api.go delete mode 100644 api/buildsproxy.api.go delete mode 100644 api/oauth2.api.go delete mode 100644 frontend/src/routes/AdditionalInfo.svelte delete mode 100644 frontend/src/routes/Builds.svelte delete mode 100644 frontend/src/routes/ErrorEmailValidation.svelte delete mode 100644 frontend/src/routes/ErrorNotVerified.svelte delete mode 100644 frontend/src/routes/Register.svelte delete mode 100644 services/github.oauth2.go delete mode 100644 services/google.oauth2.go delete mode 100644 services/notify.go delete mode 100644 services/oauth2.go diff --git a/api/admin.api.go b/api/admin.api.go deleted file mode 100644 index 01c58e2..0000000 --- a/api/admin.api.go +++ /dev/null @@ -1,58 +0,0 @@ -package api - -import ( - "log" - "net/http" - - "github.com/fido-alliance/fdo-fido-conformance-server/api/commonapi" - fdoshared "github.com/fido-alliance/fdo-fido-conformance-server/core/shared" - "github.com/fido-alliance/fdo-fido-conformance-server/dbs" - "github.com/fido-alliance/fdo-fido-conformance-server/services" -) - -type AdminApi struct { - UserDB *dbs.UserTestDB - VerifyDB *dbs.VerifyDB - NotifyService *services.NotifyService -} - -func (h *AdminApi) GetUserList(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - commonapi.RespondError(w, "Method not allowed!", http.StatusMethodNotAllowed) - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - -} - -func (h *AdminApi) SetUserAccountState(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - commonapi.RespondError(w, "Method not allowed!", http.StatusMethodNotAllowed) - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - -} - -func (h *AdminApi) EnableUser(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - commonapi.RespondError(w, "Method not allowed!", http.StatusMethodNotAllowed) - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } -} diff --git a/api/buildsproxy.api.go b/api/buildsproxy.api.go deleted file mode 100644 index fc50c8a..0000000 --- a/api/buildsproxy.api.go +++ /dev/null @@ -1,91 +0,0 @@ -package api - -import ( - "errors" - "log" - "net/http" - "net/http/httputil" - "net/url" - "strings" - - "github.com/fido-alliance/fdo-fido-conformance-server/api/commonapi" - fdoshared "github.com/fido-alliance/fdo-fido-conformance-server/core/shared" - "github.com/fido-alliance/fdo-fido-conformance-server/dbs" -) - -type BuildsProxyAPI struct { - UserDB *dbs.UserTestDB - SessionDB *dbs.SessionDB -} - -func (h *BuildsProxyAPI) checkAutzAndGetUser(r *http.Request) (*dbs.UserTestDBEntry, error) { - sessionCookie, err := r.Cookie("session") - if err != nil { - return nil, errors.New("Failed to read cookie. " + err.Error()) - - } - - if sessionCookie == nil { - return nil, errors.New("Cookie does not exists") - } - - sessionInst, err := h.SessionDB.GetSessionEntry([]byte(sessionCookie.Value)) - if err != nil { - return nil, errors.New("Session expired. " + err.Error()) - } - - if !sessionInst.LoggedIn { - return nil, errors.New("User is not logged in!" + err.Error()) - } - - userInst, err := h.UserDB.Get(sessionInst.Email) - if err != nil { - return nil, errors.New("User does not exists. " + err.Error()) - } - - return userInst, nil -} - -func (h *BuildsProxyAPI) ProxyBuilds(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - commonapi.RespondError(w, "Method not allowed!", http.StatusMethodNotAllowed) - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - _, err := h.checkAutzAndGetUser(r) - if err != nil { - log.Println("Failed to read cookie. " + err.Error()) - commonapi.RespondError(w, "Unauthorized", http.StatusUnauthorized) - return - } - - buildsApiUrl := r.Context().Value(fdoshared.CFG_ENV_API_BUILDS_URL) - - if buildsApiUrl == nil { - commonapi.RespondError(w, "Server is down. ", http.StatusInternalServerError) - return - } - - urlInst, _ := url.Parse(buildsApiUrl.(string)) - - proxy := httputil.NewSingleHostReverseProxy(urlInst) - - newPath := strings.Replace(r.URL.Path, "/api/builds/", "", 1) - - if !strings.HasPrefix(newPath, "/") { - newPath = "/" + newPath - } - - r.URL.Host = urlInst.Host - r.URL.Scheme = urlInst.Scheme - r.Host = urlInst.Host - r.URL.Path = newPath - - proxy.ServeHTTP(w, r) -} diff --git a/api/commonapi/common.go b/api/commonapi/common.go index 06a8585..b85b057 100644 --- a/api/commonapi/common.go +++ b/api/commonapi/common.go @@ -2,10 +2,7 @@ package commonapi import ( "encoding/json" - "fmt" - "log" "net/http" - "strings" "time" ) @@ -31,7 +28,6 @@ type FdoConformanceApiError struct { } func RespondError(w http.ResponseWriter, errorMessage string, httpErrorCode int) { - log.Printf("Responding error: %s. HTTP code %d", errorMessage, httpErrorCode) errorResponse := FdoConformanceApiError{ Status: FdoApiStatus_Failed, ErrorMessage: errorMessage, @@ -79,28 +75,3 @@ func CheckHeaders(w http.ResponseWriter, r *http.Request) bool { return true } - -var countriesMap map[string]string = map[string]string{ - "AW": "Aruba", "AF": "Afghanistan", "AO": "Angola", "AI": "Anguilla", "AX": "\u00c5land Islands", "AL": "Albania", "AD": "Andorra", "AE": "United Arab Emirates", "AR": "Argentina", "AM": "Armenia", "AS": "American Samoa", "AQ": "Antarctica", "TF": "French Southern and Antarctic Lands", "AG": "Antigua and Barbuda", "AU": "Australia", "AT": "Austria", "AZ": "Azerbaijan", "BI": "Burundi", "BE": "Belgium", "BJ": "Benin", "BF": "Burkina Faso", "BD": "Bangladesh", "BG": "Bulgaria", "BH": "Bahrain", "BS": "Bahamas", "BA": "Bosnia and Herzegovina", "BL": "Saint Barth\u00e9lemy", "SH": "Saint Helena, Ascension and Tristan da Cunha", "BY": "Belarus", "BZ": "Belize", "BM": "Bermuda", "BO": "Bolivia", "BQ": "Caribbean Netherlands", "BR": "Brazil", "BB": "Barbados", "BN": "Brunei", "BT": "Bhutan", "BV": "Bouvet Island", "BW": "Botswana", "CF": "Central African Republic", "CA": "Canada", "CC": "Cocos (Keeling) Islands", "CH": "Switzerland", "CL": "Chile", "CN": "China", "CI": "Ivory Coast", "CM": "Cameroon", "CD": "DR Congo", "CG": "Republic of the Congo", "CK": "Cook Islands", "CO": "Colombia", "KM": "Comoros", "CV": "Cape Verde", "CR": "Costa Rica", "CU": "Cuba", "CW": "Cura\u00e7ao", "CX": "Christmas Island", "KY": "Cayman Islands", "CY": "Cyprus", "CZ": "Czechia", "DE": "Germany", "DJ": "Djibouti", "DM": "Dominica", "DK": "Denmark", "DO": "Dominican Republic", "DZ": "Algeria", "EC": "Ecuador", "EG": "Egypt", "ER": "Eritrea", "EH": "Western Sahara", "ES": "Spain", "EE": "Estonia", "ET": "Ethiopia", "FI": "Finland", "FJ": "Fiji", "FK": "Falkland Islands", "FR": "France", "FO": "Faroe Islands", "FM": "Micronesia", "GA": "Gabon", "GB": "United Kingdom", "GE": "Georgia", "GG": "Guernsey", "GH": "Ghana", "GI": "Gibraltar", "GN": "Guinea", "GP": "Guadeloupe", "GM": "Gambia", "GW": "Guinea-Bissau", "GQ": "Equatorial Guinea", "GR": "Greece", "GD": "Grenada", "GL": "Greenland", "GT": "Guatemala", "GF": "French Guiana", "GU": "Guam", "GY": "Guyana", "HK": "Hong Kong", "HM": "Heard Island and McDonald Islands", "HN": "Honduras", "HR": "Croatia", "HT": "Haiti", "HU": "Hungary", "ID": "Indonesia", "IM": "Isle of Man", "IN": "India", "IO": "British Indian Ocean Territory", "IE": "Ireland", "IR": "Iran", "IQ": "Iraq", "IS": "Iceland", "IL": "Israel", "IT": "Italy", "JM": "Jamaica", "JE": "Jersey", "JO": "Jordan", "JP": "Japan", "KZ": "Kazakhstan", "KE": "Kenya", "KG": "Kyrgyzstan", "KH": "Cambodia", "KI": "Kiribati", "KN": "Saint Kitts and Nevis", "KR": "South Korea", "XK": "Kosovo", "KW": "Kuwait", "LA": "Laos", "LB": "Lebanon", "LR": "Liberia", "LY": "Libya", "LC": "Saint Lucia", "LI": "Liechtenstein", "LK": "Sri Lanka", "LS": "Lesotho", "LT": "Lithuania", "LU": "Luxembourg", "LV": "Latvia", "MO": "Macau", "MF": "Saint Martin", "MA": "Morocco", "MC": "Monaco", "MD": "Moldova", "MG": "Madagascar", "MV": "Maldives", "MX": "Mexico", "MH": "Marshall Islands", "MK": "North Macedonia", "ML": "Mali", "MT": "Malta", "MM": "Myanmar", "ME": "Montenegro", "MN": "Mongolia", "MP": "Northern Mariana Islands", "MZ": "Mozambique", "MR": "Mauritania", "MS": "Montserrat", "MQ": "Martinique", "MU": "Mauritius", "MW": "Malawi", "MY": "Malaysia", "YT": "Mayotte", "NA": "Namibia", "NC": "New Caledonia", "NE": "Niger", "NF": "Norfolk Island", "NG": "Nigeria", "NI": "Nicaragua", "NU": "Niue", "NL": "Netherlands", "NO": "Norway", "NP": "Nepal", "NR": "Nauru", "NZ": "New Zealand", "OM": "Oman", "PK": "Pakistan", "PA": "Panama", "PN": "Pitcairn Islands", "PE": "Peru", "PH": "Philippines", "PW": "Palau", "PG": "Papua New Guinea", "PL": "Poland", "PR": "Puerto Rico", "KP": "North Korea", "PT": "Portugal", "PY": "Paraguay", "PS": "Palestine", "PF": "French Polynesia", "QA": "Qatar", "RE": "R\u00e9union", "RO": "Romania", "RU": "Russia", "RW": "Rwanda", "SA": "Saudi Arabia", "SD": "Sudan", "SN": "Senegal", "SG": "Singapore", "GS": "South Georgia", "SJ": "Svalbard and Jan Mayen", "SB": "Solomon Islands", "SL": "Sierra Leone", "SV": "El Salvador", "SM": "San Marino", "SO": "Somalia", "PM": "Saint Pierre and Miquelon", "RS": "Serbia", "SS": "South Sudan", "ST": "S\u00e3o Tom\u00e9 and Pr\u00edncipe", "SR": "Suriname", "SK": "Slovakia", "SI": "Slovenia", "SE": "Sweden", "SZ": "Eswatini", "SX": "Sint Maarten", "SC": "Seychelles", "SY": "Syria", "TC": "Turks and Caicos Islands", "TD": "Chad", "TG": "Togo", "TH": "Thailand", "TJ": "Tajikistan", "TK": "Tokelau", "TM": "Turkmenistan", "TL": "Timor-Leste", "TO": "Tonga", "TT": "Trinidad and Tobago", "TN": "Tunisia", "TR": "Turkey", "TV": "Tuvalu", "TW": "Taiwan", "TZ": "Tanzania", "UG": "Uganda", "UA": "Ukraine", "UM": "United States Minor Outlying Islands", "UY": "Uruguay", "US": "United States", "UZ": "Uzbekistan", "VA": "Vatican City", "VC": "Saint Vincent and the Grenadines", "VE": "Venezuela", "VG": "British Virgin Islands", "VI": "United States Virgin Islands", "VN": "Vietnam", "VU": "Vanuatu", "WF": "Wallis and Futuna", "WS": "Samoa", "YE": "Yemen", "ZA": "South Africa", "ZM": "Zambia", "ZW": "Zimbabwe", -} - -func ExtractCloudflareLocation(r *http.Request) string { - cfCountryCode := r.Header.Get("CF-IPCountry") - - countryCode := "CLOUDFLARE_TEST" - if cfCountryCode != "" { - countryCode = strings.ToUpper(cfCountryCode) - } - - countryName, ok := countriesMap[countryCode] - - if countryCode == "" { - countryCode = "UNKNOWN" - } else if countryCode == "CLOUDFLARE_TEST" { - countryName = "CLOUDFLARE" - } else if !ok { - countryCode = "UNKNOWN" - } - - return fmt.Sprintf(`%s (%s)`, countryName, countryCode) -} diff --git a/api/oauth2.api.go b/api/oauth2.api.go deleted file mode 100644 index cb405a9..0000000 --- a/api/oauth2.api.go +++ /dev/null @@ -1,223 +0,0 @@ -package api - -import ( - "errors" - "log" - "net/http" - "strings" - - "github.com/fido-alliance/fdo-fido-conformance-server/api/commonapi" - fdoshared "github.com/fido-alliance/fdo-fido-conformance-server/core/shared" - "github.com/fido-alliance/fdo-fido-conformance-server/dbs" - "github.com/fido-alliance/fdo-fido-conformance-server/services" - "github.com/gorilla/mux" -) - -type OAuth2API struct { - UserDB *dbs.UserTestDB - SessionDB *dbs.SessionDB - OAuth2Service *services.OAuth2Service - Notify services.NotifyService -} - -func (h *OAuth2API) checkAutzAndGetSession(r *http.Request) (*dbs.SessionEntry, error) { - sessionCookie, err := r.Cookie("session") - if err != nil { - return nil, errors.New("Failed to read cookie. " + err.Error()) - - } - - if sessionCookie == nil { - return nil, errors.New("cookie does not exists") - } - - sessionInst, err := h.SessionDB.GetSessionEntry([]byte(sessionCookie.Value)) - if err != nil { - return nil, errors.New("Session expired. " + err.Error()) - } - - return sessionInst, nil -} - -func (h *OAuth2API) setUserSession(w http.ResponseWriter, sessionInst dbs.SessionEntry) error { - sessionDbId, err := h.SessionDB.NewSessionEntry(sessionInst) - if err != nil { - return errors.New("Error creating session. " + err.Error()) - } - - http.SetCookie(w, commonapi.GenerateCookie(sessionDbId)) - return nil -} - -type OAuth2RedictUrlResult struct { - RedirectUrl string `json:"redirect_url"` - Status commonapi.FdoConfApiStatus `json:"status"` -} - -func (h *OAuth2API) InitWithRedirectUrl(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - commonapi.RespondError(w, "Method not allowed!", http.StatusMethodNotAllowed) - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - vars := mux.Vars(r) - providerid := services.OAuth2ProviderID(vars["providerid"]) - - oauth2Provider, err := h.OAuth2Service.GetProvider(providerid) - if err != nil { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - redirectUrl, state, nonce := oauth2Provider.GetRedirectUrl() - - err = h.setUserSession(w, dbs.SessionEntry{ - OAuth2Provider: string(providerid), - OAuth2Nonce: nonce, - OAuth2State: state, - }) - if err != nil { - log.Println("Error creating session. " + err.Error()) - commonapi.RespondError(w, "Internal server error. ", http.StatusBadRequest) - return - } - - commonapi.RespondSuccessStruct(w, OAuth2RedictUrlResult{RedirectUrl: redirectUrl, Status: commonapi.FdoApiStatus_OK}) -} - -func (h *OAuth2API) ProcessCallback(w http.ResponseWriter, r *http.Request) { - session, err := h.checkAutzAndGetSession(r) - if err != nil { - log.Println(err) - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - state := r.URL.Query().Get("state") - code := r.URL.Query().Get("code") - - if state == "" || code == "" { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - vars := mux.Vars(r) - providerid := services.OAuth2ProviderID(vars["providerid"]) - - if providerid != services.OAuth2ProviderID(session.OAuth2Provider) || state != session.OAuth2State { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - oauth2Provider, err := h.OAuth2Service.GetProvider(providerid) - if err != nil { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - email, isFidoGithubMember, err := oauth2Provider.GetUserInfo(code) - if err != nil { - log.Println(err) - commonapi.RespondError(w, "Failed to validate OAuth2 code!", http.StatusUnauthorized) - return - } - - userInst, err := h.UserDB.Get(email) - - // User exists - if err == nil && userInst != nil { - if isFidoGithubMember || userInst.Status == dbs.AS_Validated { - err = h.setUserSession(w, dbs.SessionEntry{ - Email: email, - LoggedIn: true, - }) - if err != nil { - log.Println("Error creating session. " + err.Error()) - commonapi.RespondError(w, "Internal server error. ", http.StatusBadRequest) - return - } - - http.Redirect(w, r, commonapi.REDIRECT_HOME, http.StatusTemporaryRedirect) - return - } else { - err = h.setUserSession(w, dbs.SessionEntry{ - Email: email, - }) - if err != nil { - log.Println("Error creating session. " + err.Error()) - commonapi.RespondError(w, "Internal server error. ", http.StatusBadRequest) - return - } - - http.Redirect(w, r, commonapi.REDIRECT_AWAITING_VERIFICATION, http.StatusTemporaryRedirect) - return - } - - } else { // New user - if !isFidoGithubMember { - err = h.setUserSession(w, dbs.SessionEntry{ - Email: strings.ToLower(email), - OAuth2Email: strings.ToLower(email), - OAuth2AdditionalInfo: true, - }) - if err != nil { - log.Println("Error creating session. " + err.Error()) - commonapi.RespondError(w, "Internal server error. ", http.StatusBadRequest) - return - } - - http.Redirect(w, r, commonapi.REDIRECT_ADDITIONAL_INFO, http.StatusTemporaryRedirect) - return - } - - err = h.UserDB.Save(dbs.UserTestDBEntry{ - Email: strings.ToLower(email), - Status: dbs.AS_Validated, - EmailVerified: true, - }) - if err != nil { - log.Println("Error saving user. " + err.Error()) - commonapi.RespondError(w, "Internal server error.", http.StatusInternalServerError) - return - } - - if isFidoGithubMember { - err = h.setUserSession(w, dbs.SessionEntry{ - Email: email, - LoggedIn: true, - }) - if err != nil { - log.Println("Error creating session. " + err.Error()) - commonapi.RespondError(w, "Internal server error. ", http.StatusBadRequest) - return - } - - http.Redirect(w, r, commonapi.REDIRECT_HOME, http.StatusTemporaryRedirect) - } else { - err = h.setUserSession(w, dbs.SessionEntry{ - Email: strings.ToLower(email), - OAuth2Email: strings.ToLower(email), - OAuth2AdditionalInfo: true, - }) - if err != nil { - log.Println("Error creating session. " + err.Error()) - commonapi.RespondError(w, "Internal server error. ", http.StatusBadRequest) - return - } - - http.Redirect(w, r, commonapi.REDIRECT_AWAITING_VERIFICATION, http.StatusTemporaryRedirect) - } - } -} diff --git a/api/server.go b/api/server.go index 54c78eb..65b0bcf 100644 --- a/api/server.go +++ b/api/server.go @@ -10,7 +10,6 @@ import ( fdoshared "github.com/fido-alliance/fdo-fido-conformance-server/core/shared" testdbs "github.com/fido-alliance/fdo-fido-conformance-server/core/shared/testcom/dbs" "github.com/fido-alliance/fdo-fido-conformance-server/dbs" - "github.com/fido-alliance/fdo-fido-conformance-server/services" "github.com/gorilla/mux" ) @@ -28,12 +27,6 @@ func SetupServer(db *badger.DB, ctx context.Context) { devBaseDb := dbs.NewDeviceBaseDB(db) listenerDb := testdbs.NewListenerTestDB(db) doVoucherDb := dodbs.NewVoucherDB(db) - verifyDb := dbs.NewVerifyDB(db) - - notifyService := services.NewNotifyService( - ctx.Value(fdoshared.CFG_ENV_NOTIFY_SERVICE_HOST).(string), - ctx.Value(fdoshared.CFG_ENV_NOTIFY_SERVICE_SECRET).(string), - verifyDb) rvtApiHandler := testapi.RVTestMgmtAPI{ UserDB: userDb, @@ -65,45 +58,6 @@ func SetupServer(db *badger.DB, ctx context.Context) { userApiHandler := UserAPI{ UserDB: userDb, SessionDB: sessionDb, - Notify: ¬ifyService, - } - - userVerifyHandler := UserVerify{ - UserDB: userDb, - VerifyDB: verifyDb, - SessionDB: sessionDb, - NotifyService: ¬ifyService, - } - - buildsProxyHandler := BuildsProxyAPI{ - UserDB: userDb, - SessionDB: sessionDb, - } - - adminApi := AdminApi{ - UserDB: userDb, - VerifyDB: verifyDb, - NotifyService: ¬ifyService, - } - - oauth2ApiHandle := OAuth2API{ - UserDB: userDb, - SessionDB: sessionDb, - Notify: notifyService, - OAuth2Service: &services.OAuth2Service{ - Providers: map[services.OAuth2ProviderID]services.OAuth2Provider{ - services.OATH2_GITHUB: services.NewGithubOAuth2Connector(services.OAuth2ProviderConfig{ - ClientId: ctx.Value(fdoshared.CFG_ENV_GITHUB_CLIENTID).(string), - ClientSecret: ctx.Value(fdoshared.CFG_ENV_GITHUB_CLIENTSECRET).(string), - RedirectUrl: ctx.Value(fdoshared.CFG_ENV_GITHUB_REDIRECTURL).(string), - }), - services.OATH2_GOOGLE: services.NewGoogleOAuth2Connector(services.OAuth2ProviderConfig{ - ClientId: ctx.Value(fdoshared.CFG_ENV_GOOGLE_CLIENTID).(string), - ClientSecret: ctx.Value(fdoshared.CFG_ENV_GOOGLE_CLIENTSECRET).(string), - RedirectUrl: ctx.Value(fdoshared.CFG_ENV_GOOGLE_REDIRECTURL).(string), - }), - }, - }, } r := mux.NewRouter() @@ -124,32 +78,12 @@ func SetupServer(db *badger.DB, ctx context.Context) { r.HandleFunc("/api/device/testruns/{toprotocol}/{testinsthex}/{testrunid}", deviceApiHandler.DeleteTestRun).Methods("DELETE") r.HandleFunc("/api/device/testruns/{toprotocol}/{testinsthex}", deviceApiHandler.StartNewTestRun).Methods("POST") - r.PathPrefix("/api/builds/").HandlerFunc(buildsProxyHandler.ProxyBuilds) - - r.HandleFunc("/api/user/register", userApiHandler.Register) - r.HandleFunc("/api/user/register/additionalinfo", userApiHandler.AdditionalInfo) - r.HandleFunc("/api/user/login", userApiHandler.Login) r.HandleFunc("/api/user/login/onprem", userApiHandler.OnPremNoLogin) r.HandleFunc("/api/user/loggedin", userApiHandler.UserLoggedIn) - r.HandleFunc("/api/user/email/resendverification", userApiHandler.ReRequestEmailValidationLink) r.HandleFunc("/api/user/logout", userApiHandler.Logout) r.HandleFunc("/api/user/purgetests", userApiHandler.PurgeTests) r.HandleFunc("/api/user/config", userApiHandler.Config) - r.HandleFunc("/api/user/approve/{id}/{email}", userVerifyHandler.Check) - r.HandleFunc("/api/user/reject/{id}/{email}", userVerifyHandler.Reject) - r.HandleFunc("/api/user/email/check/{id}/{email}", userVerifyHandler.Check) - - r.HandleFunc("/api/user/password/reset/init", userVerifyHandler.PasswordResetInit) - r.HandleFunc("/api/user/password/reset/{id}/{email}", userVerifyHandler.PasswordResetCheck) - r.HandleFunc("/api/user/password/reset", userVerifyHandler.PasswordResetSet) - - r.HandleFunc("/api/oauth2/{providerid}/init", oauth2ApiHandle.InitWithRedirectUrl) - r.HandleFunc("/api/oauth2/{providerid}/callback", oauth2ApiHandle.ProcessCallback) - - r.HandleFunc("/api/admin/users", adminApi.GetUserList) - r.HandleFunc("/api/admin/users/{action}/{email}", adminApi.SetUserAccountState) - if ctx.Value(fdoshared.CFG_DEV_ENV) == fdoshared.CFG_ENV_DEV { r.PathPrefix("/").HandlerFunc(ProxyDevUI) } else { diff --git a/api/user.auth.api.go b/api/user.auth.api.go index 674f226..687fe6a 100644 --- a/api/user.auth.api.go +++ b/api/user.auth.api.go @@ -1,217 +1,19 @@ package api import ( - "encoding/json" - "io" "log" "net/http" "strings" "github.com/fido-alliance/fdo-fido-conformance-server/api/commonapi" - fdoshared "github.com/fido-alliance/fdo-fido-conformance-server/core/shared" "github.com/fido-alliance/fdo-fido-conformance-server/dbs" - "github.com/fido-alliance/fdo-fido-conformance-server/services" ) -func (h *UserAPI) Register(w http.ResponseWriter, r *http.Request) { - if !commonapi.CheckHeaders(w, r) { - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - bodyBytes, err := io.ReadAll(r.Body) - if err != nil { - log.Println("Failed to read body. " + err.Error()) - commonapi.RespondError(w, "Failed to read body!", http.StatusBadRequest) - return - } - - var createUser commonapi.User_UserReq - err = json.Unmarshal(bodyBytes, &createUser) - if err != nil { - log.Println("Failed to decode body. " + err.Error()) - commonapi.RespondError(w, "Failed to decode body!", http.StatusBadRequest) - return - } - - if !isEmailValid(createUser.Email) { - log.Println("Invalid email!") - commonapi.RespondError(w, "Invalid email!", http.StatusBadRequest) - return - } - - if len(createUser.Name) == 0 { - log.Println("Missing name!") - commonapi.RespondError(w, "Missing name!", http.StatusBadRequest) - return - } - - if len(createUser.Company) == 0 { - log.Println("Missing company name!") - commonapi.RespondError(w, "Missing company name!", http.StatusBadRequest) - return - } - - if len(createUser.Phone) == 0 { - log.Println("Missing phone number!") - commonapi.RespondError(w, "Missing phone number!", http.StatusBadRequest) - return - } - - if len(createUser.Password) < 8 { - log.Println("Password too short!") - commonapi.RespondError(w, "Password too short!", http.StatusBadRequest) - return - } - - userInst, err := h.UserDB.Get(createUser.Email) - if err == nil && userInst.Status == dbs.AS_Awaiting { - log.Println("User exists.") - commonapi.RespondError(w, "User exists.", http.StatusBadRequest) - return - } - - passwordHash, err := h.generatePasswordHash(createUser.Password) - if err != nil { - log.Println("Error generating user hash. " + err.Error()) - commonapi.RespondError(w, "Internal server error.", http.StatusInternalServerError) - return - } - - newUserInst := dbs.UserTestDBEntry{ - Email: strings.ToLower(createUser.Email), - PasswordHash: passwordHash, - Name: createUser.Name, - Company: createUser.Company, - Status: dbs.AS_Awaiting, - } - - err = h.UserDB.Save(newUserInst) - if err != nil { - log.Println("Error saving user. " + err.Error()) - commonapi.RespondError(w, "Internal server error.", http.StatusInternalServerError) - return - } - - submissionCountry := commonapi.ExtractCloudflareLocation(r) - - err = h.Notify.NotifyUserRegistration_EmailVerification(newUserInst.Email, submissionCountry, r.Context()) - if err != nil { - log.Println("Error sending user registration email. " + err.Error()) - commonapi.RespondError(w, "Internal server error.", http.StatusInternalServerError) - return - } - - err = h.Notify.NotifyUserRegistration_AccountValidation(newUserInst.Email, services.NotifyPayload{ - VendorEmail: newUserInst.Email, - VendorName: newUserInst.Name, - VendorPhone: createUser.Phone, - VendorCompany: newUserInst.Company, - }, submissionCountry, r.Context()) - if err != nil { - log.Println("Error sending user verification email. " + err.Error()) - commonapi.RespondError(w, "Internal server error.", http.StatusInternalServerError) - return - } - - commonapi.RespondError(w, "Your account pending approval. Once it approved you will receive notification on your email address.", http.StatusInternalServerError) -} - -func (h *UserAPI) Login(w http.ResponseWriter, r *http.Request) { - if !commonapi.CheckHeaders(w, r) { - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - bodyBytes, err := io.ReadAll(r.Body) - if err != nil { - log.Println("Failed to read body. " + err.Error()) - commonapi.RespondError(w, "Failed to read body!", http.StatusBadRequest) - return - } - - var loginUser commonapi.User_UserReq - err = json.Unmarshal(bodyBytes, &loginUser) - if err != nil { - log.Println("Failed to decode body. " + err.Error()) - commonapi.RespondError(w, "Failed to decode body!", http.StatusBadRequest) - return - } - - if !isEmailValid(loginUser.Email) { - log.Println("Invalid email!") - commonapi.RespondError(w, "Invalid email!", http.StatusBadRequest) - return - } - - userInst, err := h.UserDB.Get(loginUser.Email) - if err != nil { - log.Printf("Can not find user with email \"%s\". %s \n", loginUser.Email, err.Error()) - commonapi.RespondError(w, "Invalid email or password", http.StatusBadRequest) - return - } - - passwordMatch, err := h.verifyPasswordHash(loginUser.Password, userInst.PasswordHash) - if err != nil { - log.Println("Error while verifying hash of the password. " + err.Error()) - commonapi.RespondError(w, "Invalid emails or password", http.StatusBadRequest) - return - } - - if !passwordMatch { - log.Println("Passwords do not match.") - commonapi.RespondError(w, "Invalid emails or password", http.StatusBadRequest) - return - } - - if userInst.Status != dbs.AS_Validated { - err := h.setUserSession(w, dbs.SessionEntry{ - Email: loginUser.Email, - }) - if err != nil { - log.Println("Error creating session. " + err.Error()) - commonapi.RespondError(w, "Internal server error. ", http.StatusBadRequest) - return - } - - commonapi.RespondError(w, "Your account pending approval. Please wait 2-3 working days. Otherwise email certification@fidoalliance.org", http.StatusBadRequest) - return - } - - err = h.setUserSession(w, dbs.SessionEntry{ - Email: loginUser.Email, - LoggedIn: true, - }) - if err != nil { - log.Println("Error creating session. " + err.Error()) - commonapi.RespondError(w, "Internal server error. ", http.StatusBadRequest) - return - } - - commonapi.RespondSuccess(w) -} - func (h *UserAPI) OnPremNoLogin(w http.ResponseWriter, r *http.Request) { if !commonapi.CheckHeaders(w, r) { return } - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONLINE { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - _, err := h.UserDB.Get(ONPREM_CONFIG) if err != nil { newUserInst := dbs.UserTestDBEntry{ diff --git a/api/user.common.api.go b/api/user.common.api.go index 0e6c7d1..f07322e 100644 --- a/api/user.common.api.go +++ b/api/user.common.api.go @@ -9,7 +9,6 @@ import ( "github.com/fido-alliance/fdo-fido-conformance-server/api/commonapi" fdoshared "github.com/fido-alliance/fdo-fido-conformance-server/core/shared" "github.com/fido-alliance/fdo-fido-conformance-server/dbs" - "github.com/fido-alliance/fdo-fido-conformance-server/services" "golang.org/x/crypto/scrypt" ) @@ -18,7 +17,6 @@ const ONPREM_CONFIG string = "tester@fido.local" type UserAPI struct { UserDB *dbs.UserTestDB SessionDB *dbs.SessionDB - Notify *services.NotifyService } func isEmailValid(e string) bool { diff --git a/api/user.other.api.go b/api/user.other.api.go index bb2cf86..95099ef 100644 --- a/api/user.other.api.go +++ b/api/user.other.api.go @@ -1,16 +1,11 @@ package api import ( - "encoding/json" - "io" "log" "net/http" - "strings" "github.com/fido-alliance/fdo-fido-conformance-server/api/commonapi" - fdoshared "github.com/fido-alliance/fdo-fido-conformance-server/core/shared" "github.com/fido-alliance/fdo-fido-conformance-server/dbs" - "github.com/fido-alliance/fdo-fido-conformance-server/services" ) func (h *UserAPI) isLoggedIn(r *http.Request) (bool, *dbs.SessionEntry, *dbs.UserTestDBEntry) { @@ -27,7 +22,7 @@ func (h *UserAPI) isLoggedIn(r *http.Request) (bool, *dbs.SessionEntry, *dbs.Use sessionInst, err := h.SessionDB.GetSessionEntry([]byte(sessionCookie.Value)) if err != nil { - log.Println("Error reading session db!" + err.Error()) + // log.Println("Error reading session db!" + err.Error()) return false, nil, nil } @@ -57,7 +52,7 @@ func (h *UserAPI) Config(w http.ResponseWriter, r *http.Request) { } commonapi.RespondSuccessStruct(w, commonapi.User_Config{ - Mode: r.Context().Value(fdoshared.CFG_ENV_MODE).(string), + Mode: "onprem", }) } @@ -82,7 +77,7 @@ func (h *UserAPI) Logout(w http.ResponseWriter, r *http.Request) { _, err = h.SessionDB.GetSessionEntry([]byte(sessionCookie.Value)) if err != nil { - log.Println("Error reading session db!" + err.Error()) + // log.Println("Error reading session db!" + err.Error()) commonapi.RespondError(w, "Unauthorized", http.StatusUnauthorized) return } @@ -120,7 +115,7 @@ func (h *UserAPI) PurgeTests(w http.ResponseWriter, r *http.Request) { sessionInst, err := h.SessionDB.GetSessionEntry([]byte(sessionCookie.Value)) if err != nil { - log.Println("Error reading session db!" + err.Error()) + // log.Println("Error reading session db!" + err.Error()) commonapi.RespondError(w, "Unauthorized", http.StatusUnauthorized) return } @@ -152,113 +147,3 @@ func (h *UserAPI) PurgeTests(w http.ResponseWriter, r *http.Request) { commonapi.RespondSuccess(w) } - -func (h *UserAPI) ReRequestEmailValidationLink(w http.ResponseWriter, r *http.Request) { - if !commonapi.CheckHeaders(w, r) { - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - isLoggedIn, session, _ := h.isLoggedIn(r) - if isLoggedIn { - commonapi.RespondError(w, "Unauthorized", http.StatusUnauthorized) - } - - submissionCountry := commonapi.ExtractCloudflareLocation(r) - - err := h.Notify.NotifyUserRegistration_EmailVerification(session.Email, submissionCountry, r.Context()) - if err != nil { - log.Println("Error sending user registration email. " + err.Error()) - commonapi.RespondError(w, "Internal server error.", http.StatusInternalServerError) - return - } - - commonapi.RespondSuccess(w) -} - -func (h *UserAPI) AdditionalInfo(w http.ResponseWriter, r *http.Request) { - if !commonapi.CheckHeaders(w, r) { - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - _, session, _ := h.isLoggedIn(r) - if session == nil || !session.OAuth2AdditionalInfo { - log.Println("Session is empty!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - bodyBytes, err := io.ReadAll(r.Body) - if err != nil { - log.Println("Failed to read body. " + err.Error()) - commonapi.RespondError(w, "Failed to read body!", http.StatusBadRequest) - return - } - - var additonalInfo commonapi.User_UserReq - err = json.Unmarshal(bodyBytes, &additonalInfo) - if err != nil { - log.Println("Failed to decode body. " + err.Error()) - commonapi.RespondError(w, "Failed to decode body!", http.StatusBadRequest) - return - } - - if len(additonalInfo.Name) == 0 { - log.Println("Missing name!") - commonapi.RespondError(w, "Missing name!", http.StatusBadRequest) - return - } - - if len(additonalInfo.Company) == 0 { - log.Println("Missing company name!") - commonapi.RespondError(w, "Missing company name!", http.StatusBadRequest) - return - } - - if len(additonalInfo.Phone) == 0 { - log.Println("Missing phone number!") - commonapi.RespondError(w, "Missing phone number!", http.StatusBadRequest) - return - } - - newUserInst := dbs.UserTestDBEntry{ - Email: strings.ToLower(session.OAuth2Email), - Name: additonalInfo.Name, - Company: additonalInfo.Company, - Status: dbs.AS_Awaiting, - } - - err = h.UserDB.Save(newUserInst) - if err != nil { - log.Println("Error saving user. " + err.Error()) - commonapi.RespondError(w, "Internal server error.", http.StatusInternalServerError) - return - } - - submissionCountry := commonapi.ExtractCloudflareLocation(r) - - err = h.Notify.NotifyUserRegistration_AccountValidation(newUserInst.Email, services.NotifyPayload{ - VendorEmail: newUserInst.Email, - VendorName: additonalInfo.Name, - VendorPhone: additonalInfo.Phone, - VendorCompany: additonalInfo.Company, - }, submissionCountry, r.Context()) - if err != nil { - log.Println("Error sending user verification email. " + err.Error()) - commonapi.RespondError(w, "Internal server error.", http.StatusInternalServerError) - return - } - - commonapi.RespondError(w, "Your account pending approval. Once it approved you will receive notification on your email address.", http.StatusInternalServerError) -} diff --git a/api/user.verify.api.go b/api/user.verify.api.go index fe14dfa..ddb2243 100644 --- a/api/user.verify.api.go +++ b/api/user.verify.api.go @@ -1,28 +1,18 @@ package api import ( - "encoding/json" - "errors" - "io" - "log" "net/http" "time" - "github.com/fido-alliance/fdo-fido-conformance-server/api/commonapi" - fdoshared "github.com/fido-alliance/fdo-fido-conformance-server/core/shared" "github.com/fido-alliance/fdo-fido-conformance-server/dbs" - "github.com/fido-alliance/fdo-fido-conformance-server/services" - "github.com/gorilla/mux" - "golang.org/x/crypto/scrypt" ) const MAX_PASSWORD_RESET time.Duration = time.Hour type UserVerify struct { - UserDB *dbs.UserTestDB - VerifyDB *dbs.VerifyDB - SessionDB *dbs.SessionDB - NotifyService *services.NotifyService + UserDB *dbs.UserTestDB + VerifyDB *dbs.VerifyDB + SessionDB *dbs.SessionDB } func (h *UserVerify) getSession(r *http.Request) (*dbs.SessionEntry, error) { @@ -60,339 +50,3 @@ func (h *UserVerify) deleteSession(r *http.Request) error { return nil } - -func (h *UserVerify) generatePasswordHash(password string) ([]byte, error) { - salt := fdoshared.NewRandomBuffer(8) - - dk, err := scrypt.Key([]byte(password), salt, 1<<15, 8, 1, 32) - if err != nil { - return []byte{}, errors.New("error hashing password") - } - - return append(salt, dk...), nil -} - -func (h *UserVerify) Reject(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - commonapi.RespondError(w, "Method not allowed!", http.StatusMethodNotAllowed) - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - vars := mux.Vars(r) - id := vars["id"] - email := vars["email"] - - entry, err := h.VerifyDB.GetEntry([]byte(id)) - if err != nil { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - if entry.Email != email { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - userInst, err := h.UserDB.Get(entry.Email) - if err != nil { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - if entry.Type != dbs.VT_AccountValidation { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - userInst.Status = dbs.AS_Blocked - - err = h.UserDB.Save(*userInst) - if err != nil { - commonapi.RespondError(w, "Internal Server Error!", http.StatusInternalServerError) - return - } - - err = h.VerifyDB.DeleteEntry([]byte(id)) - if err != nil { - log.Println("Error deleting verify entry. " + err.Error()) - commonapi.RespondError(w, "Internal Server Error!", http.StatusInternalServerError) - return - } - - err = h.NotifyService.NotifyUserRegistration_Rejected(userInst.Email, r.Context()) - if err != nil { - log.Println("Error sending reject notification email. " + err.Error()) - commonapi.RespondError(w, "Internal Server Error!", http.StatusInternalServerError) - return - } - - commonapi.RespondSuccess(w) -} - -func (h *UserVerify) Check(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - commonapi.RespondError(w, "Method not allowed!", http.StatusMethodNotAllowed) - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - vars := mux.Vars(r) - id := vars["id"] - email := vars["email"] - - entry, err := h.VerifyDB.GetEntry([]byte(id)) - if err != nil { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - if entry.Email != email { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - userInst, err := h.UserDB.Get(entry.Email) - if err != nil { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - if entry.Type == dbs.VT_Email { - userInst.EmailVerified = true - } else if entry.Type == dbs.VT_AccountValidation { - userInst.Status = dbs.AS_Validated - } else { - commonapi.RespondError(w, "Bad request!", http.StatusBadRequest) - return - } - - err = h.UserDB.Save(*userInst) - if err != nil { - commonapi.RespondError(w, "Internal Server Error!", http.StatusInternalServerError) - return - } - - err = h.VerifyDB.DeleteEntry([]byte(id)) - if err != nil { - log.Println("Error deleting verify entry. " + err.Error()) - commonapi.RespondError(w, "Internal Server Error!", http.StatusInternalServerError) - return - } - - commonapi.RespondSuccess(w) -} - -func (h *UserVerify) PasswordResetInit(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - commonapi.RespondError(w, "Method not allowed!", http.StatusMethodNotAllowed) - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - // Decode body - bodyBytes, err := io.ReadAll(r.Body) - if err != nil { - log.Println("Failed to read body. " + err.Error()) - commonapi.RespondError(w, "Bad request!", http.StatusBadRequest) - return - } - - var userResetPasswordReq commonapi.User_ResetPasswordReq - err = json.Unmarshal(bodyBytes, &userResetPasswordReq) - if err != nil { - log.Println("Failed to decode body. " + err.Error()) - commonapi.RespondSuccess(w) - return - } - - _, err = h.UserDB.Get(userResetPasswordReq.Email) - if err != nil { - log.Println("Failed to find user. " + err.Error()) - commonapi.RespondSuccess(w) - return - } - - err = h.NotifyService.NotifyUserRegistration_PasswordReset(userResetPasswordReq.Email, r.Context()) - if err != nil { - log.Println("Failed to submit notification. " + err.Error()) - commonapi.RespondError(w, "Internal Server Error!", http.StatusInternalServerError) - return - } - - commonapi.RespondSuccess(w) -} - -func (h *UserVerify) PasswordResetCheck(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" { - commonapi.RespondError(w, "Method not allowed!", http.StatusMethodNotAllowed) - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - vars := mux.Vars(r) - id := vars["id"] - email := vars["email"] - - entry, err := h.VerifyDB.GetEntry([]byte(id)) - if err != nil { - log.Println("Entry not found") - return - } - - userInst, err := h.UserDB.Get(entry.Email) - if err != nil { - log.Println("User not found") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - if userInst.Email != email { - log.Println("Emails dont match") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - if entry.Type != dbs.VT_PasswordReset { - log.Println("Bad request. Entry type is not PasswordReset") - commonapi.RespondError(w, "Bad request!", http.StatusBadRequest) - return - } - - sessionId, err := h.SessionDB.NewSessionEntry(dbs.SessionEntry{ - PasswordResetEmail: userInst.Email, - PasswordResetTimestamp: time.Now(), - }) - if err != nil { - log.Println("Error creating session. " + err.Error()) - commonapi.RespondError(w, "Internal server error. ", http.StatusBadRequest) - return - } - - http.SetCookie(w, commonapi.GenerateCookie(sessionId)) - - err = h.VerifyDB.DeleteEntry([]byte(id)) - if err != nil { - log.Println("Error deleting verify entry. " + err.Error()) - commonapi.RespondError(w, "Internal Server Error!", http.StatusInternalServerError) - return - } - - http.Redirect(w, r, commonapi.REDIRECT_RESET_PASSWORD, http.StatusTemporaryRedirect) -} - -func (h *UserVerify) PasswordResetSet(w http.ResponseWriter, r *http.Request) { - if r.Method != "POST" { - commonapi.RespondError(w, "Method not allowed!", http.StatusMethodNotAllowed) - return - } - - if r.Context().Value(fdoshared.CFG_ENV_MODE) == fdoshared.CFG_MODE_ONPREM { - log.Println("Only allowed for on-line build!") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - session, err := h.getSession(r) - if err != nil { - log.Println("Session not found") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - if session.PasswordResetEmail == "" { - log.Println("Session missing password reset email") - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - if session.PasswordResetTimestamp.Add(MAX_PASSWORD_RESET).Before(time.Now()) { - err = h.deleteSession(r) - if err != nil { - log.Println("Error generating user hash. " + err.Error()) - commonapi.RespondError(w, "Internal server error.", http.StatusInternalServerError) - return - } - } - - // Decode body - - bodyBytes, err := io.ReadAll(r.Body) - if err != nil { - log.Println("Failed to read body. " + err.Error()) - commonapi.RespondError(w, "Failed to read body!", http.StatusBadRequest) - return - } - - var userResetPassword commonapi.User_ResetPassword - err = json.Unmarshal(bodyBytes, &userResetPassword) - if err != nil { - log.Println("Failed to decode body. " + err.Error()) - commonapi.RespondError(w, "Failed to decode body!", http.StatusBadRequest) - return - } - - // Add updated password - userInst, err := h.UserDB.Get(session.PasswordResetEmail) - if err != nil { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - if len(userResetPassword.Password) < 6 || userResetPassword.Password != userResetPassword.ConfirmPassword { - commonapi.RespondError(w, "Password is too short or does not match!", http.StatusBadRequest) - return - } - - passwordHash, err := h.generatePasswordHash(userResetPassword.Password) - if err != nil { - log.Println("Error generating user hash. " + err.Error()) - commonapi.RespondError(w, "Internal server error.", http.StatusInternalServerError) - return - } - - userInst.PasswordHash = passwordHash - - err = h.UserDB.Save(*userInst) - if err != nil { - log.Println("Error saving user. " + err.Error()) - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - err = h.deleteSession(r) - if err != nil { - commonapi.RespondError(w, "Unauthorized!", http.StatusUnauthorized) - return - } - - sessionDbId, err := h.SessionDB.NewSessionEntry(dbs.SessionEntry{Email: userInst.Email, LoggedIn: true}) - if err != nil { - log.Println("Error creating session. " + err.Error()) - commonapi.RespondError(w, "Internal server error. ", http.StatusBadRequest) - return - } - - http.SetCookie(w, commonapi.GenerateCookie(sessionDbId)) - commonapi.RespondSuccess(w) -} diff --git a/core/shared/env.go b/core/shared/env.go index fde9b27..97467ea 100644 --- a/core/shared/env.go +++ b/core/shared/env.go @@ -3,29 +3,12 @@ package fdoshared type CONFIG_ENTRY string const ( - CFG_ENV_API_KEY_RESULTS CONFIG_ENTRY = "RESULTS_API_KEY" - CFG_ENV_API_BUILDS_URL CONFIG_ENTRY = "BUILDS_API_URL" CFG_ENV_FDO_SERVICE_URL CONFIG_ENTRY = "FDO_SERVICE_URL" CFG_ENV_MODE CONFIG_ENTRY = "MODE" CFG_DEV_ENV CONFIG_ENTRY = "DEV" CFG_ENV_PORT CONFIG_ENTRY = "PORT" - CFG_ENV_NOTIFY_SERVICE_HOST CONFIG_ENTRY = "NOTIFY_SERVICE_HOST" - CFG_ENV_NOTIFY_SERVICE_SECRET CONFIG_ENTRY = "NOTIFY_SERVICE_SECRET" - - CFG_ENV_GITHUB_CLIENTID CONFIG_ENTRY = "OAUTH2_GITHUB_CLIENTID" - CFG_ENV_GITHUB_CLIENTSECRET CONFIG_ENTRY = "OAUTH2_GITHUB_CLIENTSECRET" - CFG_ENV_GITHUB_REDIRECTURL CONFIG_ENTRY = "OAUTH2_GITHUB_REDIRECTURL" - - CFG_ENV_GOOGLE_CLIENTID CONFIG_ENTRY = "OAUTH2_GOOGLE_CLIENTID" - CFG_ENV_GOOGLE_CLIENTSECRET CONFIG_ENTRY = "OAUTH2_GOOGLE_CLIENTSECRET" - CFG_ENV_GOOGLE_REDIRECTURL CONFIG_ENTRY = "OAUTH2_GOOGLE_REDIRECTURL" - - CFG_ENV_MICROSOFT_CLIENTID CONFIG_ENTRY = "OAUTH2_MICROSOFT_CLIENTID" - CFG_ENV_MICROSOFT_CLIENTSECRET CONFIG_ENTRY = "OAUTH2_MICROSOFT_CLIENTSECRET" - CFG_ENV_MICROSOFT_REDIRECTURL CONFIG_ENTRY = "OAUTH2_MICROSOFT_REDIRECTURL" - // For conformance testing CFG_ENV_INTEROP_ENABLED CONFIG_ENTRY = "INTEROP_ENABLED" CFG_ENV_INTEROP_DASHBOARD_URL CONFIG_ENTRY = "INTEROP_DASHBOARD_URL" diff --git a/example.env b/example.env index 0193b64..c9bccd8 100644 --- a/example.env +++ b/example.env @@ -4,37 +4,9 @@ GODEBUG=x509sha1=1 # PORT PORT=8080 #PORT to run the server on -# API key to submit test results (FIDO Alliance Only) -RESULTS_API_KEY= # Domain to access FDO endpoints. Will be returned in RVInfo etc. FDO_SERVICE_URL= -# CFG_MODE_ONLINE(online) (FIDO Alliance hosted fido.tools) or CFG_MODE_ONPREM(onprem) for on premises hosting -MODE=online - # ENV_PROD(prod) for fully built version, ENV_DEV(dev) for development with frontend running in a dev mode DEV=prod - -# ----- FIDO Alliance Only ----- # -# API key to submit test results (FIDO Alliance Only) -BUILDS_API_URL= - -# Notify email service for fido.tools (FIDO Alliance Only) -NOTIFY_SERVICE_HOST= -NOTIFY_SERVICE_SECRET= - -# OAuth2 config for github (FIDO Alliance Only) -OAUTH2_GITHUB_CLIENTID= -OAUTH2_GITHUB_CLIENTSECRET= -OAUTH2_GITHUB_REDIRECTURL= - -# OAuth2 config for github (FIDO Alliance Only) -OAUTH2_GOOGLE_CLIENTID= -OAUTH2_GOOGLE_CLIENTSECRET= -OAUTH2_GOOGLE_REDIRECTURL= - -# Interop testing -INTEROP_DASHBOARD_URL= -INTEROP_DASHBOARD_RV_AUTHZ= -INTEROP_DASHBOARD_DO_AUTHZ= diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index 604854f..f525ad5 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -1,6 +1,5 @@ - -
-
-
-
-

Additional info required

-
- -
-
-
- -
-
- -
-
- -
-
-
    -
  • -
-
-
-

{errorMsg}

-
-
-
-
-
-
- - - diff --git a/frontend/src/routes/Builds.svelte b/frontend/src/routes/Builds.svelte deleted file mode 100644 index 61559ad..0000000 --- a/frontend/src/routes/Builds.svelte +++ /dev/null @@ -1,26 +0,0 @@ - - -
-
-

FIDO Test Tools Builds

-
- - -
-
- -
-
-
\ No newline at end of file diff --git a/frontend/src/routes/ErrorEmailValidation.svelte b/frontend/src/routes/ErrorEmailValidation.svelte deleted file mode 100644 index 9309ee3..0000000 --- a/frontend/src/routes/ErrorEmailValidation.svelte +++ /dev/null @@ -1,41 +0,0 @@ - -
-
-

Error: Your account pending approval.

-
- -
\ No newline at end of file diff --git a/frontend/src/routes/ErrorNotVerified.svelte b/frontend/src/routes/ErrorNotVerified.svelte deleted file mode 100644 index 14083b5..0000000 --- a/frontend/src/routes/ErrorNotVerified.svelte +++ /dev/null @@ -1,8 +0,0 @@ -
-
-

Error: Your account pending approval.

-
- -
\ No newline at end of file diff --git a/frontend/src/routes/Login.svelte b/frontend/src/routes/Login.svelte index f060851..c7ea569 100644 --- a/frontend/src/routes/Login.svelte +++ b/frontend/src/routes/Login.svelte @@ -1,6 +1,6 @@ - - - - -
-
-
-
-

Register

-
- -
-
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
    -
  • -
-
-
-

{errorMsg}

-
-
-
-
- -
-
- - - diff --git a/main.go b/main.go index 8d5e4b2..577c179 100644 --- a/main.go +++ b/main.go @@ -108,32 +108,14 @@ func loadEnvCtx() context.Context { ctx = context.WithValue(ctx, fdoshared.CFG_ENV_PORT, selectedPort) - ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_MODE, fdoshared.CFG_MODE_ONPREM, false) ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_DEV_ENV, fdoshared.CFG_ENV_PROD, false) - onlineMandate := ctx.Value(fdoshared.CFG_ENV_MODE).(string) == fdoshared.CFG_MODE_ONLINE - ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_API_KEY_RESULTS, "", onlineMandate) - ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_API_BUILDS_URL, "", onlineMandate) - ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_FDO_SERVICE_URL, defaultUrl, onlineMandate) - - ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_NOTIFY_SERVICE_HOST, "", onlineMandate) - ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_NOTIFY_SERVICE_SECRET, "", onlineMandate) - - ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_GITHUB_CLIENTID, "", false) - ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_GITHUB_CLIENTSECRET, "", false) - ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_GITHUB_REDIRECTURL, "", false) - - ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_GOOGLE_CLIENTID, "", false) - ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_GOOGLE_CLIENTSECRET, "", false) - ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_GOOGLE_REDIRECTURL, "", false) - - // TODO: Add Microsoft OAuth2 - // For interop testing ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_INTEROP_DASHBOARD_URL, "", false) iopEnabled := ctx.Value(fdoshared.CFG_ENV_INTEROP_DASHBOARD_URL).(string) != "" ctx = context.WithValue(ctx, fdoshared.CFG_ENV_INTEROP_ENABLED, iopEnabled) + ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_FDO_SERVICE_URL, defaultUrl, iopEnabled) ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_INTEROP_DASHBOARD_RV_AUTHZ, "", iopEnabled) ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_INTEROP_DASHBOARD_DO_AUTHZ, "", iopEnabled) ctx = TryEnvAndSaveToCtx(ctx, fdoshared.CFG_ENV_INTEROP_DO_TOKEN_MAPPING, "", iopEnabled) diff --git a/services/github.oauth2.go b/services/github.oauth2.go deleted file mode 100644 index 2ee924c..0000000 --- a/services/github.oauth2.go +++ /dev/null @@ -1,161 +0,0 @@ -package services - -import ( - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "time" - - fdoshared "github.com/fido-alliance/fdo-fido-conformance-server/core/shared" - "golang.org/x/oauth2" -) - -var Github_EndpointConfig = oauth2.Endpoint{ - AuthURL: "https://github.com/login/oauth/authorize", - TokenURL: "https://github.com/login/oauth/access_token", -} - -var Github_OAuth2Scopes = []string{ - "read:user", - "user:email", - "read:org", -} - -const Github_UserUrl = "https://api.github.com/user" -const Github_OrgsUrl = "https://api.github.com/user/orgs" -const Github_FIDOAllianceID = "fido-alliance" - -type GithubUser struct { - Username string `json:"login"` - Email string `json:"email"` - Name string `json:"name"` - Company string `json:"company"` - Location string `json:"location"` - Bio string `json:"bio"` -} - -type GithubOrg struct { - OrgName string `json:"login"` -} - -type GithubOAuth2Provider struct { - Config OAuth2ProviderConfig - Endpoint oauth2.Endpoint - LogTag string -} - -func NewGithubOAuth2Connector(config OAuth2ProviderConfig) GithubOAuth2Provider { - return GithubOAuth2Provider{ - Config: config, - Endpoint: Github_EndpointConfig, - LogTag: "GithubOAuth2", - } -} - -func (h GithubOAuth2Provider) getGithubUser(authToken string) (string, error) { - httpClient := &http.Client{ - Timeout: 30 * time.Second, - } - req, err := http.NewRequest("GET", Github_UserUrl, nil) - if err != nil { - return "", fmt.Errorf("%s: Error generating new request instance. %s", h.LogTag, err.Error()) - } - - req.Header.Set("Authorization", "Bearer "+authToken) - req.Header.Set("Accept", "application/vnd.github+json") - resp, err := httpClient.Do(req) - if err != nil { - return "", fmt.Errorf("%s: Error sending request. %s", h.LogTag, err.Error()) - } - - defer resp.Body.Close() - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return "", fmt.Errorf("%s: Error reading response body. %s", h.LogTag, err.Error()) - } - - var userInst GithubUser - err = json.Unmarshal(bodyBytes, &userInst) - if err != nil { - return "", fmt.Errorf("%s: Error decoding userinfo. %s", h.LogTag, err.Error()) - } - - return userInst.Email, nil -} - -func (h GithubOAuth2Provider) getGithubUser_Orgs(authToken string) ([]string, error) { - var result = []string{} - - httpClient := &http.Client{ - Timeout: 30 * time.Second, - } - req, err := http.NewRequest("GET", Github_OrgsUrl, nil) - if err != nil { - return result, fmt.Errorf("%s: Error generating new request instance. %s", h.LogTag, err.Error()) - } - - req.Header.Set("Authorization", "Bearer "+authToken) - req.Header.Set("Accept", "application/vnd.github+json") - resp, err := httpClient.Do(req) - if err != nil { - return result, fmt.Errorf("%s: Error sending request. %s", h.LogTag, err.Error()) - } - - defer resp.Body.Close() - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return result, fmt.Errorf("%s: Error reading response body. %s", h.LogTag, err.Error()) - } - - var userOrgs []GithubOrg - err = json.Unmarshal(bodyBytes, &userOrgs) - if err != nil { - return result, fmt.Errorf("%s: Error decoding userinfo. %s", h.LogTag, err.Error()) - } - - for _, org := range userOrgs { - result = append(result, org.OrgName) - } - - return result, nil -} - -func (h GithubOAuth2Provider) getGithubOauthConfig() *oauth2.Config { - return &oauth2.Config{ - // RedirectURL: h.Config.RedirectUrl, - ClientID: h.Config.ClientId, - ClientSecret: h.Config.ClientSecret, - RedirectURL: h.Config.RedirectUrl, - Scopes: Github_OAuth2Scopes, - Endpoint: h.Endpoint, - } -} - -func (h GithubOAuth2Provider) GetRedirectUrl() (string, string, string) { - - state := fdoshared.NewRandomString(16) - nonce := fdoshared.NewRandomString(16) - - return h.getGithubOauthConfig().AuthCodeURL(state), state, nonce -} - -func (h GithubOAuth2Provider) GetUserInfo(resultCode string) (string, bool, error) { - oauth2Token, err := h.getGithubOauthConfig().Exchange(context.Background(), resultCode) - if err != nil { - return "", false, err - } - - email, err := h.getGithubUser(oauth2Token.AccessToken) - if err != nil { - return "", false, err - } - - orgs, err := h.getGithubUser_Orgs(oauth2Token.AccessToken) - if err != nil { - return email, false, err - } - - return email, fdoshared.StringsContain(orgs, Github_FIDOAllianceID), nil -} diff --git a/services/google.oauth2.go b/services/google.oauth2.go deleted file mode 100644 index 9684092..0000000 --- a/services/google.oauth2.go +++ /dev/null @@ -1,113 +0,0 @@ -package services - -import ( - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "time" - - fdoshared "github.com/fido-alliance/fdo-fido-conformance-server/core/shared" - "golang.org/x/oauth2" -) - -var Google_EndpointConfig = oauth2.Endpoint{ - AuthURL: "https://accounts.google.com/o/oauth2/auth", - TokenURL: "https://oauth2.googleapis.com/token", -} - -var Google_OAuth2Scopes = []string{ - "https://www.googleapis.com/auth/userinfo.email", - "https://www.googleapis.com/auth/userinfo.profile", -} - -const Google_UserUrl = "https://openidconnect.googleapis.com/v1/userinfo" - -// https://developers.google.com/identity/openid-connect/openid-connect -type GoogleUser struct { - Email string `json:"email"` - Name string `json:"name"` -} - -type GoogleOrg struct { - OrgName string `json:"login"` -} - -type GoogleOAuth2Provider struct { - Config OAuth2ProviderConfig - Endpoint oauth2.Endpoint - LogTag string -} - -func NewGoogleOAuth2Connector(config OAuth2ProviderConfig) GoogleOAuth2Provider { - return GoogleOAuth2Provider{ - Config: config, - Endpoint: Google_EndpointConfig, - LogTag: "GoogleOAuth2", - } -} - -func (h GoogleOAuth2Provider) getUserInfo(authToken string) (string, error) { - httpClient := &http.Client{ - Timeout: 30 * time.Second, - } - req, err := http.NewRequest("GET", Google_UserUrl, nil) - if err != nil { - return "", fmt.Errorf("%s: Error generating new request instance. %s", h.LogTag, err.Error()) - } - - req.Header.Set("Authorization", "Bearer "+authToken) - req.Header.Set("Accept", "application/vnd.github+json") - resp, err := httpClient.Do(req) - if err != nil { - return "", fmt.Errorf("%s: Error sending request. %s", h.LogTag, err.Error()) - } - - defer resp.Body.Close() - bodyBytes, err := io.ReadAll(resp.Body) - if err != nil { - return "", fmt.Errorf("%s: Error reading response body. %s", h.LogTag, err.Error()) - } - - var userInst GoogleUser - err = json.Unmarshal(bodyBytes, &userInst) - if err != nil { - return "", fmt.Errorf("%s: Error decoding userinfo. %s", h.LogTag, err.Error()) - } - - return userInst.Email, nil -} - -func (h GoogleOAuth2Provider) getGithubOauthConfig() *oauth2.Config { - return &oauth2.Config{ - // RedirectURL: h.Config.RedirectUrl, - ClientID: h.Config.ClientId, - ClientSecret: h.Config.ClientSecret, - RedirectURL: h.Config.RedirectUrl, - Scopes: Google_OAuth2Scopes, - Endpoint: h.Endpoint, - } -} - -func (h GoogleOAuth2Provider) GetRedirectUrl() (string, string, string) { - - state := fdoshared.NewRandomString(16) - nonce := fdoshared.NewRandomString(16) - - return h.getGithubOauthConfig().AuthCodeURL(state), state, nonce -} - -func (h GoogleOAuth2Provider) GetUserInfo(resultCode string) (string, bool, error) { - oauth2Token, err := h.getGithubOauthConfig().Exchange(context.Background(), resultCode) - if err != nil { - return "", false, err - } - - email, err := h.getUserInfo(oauth2Token.AccessToken) - if err != nil { - return "", false, err - } - - return email, false, nil -} diff --git a/services/notify.go b/services/notify.go deleted file mode 100644 index 74c7950..0000000 --- a/services/notify.go +++ /dev/null @@ -1,153 +0,0 @@ -package services - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "log" - "net/http" - "time" - - fdoshared "github.com/fido-alliance/fdo-fido-conformance-server/core/shared" - "github.com/fido-alliance/fdo-fido-conformance-server/dbs" -) - -const FIDO_NOTIFY_EMAIL = "certification@fidoalliance.org" - -type NotifyPayload struct { - VendorEmail string `json:"vendor_email"` - VendorName string `json:"vendor_name"` - VendorPhone string `json:"vendor_phone"` - VendorCompany string `json:"vendor_company"` - - ApproveLink string `json:"approve_link,omitempty"` - RejectLink string `json:"reject_link,omitempty"` - PasswordResetLink string `json:"reset_link,omitempty"` - EmailVerifyLink string `json:"verify_link,omitempty"` - - Type dbs.VerifyType `json:"type"` - SubmissionCountry string `json:"submission_country"` - RandomKss string `json:"randomkss,omitempty"` -} - -type NotifyService struct { - ResultsApiKey string - ResultsHost string - VerifyDB *dbs.VerifyDB - LogTag string -} - -func NewNotifyService(resultsHost string, resultsApiKey string, verifyDb *dbs.VerifyDB) NotifyService { - return NotifyService{ - ResultsApiKey: resultsApiKey, - ResultsHost: resultsHost, - VerifyDB: verifyDb, - LogTag: "NotifyService", - } -} - -func (h *NotifyService) getResultsUrl(vttype dbs.VerifyType) string { - return fmt.Sprintf("%s/api/fdotools/notify/%s", h.ResultsHost, vttype) -} - -func (h *NotifyService) createNotifyUserSession(email string, vttype dbs.VerifyType) ([]byte, error) { - var entry = dbs.VerifyEntry{ - Email: email, - Type: vttype, - } - - return h.VerifyDB.SaveEntry(entry) -} - -func (h *NotifyService) sendEmailNotification(requestPayload NotifyPayload) error { - reqBytes, _ := json.Marshal(requestPayload) - - httpClient := &http.Client{ - Timeout: 30 * time.Second, - } - req, err := http.NewRequest("POST", h.getResultsUrl(requestPayload.Type), bytes.NewBuffer(reqBytes)) - if err != nil { - return fmt.Errorf("%s: Error generating new request instance. %s", h.LogTag, err.Error()) - } - - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Authorization", "Bearer "+h.ResultsApiKey) - resp, err := httpClient.Do(req) - if err != nil { - return fmt.Errorf("%s: Error sending request. %s", h.LogTag, err.Error()) - } - - if resp.StatusCode != http.StatusOK { - log.Println(resp.Status) - } - return nil -} - -// Send user email validation link -func (h *NotifyService) NotifyUserRegistration_EmailVerification(email string, submissionCountry string, ctx context.Context) error { - entryId, err := h.createNotifyUserSession(email, dbs.VT_Email) - if err != nil { - log.Println("Error notifying user... " + err.Error()) - return nil - } - - emailVerificationLink := fmt.Sprintf("%s/api/user/email/check/%s/%s", ctx.Value(fdoshared.CFG_ENV_FDO_SERVICE_URL).(string), string(entryId), email) - - return h.sendEmailNotification(NotifyPayload{ - VendorEmail: email, - ApproveLink: emailVerificationLink, - Type: dbs.VT_Email, - }) -} - -// Send FIDO email about new user -func (h *NotifyService) NotifyUserRegistration_AccountValidation(email string, userInfo NotifyPayload, submissionCountry string, ctx context.Context) error { - entryId, err := h.createNotifyUserSession(email, dbs.VT_AccountValidation) - if err != nil { - return nil - } - - userApprovalLink := fmt.Sprintf("%s/api/user/approve/%s/%s", ctx.Value(fdoshared.CFG_ENV_FDO_SERVICE_URL).(string), string(entryId), email) - userRejectLink := fmt.Sprintf("%s/api/user/approve/%s/%s", ctx.Value(fdoshared.CFG_ENV_FDO_SERVICE_URL).(string), string(entryId), email) - - reqPayload := userInfo - reqPayload.ApproveLink = userApprovalLink - reqPayload.RejectLink = userRejectLink - reqPayload.VendorEmail = email - reqPayload.SubmissionCountry = submissionCountry - reqPayload.Type = dbs.VT_AccountValidation - - return h.sendEmailNotification(reqPayload) -} - -// Send FIDO email about new user -func (h *NotifyService) NotifyUserRegistration_Approved(email string, ctx context.Context) error { - return h.sendEmailNotification(NotifyPayload{ - VendorEmail: email, - Type: dbs.VT_RegistrationApproved, - }) -} - -// Send FIDO email about new user -func (h *NotifyService) NotifyUserRegistration_Rejected(email string, ctx context.Context) error { - return h.sendEmailNotification(NotifyPayload{ - VendorEmail: email, - Type: dbs.VT_RegistrationRejected, - }) -} - -func (h *NotifyService) NotifyUserRegistration_PasswordReset(email string, ctx context.Context) error { - entryId, err := h.createNotifyUserSession(email, dbs.VT_PasswordReset) - if err != nil { - return err - } - - resetLink := fmt.Sprintf("%s/api/user/password/reset/%s/%s", ctx.Value(fdoshared.CFG_ENV_FDO_SERVICE_URL).(string), string(entryId), email) - - return h.sendEmailNotification(NotifyPayload{ - VendorEmail: email, - PasswordResetLink: resetLink, - Type: dbs.VT_PasswordReset, - }) -} diff --git a/services/oauth2.go b/services/oauth2.go deleted file mode 100644 index 76ce14a..0000000 --- a/services/oauth2.go +++ /dev/null @@ -1,48 +0,0 @@ -package services - -import ( - "fmt" -) - -type OAuth2ProviderConfig struct { - // RedirectUrl string - ClientSecret string - ClientId string - RedirectUrl string -} - -type OAuth2ProviderID string - -const ( - OATH2_GITHUB = "github" - OATH2_GOOGLE = "google" -) - -type OAuth2Provider interface { - // Redirect URL, State, Nonce - GetRedirectUrl() (string, string, string) - GetUserInfo(resultCode string) (string, bool, error) -} - -type OAuth2Service struct { - Providers map[OAuth2ProviderID]OAuth2Provider -} - -func (h *OAuth2Service) ProviderExists(providerId OAuth2ProviderID) bool { - for k, _ := range h.Providers { - if k == providerId { - return true - } - } - - return false -} - -func (h *OAuth2Service) GetProvider(providerId OAuth2ProviderID) (OAuth2Provider, error) { - val, ok := h.Providers[providerId] - if ok { - return val, nil - } else { - return nil, fmt.Errorf("%s provider does not exist", providerId) - } -}