Esempio n. 1
0
// FundraisingPageURLCheck checks the availability of a JustGiving fundraising page
func (svc *Service) FundraisingPageURLCheck(pageShortName string) (avail bool, suggestions []string, err error) {

	// if page is not available we return some suggestions
	var suggs []string

	method := "HEAD"

	path := bytes.NewBuffer([]byte(svc.BasePath))
	path.WriteString("/")
	path.WriteString(svc.APIKey)
	path.WriteString("/v1/fundraising/pages/")
	path.WriteString(pageShortName)

	req, err := api.BuildRequest(UserAgent, ContentType, method, path.String(), nil)
	if err != nil {
		return false, suggs, err
	}

	res, _, err := api.Do(svc.client, svc.origin, "FundraisingPageURLCheck", req, "", svc.HTTPLogger)
	if err != nil {
		return false, suggs, err
	}

	// 404 is success, which is a bit dangerous, so we first make sure we have the correct JustGiving response header
	if res.Header.Get("X-Justgiving-Operation") != "FundraisingApi:FundraisingPageUrlCheck" {
		return false, suggs, fmt.Errorf("invalid response, expected X-Justgiving-Operation response header to be FundraisingApi:FundraisingPageUrlCheck but recieved %s", res.Header.Get("X-Justgiving-Operation"))
	}
	if res.StatusCode == 404 {
		return true, suggs, nil
	}
	if res.StatusCode != 200 {
		return false, suggs, fmt.Errorf("invalid response %s", res.Status)
	}
	// 200 - Page short name already registered
	// Return a list of suggestions
	path = bytes.NewBuffer([]byte(svc.BasePath))
	path.WriteString("/")
	path.WriteString(svc.APIKey)
	path.WriteString("/v1/fundraising/pages/suggest?preferredName=")
	path.WriteString(url.QueryEscape(pageShortName))
	req, err = api.BuildRequest(UserAgent, ContentType, "GET", path.String(), nil)
	res, resBody, err := api.Do(svc.client, svc.origin, "FundraisingPageURLCheck", req, "", svc.HTTPLogger)
	if err != nil {
		return false, suggs, err
	}
	var result = struct {
		Names []string
	}{}
	if err := json.Unmarshal([]byte(resBody), &result); err != nil {
		return false, suggs, fmt.Errorf("invalid response %v", err)
	}
	return false, result.Names, nil

}
Esempio n. 2
0
// Event returns the specified JustGiving event
func (svc *Service) Event(eventID uint) (*models.Event, error) {
	var result models.Event

	method := "GET"
	path := bytes.NewBuffer([]byte(svc.BasePath))
	path.WriteString("/")
	path.WriteString(svc.APIKey)
	path.WriteString("/v1/event/")
	path.WriteString(strconv.FormatUint(uint64(eventID), 10))

	req, err := api.BuildRequest(UserAgent, ContentType, method, path.String(), nil)
	if err != nil {
		return nil, err
	}

	res, resBody, err := api.Do(svc.client, svc.origin, "Event", req, "", svc.HTTPLogger)
	if err != nil {
		return nil, err
	}

	if res.StatusCode == 404 {
		return nil, nil
	}

	if res.StatusCode != 200 {
		return nil, fmt.Errorf("invalid response %s", res.Status)
	}

	if err = json.Unmarshal([]byte(resBody), &result); err != nil {
		return nil, fmt.Errorf("invalid response %v", err)
	}

	return &result, nil
}
Esempio n. 3
0
// FundraisingPagesForCharityAndUser returns the charity's fundraising pages registered with the specified JustGiving user account
func (svc *Service) FundraisingPagesForCharityAndUser(charityID uint, account mail.Address) ([]*FundraisingPageRef, error) {

	var results []*FundraisingPageRef

	// mail.Address stores email in the format <*****@*****.**>, this simply removes the `<` `>`
	em := account.String()
	if em != "" {
		em = em[1 : len(em)-1]
	}

	method := "GET"
	path := bytes.NewBuffer([]byte(svc.BasePath))
	path.WriteString("/")
	path.WriteString(svc.APIKey)
	path.WriteString("/v1/account/")
	path.WriteString(em)
	path.WriteString("/pages/?charityId=")
	path.WriteString(strconv.FormatUint(uint64(charityID), 10))

	req, err := api.BuildRequest(UserAgent, ContentType, method, path.String(), nil)
	if err != nil {
		return nil, err
	}
	res, resBody, err := api.Do(svc.client, svc.origin, "FundraisingPagesForCharityAndUser", req, "", svc.HTTPLogger)
	if err != nil {
		return nil, err
	}

	if res.StatusCode == 404 {
		return results, nil
	}

	if res.StatusCode != 200 {
		return nil, fmt.Errorf("invalid response %s", res.Status)
	}

	var result = []struct {
		EventID       uint   `json:"eventId"`
		PageID        uint   `json:"pageId"`
		PageShortName string `json:"pageShortName"`
	}{}

	if err := json.Unmarshal([]byte(resBody), &result); err != nil {
		return nil, fmt.Errorf("invalid response %v", err)
	}

	for _, p := range result {
		if p.PageID > 0 {
			results = append(results, &FundraisingPageRef{
				charityID: charityID,
				eventID:   p.EventID,
				id:        p.PageID,
				shortName: p.PageShortName,
			})

		}
	}

	return results, nil
}
Esempio n. 4
0
// RequestPasswordReminder requests JustGiving to send a password reset email
func (svc *Service) RequestPasswordReminder(account mail.Address) error {

	method := "GET"

	// mail.Address stores email in the format <*****@*****.**>, we don't want the `<` `>`
	em := account.String()
	em = em[1 : len(em)-1]

	path := bytes.NewBuffer([]byte(svc.BasePath))
	path.WriteString("/")
	path.WriteString(svc.APIKey)
	path.WriteString("/v1/account/")
	path.WriteString(em)
	path.WriteString("/requestpasswordreminder")

	req, err := api.BuildRequest(UserAgent, ContentType, method, path.String(), nil)
	if err != nil {
		return err
	}

	res, _, err := api.Do(svc.client, svc.origin, "RequestPasswordReminder", req, "", svc.HTTPLogger)
	if err != nil {
		return err
	}

	if res.StatusCode != 200 {
		return fmt.Errorf("invalid response %s", res.Status)
	}
	return nil

}
Esempio n. 5
0
func paginatedFundraisingPagesForEvent(svc *Service, eventID uint, pagination uint) (results []*FundraisingPageRef, totalPagination uint, totalFundraisingPages uint, err error) {

	method := "GET"
	path := bytes.NewBuffer([]byte(svc.BasePath))
	path.WriteString("/")
	path.WriteString(svc.APIKey)
	path.WriteString("/v1/event/")
	path.WriteString(strconv.FormatUint(uint64(eventID), 10))
	path.WriteString("/pages/?pageSize=100")

	// set pagination
	pg := "1"
	if pagination > 0 {
		pg = strconv.FormatUint(uint64(pagination), 10)
	}

	req, err := api.BuildRequest(UserAgent, ContentType, method, path.String()+"&page="+pg, nil)
	if err != nil {
		return nil, 0, 0, err
	}
	res, resBody, err := api.Do(svc.client, svc.origin, "FundraisingPagesForEvent", req, "", svc.HTTPLogger)
	if err != nil {
		return nil, 0, 0, err
	}

	if res.StatusCode != 200 {
		return nil, 0, 0, fmt.Errorf("invalid response %s", res.Status)
	}
	type page struct {
		CharityID     uint   `json:"charityId"`
		PageID        uint   `json:"pageId"`
		PageShortName string `json:"pageShortName"`
	}
	var result = struct {
		TotalPagination       uint   `json:"totalPages"`
		TotalFundraisingPages uint   `json:"totalFundraisingPages"`
		FundraisingPages      []page `json:"fundraisingPages"`
	}{}

	if err := json.Unmarshal([]byte(resBody), &result); err != nil {
		return nil, 0, 0, fmt.Errorf("invalid response %v", err)
	}

	for _, p := range result.FundraisingPages {
		if p.PageID > 0 {
			results = append(results, &FundraisingPageRef{
				charityID: p.CharityID,
				eventID:   eventID,
				id:        p.PageID,
				shortName: p.PageShortName,
			})

		}
	}

	return results, result.TotalPagination, result.TotalFundraisingPages, nil
}
Esempio n. 6
0
// Validate a set of supplied user credentials against the JustGiving database
func (svc *Service) Validate(account mail.Address, password string) (valid bool, err error) {

	method := "POST"

	path := bytes.NewBuffer([]byte(svc.BasePath))
	path.WriteString("/")
	path.WriteString(svc.APIKey)
	path.WriteString("/v1/account/validate")

	// mail.Address stores email in the format <*****@*****.**>, we don't want the `<` `>`
	em := account.String()
	em = em[1 : len(em)-1]

	data := struct {
		Email    string
		Password string
	}{em, password}

	sBody, body, err := api.BuildBody("Validate", data, ContentType)
	if err != nil {
		return false, err
	}

	req, err := api.BuildRequest(UserAgent, ContentType, method, path.String(), body)
	if err != nil {
		return false, err
	}

	res, resBody, err := api.Do(svc.client, svc.origin, "Validate", req, sBody, svc.HTTPLogger)
	if err != nil {
		return false, err
	}

	if res.StatusCode != 200 {
		return false, fmt.Errorf("invalid response %s", res.Status)
	}
	var result = struct {
		IsValid bool `json:"isValid"`
	}{}
	if err := json.Unmarshal([]byte(resBody), &result); err != nil {
		return false, fmt.Errorf("invalid response %v", err)
	}
	return result.IsValid, nil

}
Esempio n. 7
0
// IsValidCountry checks the Country used by models.Account is in the published JustGiving countries list
func (svc *Service) IsValidCountry(name string) (bool, error) {

	method := "GET"

	path := bytes.NewBuffer([]byte(svc.BasePath))
	path.WriteString("/")
	path.WriteString(svc.APIKey)
	path.WriteString("/v1/countries")

	req, err := api.BuildRequest(UserAgent, ContentType, method, path.String(), nil)
	if err != nil {
		return false, err
	}

	res, resBody, err := api.Do(svc.client, svc.origin, "IsValidCountry", req, "", svc.HTTPLogger)
	if err != nil {
		return false, err
	}

	if res.StatusCode != 200 {
		return false, fmt.Errorf("invalid response %s", res.Status)
	}

	var result = []struct {
		Name string `json:"name"`
	}{}

	if err := json.Unmarshal([]byte(resBody), &result); err != nil {
		return false, fmt.Errorf("invalid response %v", err)
	}

	for _, c := range result {
		if name == c.Name {
			return true, nil
		}
	}
	return false, nil

}
Esempio n. 8
0
// AccountRegistration registers a new user account with JustGiving
func (svc *Service) AccountRegistration(account models.Account) (err error) {

	method := "PUT"

	path := bytes.NewBuffer([]byte(svc.BasePath))
	path.WriteString("/")
	path.WriteString(svc.APIKey)
	path.WriteString("/v1/account/")

	sBody, body, err := api.BuildBody("AccountRegistration", account, ContentType)
	if err != nil {
		return err
	}
	req, err := api.BuildRequest(UserAgent, ContentType, method, path.String(), body)
	if err != nil {
		return err
	}

	res, _, err := api.Do(svc.client, svc.origin, "AccountRegistration", req, sBody, svc.HTTPLogger)
	if err != nil {
		return err
	}

	if res.StatusCode != 200 {
		// run request validation on failure
		info := "no errors found"
		valid, err := account.HasValidCountry(svc)
		if err != nil {
			info = fmt.Sprintf("errors running validation %v", err)
		} else {
			if !valid {
				info = "invalid Country"
			}
		}
		return fmt.Errorf("invalid response %s, result of running validation on request payload was: %s", res.Status, info)
	}
	return nil

}
Esempio n. 9
0
// AccountAvailabilityCheck checks the availability of a JustGiving account by email address
func (svc *Service) AccountAvailabilityCheck(account mail.Address) (avail bool, err error) {

	method := "HEAD"

	// mail.Address stores email in the format <*****@*****.**>, we don't want the `<` `>`
	em := account.String()
	em = em[1 : len(em)-1]

	path := bytes.NewBuffer([]byte(svc.BasePath))
	path.WriteString("/")
	path.WriteString(svc.APIKey)
	path.WriteString("/v1/account/")
	path.WriteString(em)

	req, err := api.BuildRequest(UserAgent, ContentType, method, path.String(), nil)
	if err != nil {
		return false, err
	}

	res, _, err := api.Do(svc.client, svc.origin, "AccountAvailabilityCheck", req, "", svc.HTTPLogger)
	if err != nil {
		return false, err
	}

	// 404 is success (available), which is a bit dangerous, so we first make sure we have the correct JustGiving response header
	if res.Header.Get("X-Justgiving-Operation") != "AccountApi:AccountAvailabilityCheck" {
		return false, fmt.Errorf("invalid response, expected X-Justgiving-Operation response header to be AccountApi:AccountAvailabilityCheck but recieved %s", res.Header.Get("X-Justgiving-Operation"))
	}
	if res.StatusCode == 404 {
		return true, nil
	}
	if res.StatusCode != 200 {
		return false, fmt.Errorf("invalid response %s", res.Status)
	}
	// 200 - account exists
	return false, nil

}
Esempio n. 10
0
// FundraisingPageResults returns the current fundraising results for the specified JustGiving page
func (svc *Service) FundraisingPageResults(page *FundraisingPageRef) (models.FundraisingResults, error) {

	var result models.FundraisingResults
	method := "GET"
	path := bytes.NewBuffer([]byte(svc.BasePath))
	path.WriteString("/")
	path.WriteString(svc.APIKey)
	path.WriteString("/v1/fundraising/pages/")
	path.WriteString(page.shortName)

	req, err := api.BuildRequest(UserAgent, ContentType, method, path.String(), nil)
	if err != nil {
		return result, err
	}

	res, resBody, err := api.Do(svc.client, svc.origin, "FundraisingPageResults", req, "", svc.HTTPLogger)
	if err != nil {
		return result, err
	}

	if res.StatusCode == 410 {
		result.PageCancelled = true
		return result, nil
	}

	if res.StatusCode != 200 {
		return result, fmt.Errorf("invalid response %s", res.Status)
	}

	result = models.FundraisingResults{}
	if err = json.Unmarshal([]byte(resBody), &result); err != nil {
		return result, fmt.Errorf("invalid response %v", err)
	}

	return result, nil

}
Esempio n. 11
0
// RegisterFundraisingPageForEvent registers a fundraising page on the JustGiving website
func (svc *Service) RegisterFundraisingPageForEvent(account mail.Address, password string, page models.FundraisingPageForEvent) (pageURL *url.URL, signOnURL *url.URL, err error) {

	method := "PUT"

	path := bytes.NewBuffer([]byte(svc.BasePath))
	path.WriteString("/")
	path.WriteString(svc.APIKey)
	path.WriteString("/v1/fundraising/pages")

	sBody, body, err := api.BuildBody("RegisterFundraisingPageForEvent", page, ContentType)
	if err != nil {
		return nil, nil, err
	}
	req, err := api.BuildRequest(UserAgent, ContentType, method, path.String(), body)
	if err != nil {
		return nil, nil, err
	}

	// This request requires authentication
	// mail.Address stores email in the format <*****@*****.**>, we don't want the `<` `>`
	em := account.String()
	em = em[1 : len(em)-1]
	req.SetBasicAuth(em, password)

	res, resBody, err := api.Do(svc.client, svc.origin, "RegisterFundraisingPageForEvent", req, sBody, svc.HTTPLogger)
	if err != nil {
		return nil, nil, err
	}

	//201 Created
	if res.StatusCode != 201 {
		// run request validation on failure
		var info string
		var valid bool
		valid, err = page.HasValidCurrencyCode(svc)
		if err != nil {
			info = fmt.Sprintf("errors running CurrencyCode validation %v; ", err)
		} else {
			if !valid {
				info = "invalid CurrencyCode; "
			}
		}
		valid = page.HasValidTargetAmount()
		if !valid {
			info += "invalid TargetAmount"
		}
		if info == "" {
			info = "no errors found"
		}
		return nil, nil, fmt.Errorf("invalid response %s, result of running validation on request payload was: %s", res.Status, info)
	}

	// Read page URL and signon URL from response
	var result = struct {
		SignOnURL string `json:"signOnUrl"`
		Page      struct {
			URL string `json:"uri"`
		} `json:"next"`
	}{}
	if err = json.Unmarshal([]byte(resBody), &result); err != nil {
		return nil, nil, fmt.Errorf("invalid response %v", err)
	}
	pageURL, err = url.Parse(result.Page.URL)
	if err != nil {
		return nil, nil, fmt.Errorf("invalid response %v", err)
	}
	signOnURL, err = url.Parse(result.SignOnURL)
	if err != nil {
		return nil, nil, fmt.Errorf("invalid response %v", err)
	}

	return pageURL, signOnURL, nil

}