Skip to content

Commit

Permalink
db invitations tests and phone remove from whole api
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasmenendez committed Oct 29, 2024
1 parent d99e59e commit c3ea982
Show file tree
Hide file tree
Showing 13 changed files with 293 additions and 95 deletions.
2 changes: 0 additions & 2 deletions api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ type UserOrganization struct {
// UserInfo is the request to register a new user.
type UserInfo struct {
Email string `json:"email,omitempty"`
Phone string `json:"phone,omitempty"`
Password string `json:"password,omitempty"`
FirstName string `json:"firstName,omitempty"`
LastName string `json:"lastName,omitempty"`
Expand Down Expand Up @@ -88,7 +87,6 @@ type UserPasswordUpdate struct {
type UserVerification struct {
Email string `json:"email,omitempty"`
Code string `json:"code,omitempty"`
Phone string `json:"phone,omitempty"`
Expiration time.Time `json:"expiration,omitempty"`
Valid bool `json:"valid"`
}
Expand Down
24 changes: 3 additions & 21 deletions api/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@ func (a *API) sendUserCode(ctx context.Context, user *db.User, t db.CodeType) er
}); err != nil {
return err
}
} else if a.sms != nil {
// send the verification code via SMS if the SMS service is available
if err := a.sms.SendNotification(ctx, &notifications.Notification{
ToNumber: user.Phone,
Body: VerificationCodeTextBody + code,
}); err != nil {
return err
}
}
return nil
}
Expand Down Expand Up @@ -94,11 +86,6 @@ func (a *API) registerHandler(w http.ResponseWriter, r *http.Request) {
ErrMalformedBody.Withf("last name is empty").Write(w)
return
}
// check the phone is not empty
if userInfo.Phone == "" {
ErrMalformedBody.Withf("phone is empty").Write(w)
return
}
// hash the password
hPassword := internal.HexHashPassword(passwordSalt, userInfo.Password)
// add the user to the database
Expand Down Expand Up @@ -151,10 +138,8 @@ func (a *API) verifyUserAccountHandler(w http.ResponseWriter, r *http.Request) {

// check the email and verification code are not empty
if (a.mail != nil || a.sms != nil) &&
(verification.Code == "" ||
(verification.Email == "" && verification.Phone == "") ||
(a.mail == nil && verification.Email != "") ||
(a.sms == nil && verification.Phone != "")) {
(verification.Code == "" || verification.Email == "" ||
(a.mail == nil && verification.Email != "")) {
ErrInvalidUserData.With("no verification code or email/phone provided").Write(w)
return
}
Expand Down Expand Up @@ -260,7 +245,6 @@ func (a *API) userVerificationCodeInfoHandler(w http.ResponseWriter, r *http.Req
// return the verification code information
httpWriteJSON(w, UserVerification{
Email: user.Email,
Phone: user.Phone,
Expiration: code.Expiration,
Valid: code.Expiration.After(time.Now()),
})
Expand All @@ -279,7 +263,7 @@ func (a *API) resendUserVerificationCodeHandler(w http.ResponseWriter, r *http.R
return
}
// check the email or the phone number is not empty
if verification.Email == "" && verification.Phone == "" {
if verification.Email == "" {
ErrInvalidUserData.With("no email or phone number provided").Write(w)
return
}
Expand All @@ -288,8 +272,6 @@ func (a *API) resendUserVerificationCodeHandler(w http.ResponseWriter, r *http.R
// get the user information from the database by email or phone
if verification.Email != "" {
user, err = a.db.UserByEmail(verification.Email)
} else {
user, err = a.db.UserByPhone(verification.Phone)
}
// check the error getting the user information
if err != nil {
Expand Down
11 changes: 0 additions & 11 deletions api/users_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ func TestRegisterHandler(t *testing.T) {
Password: "password",
FirstName: "first",
LastName: "last",
Phone: "123456789",
}),
expectedStatus: http.StatusOK,
},
Expand All @@ -51,7 +50,6 @@ func TestRegisterHandler(t *testing.T) {
Password: "password",
FirstName: "first",
LastName: "last",
Phone: "123456789",
}),
expectedStatus: http.StatusInternalServerError,
expectedBody: mustMarshal(ErrGenericInternalServerError),
Expand All @@ -64,7 +62,6 @@ func TestRegisterHandler(t *testing.T) {
Password: "password",
FirstName: "first",
LastName: "",
Phone: "123456789",
}),
expectedStatus: http.StatusBadRequest,
expectedBody: mustMarshal(ErrMalformedBody.Withf("last name is empty")),
Expand All @@ -77,7 +74,6 @@ func TestRegisterHandler(t *testing.T) {
Password: "password",
FirstName: "",
LastName: "last",
Phone: "123456789",
}),
expectedStatus: http.StatusBadRequest,
expectedBody: mustMarshal(ErrMalformedBody.Withf("first name is empty")),
Expand All @@ -90,7 +86,6 @@ func TestRegisterHandler(t *testing.T) {
Password: "password",
FirstName: "first",
LastName: "last",
Phone: "123456789",
}),
expectedStatus: http.StatusBadRequest,
expectedBody: mustMarshal(ErrEmailMalformed),
Expand All @@ -103,7 +98,6 @@ func TestRegisterHandler(t *testing.T) {
Password: "password",
FirstName: "first",
LastName: "last",
Phone: "123456789",
}),
expectedStatus: http.StatusBadRequest,
expectedBody: mustMarshal(ErrEmailMalformed),
Expand All @@ -116,7 +110,6 @@ func TestRegisterHandler(t *testing.T) {
Password: "short",
FirstName: "first",
LastName: "last",
Phone: "123456789",
}),
expectedStatus: http.StatusBadRequest,
expectedBody: mustMarshal(ErrPasswordTooShort),
Expand All @@ -129,7 +122,6 @@ func TestRegisterHandler(t *testing.T) {
Password: "",
FirstName: "first",
LastName: "last",
Phone: "123456789",
}),
expectedStatus: http.StatusBadRequest,
},
Expand Down Expand Up @@ -157,7 +149,6 @@ func TestRegisterHandler(t *testing.T) {
c.Errorf("error closing response body: %v", err)
}
}()

c.Assert(resp.StatusCode, qt.Equals, testCase.expectedStatus)
if testCase.expectedBody != nil {
body, err := io.ReadAll(resp.Body)
Expand All @@ -181,7 +172,6 @@ func TestVerifyAccountHandler(t *testing.T) {
Password: testPass,
FirstName: testFirstName,
LastName: testLastName,
Phone: testPhone,
})
req, err := http.NewRequest(http.MethodPost, testURL(usersEndpoint), bytes.NewBuffer(jsonUser))
c.Assert(err, qt.IsNil)
Expand Down Expand Up @@ -271,7 +261,6 @@ func TestRecoverAndResetPassword(t *testing.T) {
Password: testPass,
FirstName: testFirstName,
LastName: testLastName,
Phone: testPhone,
})
req, err := http.NewRequest(http.MethodPost, testURL(usersEndpoint), bytes.NewBuffer(jsonUser))
c.Assert(err, qt.IsNil)
Expand Down
21 changes: 0 additions & 21 deletions cmd/service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/vocdoni/saas-backend/api"

Check failure on line 12 in cmd/service/main.go

View workflow job for this annotation

GitHub Actions / lint

could not import github.com/vocdoni/saas-backend/api (-: # github.com/vocdoni/saas-backend/api

Check failure on line 12 in cmd/service/main.go

View workflow job for this annotation

GitHub Actions / lint

could not import github.com/vocdoni/saas-backend/api (-: # github.com/vocdoni/saas-backend/api
"github.com/vocdoni/saas-backend/db"
"github.com/vocdoni/saas-backend/notifications/smtp"
"github.com/vocdoni/saas-backend/notifications/twilio"
"go.vocdoni.io/dvote/apiclient"
"go.vocdoni.io/dvote/log"
)
Expand All @@ -34,9 +33,6 @@ func main() {
flag.String("smtpPassword", "", "SMTP password")
flag.String("emailFromAddress", "", "Email service from address")
flag.String("emailFromName", "Vocdoni", "Email service from name")
flag.String("twilioAccountSid", "", "Twilio account SID")
flag.String("twilioAuthToken", "", "Twilio auth token")
flag.String("smsFromNumber", "", "SMS from number")
// parse flags
flag.Parse()
// initialize Viper
Expand All @@ -62,10 +58,6 @@ func main() {
smtpPassword := viper.GetString("smtpPassword")
emailFromAddress := viper.GetString("emailFromAddress")
emailFromName := viper.GetString("emailFromName")
// sms vars
twilioAccountSid := viper.GetString("twilioAccountSid")
twilioAuthToken := viper.GetString("twilioAuthToken")
twilioFromNumber := viper.GetString("twilioFromNumber")
// initialize the MongoDB database
database, err := db.New(mongoURL, mongoDB)
if err != nil {
Expand Down Expand Up @@ -118,19 +110,6 @@ func main() {
}
log.Infow("email service created", "from", fmt.Sprintf("%s <%s>", emailFromName, emailFromAddress))
}
// create SMS notifications service if the required parameters are set and
// include it in the API configuration
if twilioAccountSid != "" && twilioAuthToken != "" && twilioFromNumber != "" {
apiConf.SMSService = new(twilio.TwilioSMS)
if err := apiConf.SMSService.New(&twilio.TwilioConfig{
AccountSid: twilioAccountSid,
AuthToken: twilioAuthToken,
FromNumber: twilioFromNumber,
}); err != nil {
log.Fatalf("could not create the SMS service: %v", err)
}
log.Infow("SMS service created", "from", twilioFromNumber)
}
// create the local API server
api.New(apiConf).Start()
log.Infow("server started", "host", host, "port", port)
Expand Down
8 changes: 8 additions & 0 deletions db/mongo.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ func (ms *MongoStorage) Reset() error {
if err := ms.organizations.Drop(ctx); err != nil {
return err
}
// drop organizationInvites collection
if err := ms.organizationInvites.Drop(ctx); err != nil {
return err
}
// drop verifications collection
if err := ms.verifications.Drop(ctx); err != nil {
return err
}
// init the collections
if err := ms.initCollections(ms.database); err != nil {
return err
Expand Down
39 changes: 34 additions & 5 deletions db/organization_invites.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package db

import (
"context"
"fmt"
"time"

"go.mongodb.org/mongo-driver/bson"
Expand All @@ -12,11 +13,39 @@ import (
func (ms *MongoStorage) CreateInvitation(invite *OrganizationInvite) error {
ms.keysLock.Lock()
defer ms.keysLock.Unlock()

// create a context with a timeout
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

_, err := ms.organizationInvites.InsertOne(ctx, invite)
// check if the organization exists
if _, err := ms.organization(ctx, invite.OrganizationAddress); err != nil {
return err
}
// check if the user exists
user, err := ms.user(ctx, invite.CurrentUserID)
if err != nil {
return err
}
// check if the user is already a member of the organization
partOfOrg := false
for _, org := range user.Organizations {
if org.Address == invite.OrganizationAddress {
partOfOrg = true
break
}
}
if !partOfOrg {
return fmt.Errorf("user is not part of the organization")
}
// check if expiration date is in the future
if !invite.Expiration.After(time.Now()) {
return fmt.Errorf("expiration date must be in the future")
}
// check if the role is valid
if !IsValidUserRole(invite.Role) {
return fmt.Errorf("invalid role")
}
// insert the invitation in the database
_, err = ms.organizationInvites.InsertOne(ctx, invite)
return err
}

Expand All @@ -39,8 +68,8 @@ func (ms *MongoStorage) Invitation(invitationCode string) (*OrganizationInvite,
return invite, nil
}

// DeclineInvitation removes the invitation from the database.
func (ms *MongoStorage) DeclineInvitation(invitationCode string) error {
// DeleteInvitation removes the invitation from the database.
func (ms *MongoStorage) DeleteInvitation(invitationCode string) error {
ms.keysLock.Lock()
defer ms.keysLock.Unlock()

Expand Down
Loading

0 comments on commit c3ea982

Please sign in to comment.