storj/satellite/console/consoleweb/consoleql/mutation.go

526 lines
15 KiB
Go
Raw Normal View History

2019-01-24 16:26:36 +00:00
// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package consoleql
import (
"github.com/graphql-go/graphql"
"github.com/skyrings/skyring-common/tools/uuid"
"go.uber.org/zap"
"storj.io/storj/internal/post"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/mailservice"
)
const (
// Mutation is graphql request that modifies data
Mutation = "mutation"
2019-01-24 16:26:36 +00:00
// CreateUserMutation is a user creation mutation name
CreateUserMutation = "createUser"
// UpdateAccountMutation is a mutation name for account updating
UpdateAccountMutation = "updateAccount"
// DeleteAccountMutation is a mutation name for account deletion
DeleteAccountMutation = "deleteAccount"
// ChangePasswordMutation is a mutation name for password changing
ChangePasswordMutation = "changePassword"
// CreateProjectMutation is a mutation name for project creation
CreateProjectMutation = "createProject"
// DeleteProjectMutation is a mutation name for project deletion
DeleteProjectMutation = "deleteProject"
// UpdateProjectDescriptionMutation is a mutation name for project updating
UpdateProjectDescriptionMutation = "updateProjectDescription"
// AddProjectMembersMutation is a mutation name for adding new project members
AddProjectMembersMutation = "addProjectMembers"
// DeleteProjectMembersMutation is a mutation name for deleting project members
DeleteProjectMembersMutation = "deleteProjectMembers"
// CreateAPIKeyMutation is a mutation name for api key creation
CreateAPIKeyMutation = "createAPIKey"
// DeleteAPIKeysMutation is a mutation name for api key deleting
DeleteAPIKeysMutation = "deleteAPIKeys"
2019-01-24 16:26:36 +00:00
2019-07-10 21:29:26 +01:00
// AddPaymentMethodMutation is mutation name for adding new payment method
AddPaymentMethodMutation = "addPaymentMethod"
// DeletePaymentMethodMutation is mutation name for deleting payment method
DeletePaymentMethodMutation = "deletePaymentMethod"
// SetDefaultPaymentMethodMutation is mutation name setting payment method as default payment method
SetDefaultPaymentMethodMutation = "setDefaultPaymentMethod"
2019-01-24 16:26:36 +00:00
// InputArg is argument name for all input types
InputArg = "input"
// FieldProjectID is field name for projectID
FieldProjectID = "projectID"
// FieldNewPassword is a field name for new password
FieldNewPassword = "newPassword"
// Secret is a field name for registration token for user creation during Vanguard release
Secret = "secret"
// ReferrerUserID is a field name for passing referrer's user id
2019-07-26 18:58:17 +01:00
ReferrerUserID = "referrerUserId"
)
// rootMutation creates mutation for graphql populated by AccountsClient
2019-04-04 15:56:20 +01:00
func rootMutation(log *zap.Logger, service *console.Service, mailService *mailservice.Service, types *TypeCreator) *graphql.Object {
return graphql.NewObject(graphql.ObjectConfig{
Name: Mutation,
Fields: graphql.Fields{
2019-01-24 16:26:36 +00:00
CreateUserMutation: &graphql.Field{
2019-04-04 15:56:20 +01:00
Type: types.user,
Args: graphql.FieldConfigArgument{
2019-01-24 16:26:36 +00:00
InputArg: &graphql.ArgumentConfig{
2019-04-04 15:56:20 +01:00
Type: graphql.NewNonNull(types.userInput),
},
Secret: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
ReferrerUserID: &graphql.ArgumentConfig{
Type: graphql.String,
},
},
2018-11-21 15:51:43 +00:00
// creates user and company from input params and returns userID if succeed
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
2019-01-24 16:26:36 +00:00
input, _ := p.Args[InputArg].(map[string]interface{})
secretInput, _ := p.Args[Secret].(string)
refUserID, _ := p.Args[ReferrerUserID].(string)
createUser := fromMapCreateUser(input)
secret, err := console.RegistrationSecretFromBase64(secretInput)
if err != nil {
satellite/satellitedb: add updateEarnedCredits method for user_credits table (#2609) * parent 13dd501042d0fa6eb0142b6f737704985c17f5bc author Yingrong Zhao <yingrong.zhao@gmail.com> 1563560530 -0400 committer Yingrong Zhao <yingrong.zhao@gmail.com> 1563581673 -0400 parent 13dd501042d0fa6eb0142b6f737704985c17f5bc author Yingrong Zhao <yingrong.zhao@gmail.com> 1563560530 -0400 committer Yingrong Zhao <yingrong.zhao@gmail.com> 1563581428 -0400 satellite/console: add referral link logic (#2576) * setup referral route * referredBy * add user id * modify user query * separate optional field from userInfo * get current reward on init of satellite gui * remove unsed code * fix format * only apply 0 credit on registration * only pass required information for rewards * fix time parsing * fix test and linter * rename method * add todo * remove user referral logic * add null check and fix format * get current offer * remove partnerID on CreateUser struct * fix storj-sim user creation * only redeem credit when there's an offer * fix default offer configuration * fix migration * Add helper function for get correct credit duration * add comment * only store userid into user_credit table * add check for partner id to set correct offer type * change free credit to use invitee credits * remove unecessary code * add credit update in activateAccount * remove unused code * fix format * close reader and fix front-end build * move create credit logic into CreateUser method * when there's no offer set, user flow shouldn't be interrupted by referral program * add appropriate error messages * remove unused code * add comment * add error class for no current offer error * add error class for credits update * add comment for migration * only log secret when it's in debug level * fix typo * add testdata
2019-07-30 14:21:00 +01:00
log.Error("register: failed to create account",
zap.Error(err))
satellite/satellitedb: add updateEarnedCredits method for user_credits table (#2609) * parent 13dd501042d0fa6eb0142b6f737704985c17f5bc author Yingrong Zhao <yingrong.zhao@gmail.com> 1563560530 -0400 committer Yingrong Zhao <yingrong.zhao@gmail.com> 1563581673 -0400 parent 13dd501042d0fa6eb0142b6f737704985c17f5bc author Yingrong Zhao <yingrong.zhao@gmail.com> 1563560530 -0400 committer Yingrong Zhao <yingrong.zhao@gmail.com> 1563581428 -0400 satellite/console: add referral link logic (#2576) * setup referral route * referredBy * add user id * modify user query * separate optional field from userInfo * get current reward on init of satellite gui * remove unsed code * fix format * only apply 0 credit on registration * only pass required information for rewards * fix time parsing * fix test and linter * rename method * add todo * remove user referral logic * add null check and fix format * get current offer * remove partnerID on CreateUser struct * fix storj-sim user creation * only redeem credit when there's an offer * fix default offer configuration * fix migration * Add helper function for get correct credit duration * add comment * only store userid into user_credit table * add check for partner id to set correct offer type * change free credit to use invitee credits * remove unecessary code * add credit update in activateAccount * remove unused code * fix format * close reader and fix front-end build * move create credit logic into CreateUser method * when there's no offer set, user flow shouldn't be interrupted by referral program * add appropriate error messages * remove unused code * add comment * add error class for no current offer error * add error class for credits update * add comment for migration * only log secret when it's in debug level * fix typo * add testdata
2019-07-30 14:21:00 +01:00
log.Debug("register: ", zap.String("rawSecret", secretInput))
return nil, err
}
user, err := service.CreateUser(p.Context, createUser, secret, refUserID)
if err != nil {
log.Error("register: failed to create account",
zap.Error(err))
satellite/satellitedb: add updateEarnedCredits method for user_credits table (#2609) * parent 13dd501042d0fa6eb0142b6f737704985c17f5bc author Yingrong Zhao <yingrong.zhao@gmail.com> 1563560530 -0400 committer Yingrong Zhao <yingrong.zhao@gmail.com> 1563581673 -0400 parent 13dd501042d0fa6eb0142b6f737704985c17f5bc author Yingrong Zhao <yingrong.zhao@gmail.com> 1563560530 -0400 committer Yingrong Zhao <yingrong.zhao@gmail.com> 1563581428 -0400 satellite/console: add referral link logic (#2576) * setup referral route * referredBy * add user id * modify user query * separate optional field from userInfo * get current reward on init of satellite gui * remove unsed code * fix format * only apply 0 credit on registration * only pass required information for rewards * fix time parsing * fix test and linter * rename method * add todo * remove user referral logic * add null check and fix format * get current offer * remove partnerID on CreateUser struct * fix storj-sim user creation * only redeem credit when there's an offer * fix default offer configuration * fix migration * Add helper function for get correct credit duration * add comment * only store userid into user_credit table * add check for partner id to set correct offer type * change free credit to use invitee credits * remove unecessary code * add credit update in activateAccount * remove unused code * fix format * close reader and fix front-end build * move create credit logic into CreateUser method * when there's no offer set, user flow shouldn't be interrupted by referral program * add appropriate error messages * remove unused code * add comment * add error class for no current offer error * add error class for credits update * add comment for migration * only log secret when it's in debug level * fix typo * add testdata
2019-07-30 14:21:00 +01:00
log.Debug("register: ", zap.String("rawSecret", secretInput))
return nil, err
}
token, err := service.GenerateActivationToken(p.Context, user.ID, user.Email)
if err != nil {
log.Error("register: failed to generate activation token",
zap.Stringer("id", user.ID),
zap.String("email", user.Email),
zap.Error(err))
return user, nil
}
rootObject := p.Info.RootValue.(map[string]interface{})
origin := rootObject["origin"].(string)
link := origin + rootObject[ActivationPath].(string) + token
userName := user.ShortName
if user.ShortName == "" {
userName = user.FullName
}
mailService.SendRenderedAsync(
p.Context,
[]post.Address{{Address: user.Email, Name: userName}},
&AccountActivationEmail{
Origin: origin,
ActivationLink: link,
},
)
return user, nil
},
},
2019-01-24 16:26:36 +00:00
UpdateAccountMutation: &graphql.Field{
2019-04-04 15:56:20 +01:00
Type: types.user,
2018-11-28 10:31:15 +00:00
Args: graphql.FieldConfigArgument{
2019-01-24 16:26:36 +00:00
InputArg: &graphql.ArgumentConfig{
2019-04-04 15:56:20 +01:00
Type: graphql.NewNonNull(types.userInput),
2018-11-28 10:31:15 +00:00
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
2019-01-24 16:26:36 +00:00
input, _ := p.Args[InputArg].(map[string]interface{})
auth, err := console.GetAuth(p.Context)
2018-11-28 10:31:15 +00:00
if err != nil {
return nil, err
}
info := fillUserInfo(&auth.User, input)
2018-11-28 10:31:15 +00:00
err = service.UpdateAccount(p.Context, info)
2018-11-28 12:30:38 +00:00
if err != nil {
return nil, err
2018-11-28 10:31:15 +00:00
}
return auth.User, nil
2018-11-28 10:31:15 +00:00
},
},
2019-01-24 16:26:36 +00:00
ChangePasswordMutation: &graphql.Field{
2019-04-04 15:56:20 +01:00
Type: types.user,
Args: graphql.FieldConfigArgument{
2019-01-24 16:26:36 +00:00
FieldPassword: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
2019-01-24 16:26:36 +00:00
FieldNewPassword: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
2019-01-24 16:26:36 +00:00
pass, _ := p.Args[FieldPassword].(string)
newPass, _ := p.Args[FieldNewPassword].(string)
auth, err := console.GetAuth(p.Context)
if err != nil {
return nil, err
}
err = service.ChangePassword(p.Context, pass, newPass)
if err != nil {
return nil, err
}
return auth.User, nil
},
},
2019-01-24 16:26:36 +00:00
DeleteAccountMutation: &graphql.Field{
2019-04-04 15:56:20 +01:00
Type: types.user,
Args: graphql.FieldConfigArgument{
2019-01-24 16:26:36 +00:00
FieldPassword: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
2019-01-24 16:26:36 +00:00
password, _ := p.Args[FieldPassword].(string)
auth, err := console.GetAuth(p.Context)
if err != nil {
return nil, err
}
err = service.DeleteAccount(p.Context, password)
if err != nil {
return nil, err
}
return auth.User, nil
},
},
// creates project from input params
2019-01-24 16:26:36 +00:00
CreateProjectMutation: &graphql.Field{
2019-04-04 15:56:20 +01:00
Type: types.project,
Args: graphql.FieldConfigArgument{
2019-01-24 16:26:36 +00:00
InputArg: &graphql.ArgumentConfig{
2019-04-04 15:56:20 +01:00
Type: graphql.NewNonNull(types.projectInput),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
2019-01-24 16:26:36 +00:00
var projectInput = fromMapProjectInfo(p.Args[InputArg].(map[string]interface{}))
return service.CreateProject(p.Context, projectInput)
},
},
// deletes project by id, taken from input params
2019-01-24 16:26:36 +00:00
DeleteProjectMutation: &graphql.Field{
2019-04-04 15:56:20 +01:00
Type: types.project,
Args: graphql.FieldConfigArgument{
2019-01-24 16:26:36 +00:00
FieldID: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
2019-01-24 16:26:36 +00:00
inputID := p.Args[FieldID].(string)
projectID, err := uuid.Parse(inputID)
if err != nil {
return nil, err
}
2019-01-08 14:54:35 +00:00
project, err := service.GetProject(p.Context, *projectID)
if err != nil {
return nil, err
}
if err = service.DeleteProject(p.Context, project.ID); err != nil {
return nil, err
}
return project, nil
},
},
// updates project description
2019-01-24 16:26:36 +00:00
UpdateProjectDescriptionMutation: &graphql.Field{
2019-04-04 15:56:20 +01:00
Type: types.project,
Args: graphql.FieldConfigArgument{
2019-01-24 16:26:36 +00:00
FieldID: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
2019-01-24 16:26:36 +00:00
FieldDescription: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
2019-01-24 16:26:36 +00:00
description := p.Args[FieldDescription].(string)
2019-01-24 16:26:36 +00:00
inputID := p.Args[FieldID].(string)
projectID, err := uuid.Parse(inputID)
if err != nil {
return nil, err
}
return service.UpdateProject(p.Context, *projectID, description)
},
},
// add user as member of given project
2019-01-24 16:26:36 +00:00
AddProjectMembersMutation: &graphql.Field{
2019-04-04 15:56:20 +01:00
Type: types.project,
Args: graphql.FieldConfigArgument{
2019-01-24 16:26:36 +00:00
FieldProjectID: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
2019-01-24 16:26:36 +00:00
FieldEmail: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.NewList(graphql.String)),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
2019-01-24 16:26:36 +00:00
pID, _ := p.Args[FieldProjectID].(string)
emails, _ := p.Args[FieldEmail].([]interface{})
projectID, err := uuid.Parse(pID)
if err != nil {
return nil, err
}
var userEmails []string
for _, email := range emails {
userEmails = append(userEmails, email.(string))
}
project, err := service.GetProject(p.Context, *projectID)
if err != nil {
return nil, err
}
users, err := service.AddProjectMembers(p.Context, *projectID, userEmails)
if err != nil {
return nil, err
}
rootObject := p.Info.RootValue.(map[string]interface{})
origin := rootObject["origin"].(string)
signIn := origin + rootObject[SignInPath].(string)
for _, user := range users {
userName := user.ShortName
if user.ShortName == "" {
userName = user.FullName
}
mailService.SendRenderedAsync(
p.Context,
[]post.Address{{Address: user.Email, Name: userName}},
&ProjectInvitationEmail{
Origin: origin,
UserName: userName,
ProjectName: project.Name,
SignInLink: signIn,
},
)
}
return project, nil
},
},
// delete user membership for given project
2019-01-24 16:26:36 +00:00
DeleteProjectMembersMutation: &graphql.Field{
2019-04-04 15:56:20 +01:00
Type: types.project,
Args: graphql.FieldConfigArgument{
2019-01-24 16:26:36 +00:00
FieldProjectID: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
2019-01-24 16:26:36 +00:00
FieldEmail: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.NewList(graphql.String)),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
2019-01-24 16:26:36 +00:00
pID, _ := p.Args[FieldProjectID].(string)
emails, _ := p.Args[FieldEmail].([]interface{})
projectID, err := uuid.Parse(pID)
if err != nil {
return nil, err
}
var userEmails []string
for _, email := range emails {
userEmails = append(userEmails, email.(string))
}
err = service.DeleteProjectMembers(p.Context, *projectID, userEmails)
if err != nil {
return nil, err
}
return service.GetProject(p.Context, *projectID)
},
},
2018-12-27 15:30:15 +00:00
// creates new api key
2019-01-24 16:26:36 +00:00
CreateAPIKeyMutation: &graphql.Field{
2019-04-04 15:56:20 +01:00
Type: types.createAPIKey,
2018-12-27 15:30:15 +00:00
Args: graphql.FieldConfigArgument{
2019-01-24 16:26:36 +00:00
FieldProjectID: &graphql.ArgumentConfig{
2018-12-27 15:30:15 +00:00
Type: graphql.NewNonNull(graphql.String),
},
2019-01-24 16:26:36 +00:00
FieldName: &graphql.ArgumentConfig{
2018-12-27 15:30:15 +00:00
Type: graphql.NewNonNull(graphql.String),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
2019-01-24 16:26:36 +00:00
projectID, _ := p.Args[FieldProjectID].(string)
name, _ := p.Args[FieldName].(string)
2018-12-27 15:30:15 +00:00
pID, err := uuid.Parse(projectID)
if err != nil {
return nil, err
}
info, key, err := service.CreateAPIKey(p.Context, *pID, name)
if err != nil {
return nil, err
}
return createAPIKey{
Key: key.Serialize(),
2018-12-27 15:30:15 +00:00
KeyInfo: info,
}, nil
},
},
// deletes api key
DeleteAPIKeysMutation: &graphql.Field{
2019-04-04 15:56:20 +01:00
Type: graphql.NewList(types.apiKeyInfo),
2018-12-27 15:30:15 +00:00
Args: graphql.FieldConfigArgument{
2019-01-24 16:26:36 +00:00
FieldID: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.NewList(graphql.String)),
2018-12-27 15:30:15 +00:00
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
paramKeysID, _ := p.Args[FieldID].([]interface{})
var keyIds []uuid.UUID
var keys []console.APIKeyInfo
for _, id := range paramKeysID {
keyID, err := uuid.Parse(id.(string))
if err != nil {
return nil, err
}
key, err := service.GetAPIKeyInfo(p.Context, *keyID)
if err != nil {
return nil, err
}
keyIds = append(keyIds, *keyID)
keys = append(keys, *key)
2018-12-27 15:30:15 +00:00
}
err := service.DeleteAPIKeys(p.Context, keyIds)
2018-12-27 15:30:15 +00:00
if err != nil {
return nil, err
}
return keys, nil
2018-12-27 15:30:15 +00:00
},
},
2019-07-10 21:29:26 +01:00
AddPaymentMethodMutation: &graphql.Field{
Type: graphql.Boolean,
Args: graphql.FieldConfigArgument{
FieldProjectID: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
FieldCardToken: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
FieldIsDefault: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.Boolean),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
projectID, _ := p.Args[FieldProjectID].(string)
cardToken, _ := p.Args[FieldCardToken].(string)
isDefault, _ := p.Args[FieldIsDefault].(bool)
projID, err := uuid.Parse(projectID)
if err != nil {
return false, err
}
_, err = service.AddNewPaymentMethod(p.Context, cardToken, isDefault, *projID)
if err != nil {
return false, err
}
return true, nil
},
},
DeletePaymentMethodMutation: &graphql.Field{
Type: graphql.Boolean,
Args: graphql.FieldConfigArgument{
FieldID: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
fieldProjectPaymentID, _ := p.Args[FieldID].(string)
paymentID, err := uuid.Parse(fieldProjectPaymentID)
if err != nil {
return false, err
}
err = service.DeleteProjectPaymentMethod(p.Context, *paymentID)
if err != nil {
return false, err
}
return true, nil
},
},
SetDefaultPaymentMethodMutation: &graphql.Field{
Type: graphql.Boolean,
Args: graphql.FieldConfigArgument{
FieldProjectID: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
FieldID: &graphql.ArgumentConfig{
Type: graphql.NewNonNull(graphql.String),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
fieldProjectID, _ := p.Args[FieldProjectID].(string)
fieldProjectPaymentID, _ := p.Args[FieldID].(string)
paymentID, err := uuid.Parse(fieldProjectPaymentID)
if err != nil {
return false, err
}
projectID, err := uuid.Parse(fieldProjectID)
if err != nil {
return false, err
}
err = service.SetDefaultPaymentMethod(p.Context, *paymentID, *projectID)
if err != nil {
return false, err
}
return true, nil
},
},
},
})
}