150 lines
4.0 KiB
Go
150 lines
4.0 KiB
Go
|
// Copyright (C) 2019 Storj Labs, Inc.
|
||
|
// See LICENSE for copying information.
|
||
|
|
||
|
package consoleapi
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"net/http"
|
||
|
|
||
|
"github.com/zeebo/errs"
|
||
|
"go.uber.org/zap"
|
||
|
|
||
|
"storj.io/storj/private/post"
|
||
|
"storj.io/storj/satellite/console"
|
||
|
"storj.io/storj/satellite/console/consoleweb/consoleql"
|
||
|
"storj.io/storj/satellite/mailservice"
|
||
|
"storj.io/storj/satellite/referrals"
|
||
|
)
|
||
|
|
||
|
// ErrReferralsAPI - console referrals api error type.
|
||
|
var ErrReferralsAPI = errs.Class("console referrals api error")
|
||
|
|
||
|
// Referrals is an api controller that exposes all referrals functionality.
|
||
|
type Referrals struct {
|
||
|
log *zap.Logger
|
||
|
service *referrals.Service
|
||
|
consoleService *console.Service
|
||
|
mailService *mailservice.Service
|
||
|
ExternalAddress string
|
||
|
}
|
||
|
|
||
|
// NewReferrals is a constructor for api referrals controller.
|
||
|
func NewReferrals(log *zap.Logger, service *referrals.Service, consoleService *console.Service, mailService *mailservice.Service, externalAddress string) *Referrals {
|
||
|
return &Referrals{
|
||
|
log: log,
|
||
|
service: service,
|
||
|
consoleService: consoleService,
|
||
|
mailService: mailService,
|
||
|
ExternalAddress: externalAddress,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// GetTokens returns referral tokens based on user ID.
|
||
|
func (controller *Referrals) GetTokens(w http.ResponseWriter, r *http.Request) {
|
||
|
ctx := r.Context()
|
||
|
var err error
|
||
|
defer mon.Task()(&ctx)(&err)
|
||
|
|
||
|
auth, err := console.GetAuth(ctx)
|
||
|
if err != nil {
|
||
|
controller.serveJSONError(w, err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
tokens, err := controller.service.GetTokens(ctx, &auth.User.ID)
|
||
|
if err != nil {
|
||
|
controller.serveJSONError(w, err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
w.Header().Set("Content-Type", "application/json")
|
||
|
err = json.NewEncoder(w).Encode(tokens)
|
||
|
if err != nil {
|
||
|
controller.log.Error("token handler could not encode token response", zap.Error(ErrReferralsAPI.Wrap(err)))
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Register creates new user, sends activation e-mail.
|
||
|
func (controller *Referrals) Register(w http.ResponseWriter, r *http.Request) {
|
||
|
ctx := r.Context()
|
||
|
var err error
|
||
|
defer mon.Task()(&ctx)(&err)
|
||
|
|
||
|
var registerData struct {
|
||
|
FullName string `json:"fullName"`
|
||
|
ShortName string `json:"shortName"`
|
||
|
Email string `json:"email"`
|
||
|
Password string `json:"password"`
|
||
|
ReferralToken string `json:"referralToken"`
|
||
|
}
|
||
|
|
||
|
err = json.NewDecoder(r.Body).Decode(®isterData)
|
||
|
if err != nil {
|
||
|
controller.serveJSONError(w, err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
user, err := controller.service.CreateUser(ctx, registerData)
|
||
|
if err != nil {
|
||
|
controller.serveJSONError(w, err)
|
||
|
return
|
||
|
}
|
||
|
token, err := controller.consoleService.GenerateActivationToken(ctx, user.ID, user.Email)
|
||
|
if err != nil {
|
||
|
controller.serveJSONError(w, err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
link := controller.ExternalAddress + "activation/?token=" + token
|
||
|
userName := user.ShortName
|
||
|
if user.ShortName == "" {
|
||
|
userName = user.FullName
|
||
|
}
|
||
|
|
||
|
controller.mailService.SendRenderedAsync(
|
||
|
ctx,
|
||
|
[]post.Address{{Address: user.Email, Name: userName}},
|
||
|
&consoleql.AccountActivationEmail{
|
||
|
ActivationLink: link,
|
||
|
Origin: controller.ExternalAddress,
|
||
|
},
|
||
|
)
|
||
|
|
||
|
w.Header().Set("Content-Type", "application/json")
|
||
|
err = json.NewEncoder(w).Encode(user.ID)
|
||
|
if err != nil {
|
||
|
controller.log.Error("registration handler could not encode userID", zap.Error(ErrReferralsAPI.Wrap(err)))
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// serveJSONError writes JSON error to response output stream.
|
||
|
func (controller *Referrals) serveJSONError(w http.ResponseWriter, err error) {
|
||
|
w.WriteHeader(controller.getStatusCode(err))
|
||
|
|
||
|
var response struct {
|
||
|
Error string `json:"error"`
|
||
|
}
|
||
|
|
||
|
response.Error = err.Error()
|
||
|
|
||
|
err = json.NewEncoder(w).Encode(response)
|
||
|
if err != nil {
|
||
|
controller.log.Error("failed to write json error response", zap.Error(ErrReferralsAPI.Wrap(err)))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// getStatusCode returns http.StatusCode depends on console error class.
|
||
|
func (controller *Referrals) getStatusCode(err error) int {
|
||
|
switch {
|
||
|
case console.ErrValidation.Has(err):
|
||
|
return http.StatusBadRequest
|
||
|
case console.ErrUnauthorized.Has(err):
|
||
|
return http.StatusUnauthorized
|
||
|
default:
|
||
|
return http.StatusInternalServerError
|
||
|
}
|
||
|
}
|