Permalink
Browse files

Merge pull request #88 from netlify/admin-access-to-coupons-and-settings

Add /coupons and /settings endpoints for admins
  • Loading branch information...
biilmann committed Oct 12, 2017
2 parents b7ec9f1 + d0a182e commit 57c5ef93b7a2579bc794b068dcb25e2115742188
Showing with 83 additions and 13 deletions.
  1. +3 −0 api/api.go
  2. +19 −0 api/coupons.go
  3. +1 −1 api/order.go
  4. +25 −0 api/settings.go
  5. +4 −0 conf/configuration.go
  6. +31 −12 coupons/coupons.go
View
@@ -113,9 +113,12 @@ func NewAPIWithVersion(ctx context.Context, globalConfig *conf.GlobalConfigurati
})
r.Route("/coupons", func(r *router) {
r.With(adminRequired).Get("/", api.CouponList)
r.Get("/{coupon_code}", api.CouponView)
})
r.With(adminRequired).Get("/settings", api.ViewSettings)
r.With(authRequired).Post("/claim", api.ClaimOrders)
})
View
@@ -43,3 +43,22 @@ func (a *API) CouponView(w http.ResponseWriter, r *http.Request) error {
return sendJSON(w, http.StatusOK, coupon)
}
// CouponList returns all the coupons for the site. Requires admin permissions
func (a *API) CouponList(w http.ResponseWriter, r *http.Request) error {
ctx := r.Context()
log := getLogEntry(r)
couponCache := gcontext.GetCoupons(ctx)
if couponCache == nil {
return sendJSON(w, http.StatusOK, []string{})
}
coupons, err := couponCache.List()
if err != nil {
log.WithError(err).Errorf("Error loading coupons: %v", err)
return internalServerError("Error fetching coupons: %v", err)
}
return sendJSON(w, http.StatusOK, coupons)
}
View
@@ -678,7 +678,7 @@ func (a *API) loadSettings(ctx context.Context) (*calculator.Settings, error) {
config := gcontext.GetConfig(ctx)
settings := &calculator.Settings{}
resp, err := a.httpClient.Get(config.SiteURL + "/gocommerce/settings.json")
resp, err := a.httpClient.Get(config.SettingsURL())
if err != nil {
return nil, fmt.Errorf("Error loading site settings: %v", err)
}
View
@@ -0,0 +1,25 @@
package api
import (
"fmt"
"io"
"net/http"
gcontext "github.com/netlify/gocommerce/context"
)
func (a *API) ViewSettings(w http.ResponseWriter, r *http.Request) error {
ctx := r.Context()
config := gcontext.GetConfig(ctx)
resp, err := a.httpClient.Get(config.SettingsURL())
if err != nil {
return fmt.Errorf("Error loading site settings: %v", err)
}
defer resp.Body.Close()
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
_, err = io.Copy(w, resp.Body)
return err
}
View
@@ -97,6 +97,10 @@ type Configuration struct {
} `json:"webhooks"`
}
func (c *Configuration) SettingsURL() string {
return c.SiteURL + "/gocommerce/settings.json"
}
func loadEnvironment(filename string) error {
var err error
if filename != "" {
View
@@ -16,6 +16,7 @@ const cacheTime = 1 * time.Minute
// Cache is an interface for how to lookup a coupon based upon the code.
type Cache interface {
Lookup(string) (*models.Coupon, error)
List() (map[string]*models.Coupon, error)
}
// CouponNotFound is an error when a coupon could not be found.
@@ -54,36 +55,29 @@ func NewCouponCacheFromURL(config *conf.Configuration) Cache {
}
}
func (c *couponCacheFromURL) Lookup(code string) (*models.Coupon, error) {
if c.coupons != nil && time.Now().Before(c.lastFetch.Add(cacheTime)) {
coupon, ok := c.coupons[code]
if ok {
return coupon, nil
}
return nil, &CouponNotFound{}
}
func (c *couponCacheFromURL) load() error {
req, err := http.NewRequest("GET", c.url, nil)
if err != nil {
return nil, err
return err
}
if c.user != "" {
req.SetBasicAuth(c.user, c.password)
}
resp, err := c.client.Do(req)
if err != nil {
return nil, err
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Coupon URL returned %v", resp.StatusCode)
return fmt.Errorf("Coupon URL returned %v", resp.StatusCode)
}
couponsResponse := &couponsResponse{}
decoder := json.NewDecoder(resp.Body)
if err := decoder.Decode(couponsResponse); err != nil {
return nil, err
return err
}
for key, coupon := range couponsResponse.Coupons {
coupon.Code = key
@@ -93,9 +87,34 @@ func (c *couponCacheFromURL) Lookup(code string) (*models.Coupon, error) {
c.coupons = couponsResponse.Coupons
c.mutex.Unlock()
return nil
}
func (c *couponCacheFromURL) Lookup(code string) (*models.Coupon, error) {
if c.coupons != nil && time.Now().Before(c.lastFetch.Add(cacheTime)) {
coupon, ok := c.coupons[code]
if ok {
return coupon, nil
}
return nil, &CouponNotFound{}
}
if err := c.load(); err != nil {
return nil, err
}
coupon, ok := c.coupons[code]
if ok {
return coupon, nil
}
return nil, &CouponNotFound{}
}
func (c *couponCacheFromURL) List() (map[string]*models.Coupon, error) {
if c.coupons == nil {
if err := c.load(); err != nil {
return nil, err
}
}
return c.coupons, nil
}

0 comments on commit 57c5ef9

Please sign in to comment.