func (a *Adaptor) InsertDowngradeToFreeReason(userID int, reason string) *adaptor.AdaptorError { reasonID, adaptorErr := a.getReasonID(reason) if adaptorErr != nil { return adaptorErr } params := url.Values{ "user_id": []string{strconv.Itoa(userID)}, "moving": []string{"0"}, "event_type": []string{"Downgrade to Free"}, "reason": []string{strconv.Itoa(reasonID)}, } columns := NewCrudColumns() columns.AddColumns(params) var ok string err := a.apidClient.DoFunction("add", url.Values{ "tableName": []string{"user_churn"}, "values": []string{columns.String()}, }, &ok) if err != nil { ln.Info("unable to call apid add on user_churn", ln.Map{"err": err.Error(), "user_id": userID}) return adaptor.NewError("internal data storage error") } if ok != "success" { ln.Info("unexpected response from apid add on user_churn", ln.Map{"err": fmt.Sprintf("got '%s', want 'success'", ok), "user_id": userID}) } return nil }
func (a *Adaptor) InsertDeactivationReason(userID int, reason string, moving bool, inHouse bool, otherProvider string, comment string) *adaptor.AdaptorError { reasonID, adaptorErr := a.getReasonID(reason) if adaptorErr != nil { return adaptorErr } if inHouse { otherProvider = "in house" } competitorID, adaptorErr := a.getValidCompetitorID(otherProvider) if adaptorErr != nil { ln.Err("unable to get competitor id - "+otherProvider, ln.Map{"err": adaptorErr}) return adaptorErr } if competitorID == 0 { competitorID, adaptorErr = a.insertNewCompetitor(userID, otherProvider) if adaptorErr != nil { ln.Err("unable to set new competitor id - "+otherProvider, ln.Map{"err": adaptorErr}) return adaptorErr } } params := url.Values{ "user_id": []string{strconv.Itoa(userID)}, "moving": []string{strconv.Itoa(boolToInt(moving))}, "event_type": []string{"Cancellation"}, "new_provider": []string{strconv.Itoa(competitorID)}, "notes": []string{comment}, "reason": []string{strconv.Itoa(reasonID)}, } columns := NewCrudColumns() columns.AddColumns(params) var ok string err := a.apidClient.DoFunction("add", url.Values{ "tableName": []string{"user_churn"}, "values": []string{columns.String()}, }, &ok) if err != nil { ln.Info("unable to call apid add on user_churn", ln.Map{"err": err.Error(), "user_id": userID}) return adaptor.NewError("internal data storage error") } if ok != "success" { ln.Info("unexpected response from apid add on user_churn", ln.Map{"err": fmt.Sprintf("got '%s', want 'success'", ok), "user_id": userID}) } return nil }
func (a *Adaptor) getValidCompetitorID(otherProvider string) (int, *adaptor.AdaptorError) { params := url.Values{ "tableName": []string{"competitors"}, "where": []string{fmt.Sprintf(`{"competitor":"%s"}`, otherProvider)}, } competition := []competitor{} err := a.apidClient.DoFunction("get", params, &competition) if err != nil { ln.Err("unable to get competitors value", ln.Map{"err": err.Error()}) return 0, adaptor.NewError("internal data storage error") } if len(competition) == 0 { return 0, nil } if len(competition) >= 1 { // only return a valid competitor id if there is no user id for _, c := range competition { if c.UserID == 0 { return c.UserID, nil } } } // if we got here, it means all entries in the competitor table were tied to a user id // meaning the BI team has not vetted the entry ln.Info("no valid competitor found", nil) return 0, adaptor.NewError("internal data storage error") }
// Get the first available IP and assign it to the user. Set that IP as the user send IP func (a *Adaptor) AssignFirstIP(userID int) *adaptor.AdaptorError { locations, err := a.getFirstIPLocation() if len(locations) == 0 { ln.Info("no locations found for first_ip policy", ln.Map{"locations": locations}) return adaptor.NewError("no locations found for first_ip policy") } if err != nil { ln.Err("error when getting server locations", ln.Map{"error": err.Error()}) return adaptor.NewError("error when getting server locations") } r := rand.New(rand.NewSource(time.Now().Unix())) params := url.Values{ "userid": []string{strconv.Itoa(userID)}, "limit": []string{strconv.Itoa(1)}, "server_location": []string{strconv.Itoa(locations[r.Intn(len(locations))])}, } // Grab the first available IP and immediately assign it to the user var IP []string apidErr := a.apidClient.DoFunction("assignBestAvailableOp", params, &IP) if apidErr != nil { ln.Err("error assigning best ips", ln.Map{"error": apidErr.Error(), "params": params}) return adaptor.NewError("error assigning best available ips") } if len(IP) == 0 { ln.Info("no available ips", ln.Map{"locations": locations}) return adaptor.NewError("no available ips") } // assign ip to user send ip _, err = a.AddUserSendIP(userID, IP[0]) if err != nil { ln.Err("could not add ip to user send ips table", ln.Map{"err": err.Error(), "user_id": userID}) return adaptor.NewError("could not add ip to user send ips table") } return nil }
func (a *Adaptor) GetChurnReasons() []userChurnReason { reasons := make([]userChurnReason, 0) err := a.apidClient.DoFunction("get", url.Values{ "tableName": []string{"user_churn_reason"}, }, &reasons) if err != nil { ln.Info("unable to get list of user_churn reasons", ln.Map{"err": err.Error()}) } return reasons }
// GetFirstIP finds an ip from the location based on the first_ip policy func (a *Adaptor) GetFirstIP() (string, *adaptor.AdaptorError) { locations, err := a.getFirstIPLocation() if len(locations) == 0 { ln.Info("no locations found for first_ip policy", ln.Map{"locations": locations}) return "", adaptor.NewError("no locations found for first_ip policy") } if err != nil { ln.Err("error when getting server locations", ln.Map{"error": err.Error()}) return "", adaptor.NewError("error when getting server locations") } r := rand.New(rand.NewSource(time.Now().Unix())) params := url.Values{ "limit": []string{strconv.Itoa(1)}, "server_location": []string{strconv.Itoa(locations[r.Intn(len(locations))])}, } var IP []string getIPErr := a.apidClient.DoFunction("getBestAvailableIp", params, &IP) if getIPErr != nil { ln.Err("error getting best ips", ln.Map{"error": getIPErr.Error(), "params": params}) return "", adaptor.NewError("error getting best available ips") } if len(IP) == 0 { ln.Info("no avaiable ips", ln.Map{"locations": locations}) return "", adaptor.NewError("no available ips") } return IP[0], nil }
func (g *Adaptor) ValidatePassword(username string, password string) (*PasswordValidationResponse, error) { authenticationURL := fmt.Sprintf("http://%s:%d/validate/password", g.GandalfHost, g.GandalfPort) authenticationReq := PasswordValidationRequest{ Username: username, Password: password, } data, err := json.Marshal(authenticationReq) if err != nil { ln.Err("could not marshal authentication request parameters", ln.Map{"error": err.Error(), "username": username}) return nil, errors.New(ErrorAuthentication) } req, err := http.NewRequest("POST", authenticationURL, bytes.NewBuffer(data)) client := &http.Client{} resp, err := client.Do(req) if err != nil { ln.Err("error posting to gandalf authentication endpoint", ln.Map{"error": err.Error(), "username": username}) return nil, errors.New(ErrorAuthentication) } defer resp.Body.Close() var authenticationResp PasswordValidationResponse err = json.NewDecoder(resp.Body).Decode(&authenticationResp) if err != nil { ln.Err("error decoding response from gandalf", ln.Map{"error": err.Error(), "username": username}) return nil, errors.New(ErrorAuthentication) } if authenticationResp.Error != "" { if authenticationResp.Error == "Unauthorized" { ln.Info("authentication failed because of bad credentials", ln.Map{"username": username}) return nil, errors.New(ErrorBadCredentials) } ln.Err("authentication failed", ln.Map{"username": username, "error": authenticationResp.Error}) return nil, errors.New(ErrorAuthentication) } return &authenticationResp, nil }