github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/daemon/api_buy_unsupp.go (about)

     1  /*
     2   * Copyright (C) 2014-2020 Canonical Ltd
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License version 3 as
     6   * published by the Free Software Foundation.
     7   *
     8   * This program is distributed in the hope that it will be useful,
     9   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11   * GNU General Public License for more details.
    12   *
    13   * You should have received a copy of the GNU General Public License
    14   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    15   *
    16   */
    17  
    18  package daemon
    19  
    20  import (
    21  	"encoding/json"
    22  	"net/http"
    23  
    24  	"github.com/snapcore/snapd/client"
    25  	"github.com/snapcore/snapd/overlord/auth"
    26  	"github.com/snapcore/snapd/store"
    27  )
    28  
    29  // TODO: this is unsupported and when supported will have a new implementation,
    30  // make these simply return errors and remove all the related code from
    31  // the store package except maybe errors
    32  
    33  var (
    34  	buyCmd = &Command{
    35  		Path:        "/v2/buy",
    36  		POST:        postBuy,
    37  		WriteAccess: authenticatedAccess{},
    38  	}
    39  
    40  	readyToBuyCmd = &Command{
    41  		Path:       "/v2/buy/ready",
    42  		GET:        readyToBuy,
    43  		ReadAccess: authenticatedAccess{},
    44  	}
    45  )
    46  
    47  func postBuy(c *Command, r *http.Request, user *auth.UserState) Response {
    48  	var opts client.BuyOptions
    49  
    50  	decoder := json.NewDecoder(r.Body)
    51  	err := decoder.Decode(&opts)
    52  	if err != nil {
    53  		return BadRequest("cannot decode buy options from request body: %v", err)
    54  	}
    55  
    56  	s := storeFrom(c.d)
    57  
    58  	buyResult, err := s.Buy(&opts, user)
    59  
    60  	if resp := convertBuyError(err); resp != nil {
    61  		return resp
    62  	}
    63  
    64  	return SyncResponse(buyResult)
    65  }
    66  
    67  func readyToBuy(c *Command, r *http.Request, user *auth.UserState) Response {
    68  	s := storeFrom(c.d)
    69  
    70  	if resp := convertBuyError(s.ReadyToBuy(user)); resp != nil {
    71  		return resp
    72  	}
    73  
    74  	return SyncResponse(true)
    75  }
    76  
    77  func convertBuyError(err error) Response {
    78  	var kind client.ErrorKind
    79  	switch err {
    80  	case nil:
    81  		return nil
    82  	case store.ErrInvalidCredentials:
    83  		return Unauthorized(err.Error())
    84  	case store.ErrUnauthenticated:
    85  		kind = client.ErrorKindLoginRequired
    86  	case store.ErrTOSNotAccepted:
    87  		kind = client.ErrorKindTermsNotAccepted
    88  	case store.ErrNoPaymentMethods:
    89  		kind = client.ErrorKindNoPaymentMethods
    90  	case store.ErrPaymentDeclined:
    91  		kind = client.ErrorKindPaymentDeclined
    92  	default:
    93  		return InternalError("%v", err)
    94  	}
    95  	return &apiError{
    96  		Status:  400,
    97  		Message: err.Error(),
    98  		Kind:    kind,
    99  	}
   100  }