diff --git a/dfssc/user/register.go b/dfssc/user/register.go index 071729c2cf7f8131f83fac736c29eb625354c341..f002ed9e07742ec49a153d48a4d1324458f113e4 100644 --- a/dfssc/user/register.go +++ b/dfssc/user/register.go @@ -5,13 +5,11 @@ import ( "regexp" "time" - "github.com/spf13/viper" - "dfss/dfssc/common" "dfss/dfssc/security" pb "dfss/dfssp/api" "dfss/net" - + "github.com/spf13/viper" "golang.org/x/net/context" "google.golang.org/grpc" ) @@ -27,6 +25,8 @@ type RegisterManager struct { bits int } +var mailRegex = regexp.MustCompile(`.+@.+\..+`) + // NewRegisterManager return a new Register Manager to register a user func NewRegisterManager(passphrase, country, organization, unit, mail string, bits int, v *viper.Viper) (*RegisterManager, error) { m := &RegisterManager{v, passphrase, country, organization, unit, mail, bits} @@ -44,8 +44,7 @@ func NewRegisterManager(passphrase, country, organization, unit, mail string, bi // Check the validity of the provided email, passphrase and bits func (m *RegisterManager) checkValidParams() error { - re, _ := regexp.Compile(`.+@.+\..+`) - if b := re.MatchString(m.mail); !b { + if b := mailRegex.MatchString(m.mail); !b { return errors.New("Provided mail is not valid") } diff --git a/dfssp/contract/contract_test.go b/dfssp/contract/contract_test.go index 14e0dd577328c2169e10c9a06fe5a6976719981e..cb326cbed790eb8f9d51ef8c387ad642f1bed2f1 100644 --- a/dfssp/contract/contract_test.go +++ b/dfssp/contract/contract_test.go @@ -2,6 +2,7 @@ package contract_test // Using another package to avoid import cycles import ( "fmt" + "log" "os" "path/filepath" "testing" @@ -49,7 +50,7 @@ func TestMain(m *testing.M) { viper.Set("verbose", true) srv := server.GetServer() - go func() { _ = net.Listen("localhost:9090", srv) }() + go func() { log.Fatal(net.Listen("localhost:9090", srv)) }() // Run code := m.Run() @@ -142,7 +143,7 @@ func TestGetWaitingForUser(t *testing.T) { c1.Ready = false c2 := entities.NewContract() - c2.AddSigner(nil, "mail1", []byte{}) + c2.AddSigner(nil, "mAil1", []byte{}) c2.AddSigner(&knownID, "mail2", []byte{0x12}) c2.Ready = false diff --git a/dfssp/contract/create.go b/dfssp/contract/create.go index e0d0eb122334738a382f700a47b56b8aa8e9ef49..8bea04c0a0bff337cdbf1669b171bb0892e2769d 100644 --- a/dfssp/contract/create.go +++ b/dfssp/contract/create.go @@ -4,6 +4,7 @@ package contract import ( "crypto/sha512" "log" + "strings" "time" "dfss/dfssp/api" @@ -62,7 +63,6 @@ func (c *Builder) Execute() *api.ErrorCode { // checkInput checks that a PostContractRequest is well-formed func (c *Builder) checkInput() *api.ErrorCode { - if len(c.in.Signer) == 0 { return &api.ErrorCode{Code: api.ErrorCode_INVARG, Message: "Expecting at least one signer"} } @@ -76,18 +76,23 @@ func (c *Builder) checkInput() *api.ErrorCode { } return nil - } // fetchSigners fetches authenticated users for this contract from the DB func (c *Builder) fetchSigners() error { var users []entities.User + // Convert emails to case-tolerant emails + var conditions []bson.RegEx + for _, s := range c.in.Signer { + conditions = append(conditions, bson.RegEx{Pattern: "^" + s + "$", Options: "i"}) + } + // Fetch users where email is part of the signers slice in request // and authentication is valid err := c.m.Get("users").FindAll(bson.M{ "expiration": bson.M{"$gt": time.Now()}, - "email": bson.M{"$in": c.in.Signer}, + "email": bson.M{"$in": conditions}, }, &users) if err != nil { return err @@ -96,8 +101,9 @@ func (c *Builder) fetchSigners() error { // Locate missing users for _, s := range c.in.Signer { found := false + lowerEmail := strings.ToLower(s) for _, u := range users { - if s == u.Email { + if lowerEmail == strings.ToLower(u.Email) { found = true break } diff --git a/dfssp/contract/create_test.go b/dfssp/contract/create_test.go index d490dcc3e3719ab70237c193ab08cf054d334224..d6498cea96877b06c2de4647360c896070f7f84b 100644 --- a/dfssp/contract/create_test.go +++ b/dfssp/contract/create_test.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "path/filepath" + "strings" "testing" "time" @@ -88,7 +89,7 @@ func TestAddContract(t *testing.T) { errorCode, err := client.PostContract(context.Background(), &api.PostContractRequest{ Hash: defaultHash[:], Filename: "ContractFilename", - Signer: []string{user1.Email, user2.Email}, + Signer: []string{strings.ToUpper(user1.Email), user2.Email}, Comment: "ContractComment", }) assert.Equal(t, nil, err) diff --git a/dfssp/entities/contract.go b/dfssp/entities/contract.go index eaf68481ef3ecd421f442694ba207c1d636f5848..c8ced969caa41b75f8b422146e7fa0936bd079a3 100644 --- a/dfssp/entities/contract.go +++ b/dfssp/entities/contract.go @@ -89,7 +89,7 @@ func (r *ContractRepository) GetWaitingForUser(email string) ([]Contract, error) "ready": false, "signers": bson.M{ "$elemMatch": bson.M{ - "email": email, + "email": bson.M{"$regex": bson.RegEx{Pattern: "^" + email + "$", Options: "i"}}, "hash": []byte{}, }}, }, &res) diff --git a/dfssp/user/auth.go b/dfssp/user/auth.go new file mode 100644 index 0000000000000000000000000000000000000000..4b7134c27a8ba5344894d2c8c7564833a7dd6035 --- /dev/null +++ b/dfssp/user/auth.go @@ -0,0 +1,153 @@ +package user + +import ( + "crypto/rsa" + "crypto/x509" + "errors" + "log" + "strings" + "time" + + "dfss/auth" + "dfss/dfssp/api" + "dfss/dfssp/authority" + "dfss/dfssp/contract" + "dfss/dfssp/entities" + "dfss/mgdb" + "github.com/spf13/viper" + "gopkg.in/mgo.v2/bson" +) + +// Check if the authentication request was made in time +func checkTokenTimeout(user *entities.User) error { + now := time.Now().UTC() + bad := now.After(user.Registration.Add(maxRegistrationDelay)) + if bad { + return errors.New("Registration request is too old, please register again") + } + + return nil +} + +// Gerenate the user's certificate and certificate hash according to the specified parameters +// +// This function should only be called AFTER checking the AuthRequest for validity +func generateUserCert(csr string, parent *x509.Certificate, key *rsa.PrivateKey) ([]byte, []byte, error) { + x509csr, err := auth.PEMToCertificateRequest([]byte(csr)) + if err != nil { + return nil, nil, err + } + + cert, err := auth.GetCertificate(viper.GetInt("validity"), auth.GenerateUID(), x509csr, parent, key) + if err != nil { + return nil, nil, err + } + + c, _ := auth.PEMToCertificate(cert) + certHash := auth.GetCertificateHash(c) + + return cert, certHash, nil +} + +// Auth checks if the authentication request is valid, and if so, +// generate the certificate and certificate hash for the user, and +// updates the user's entry in the database +// +// If there is already an entry in the database with the same email, +// and that this entry already has a certificate and certificate hash, +// evaluates the request as invalid +// +// The user's ConnectionInfo field is NOT handled here +// This data should be gathered upon beginning the signing sequence +func Auth(pid *authority.PlatformID, manager *mgdb.MongoManager, in *api.AuthRequest) (*api.RegisteredUser, error) { + // Check the request validity + err := checkAuthRequest(in) + if err != nil { + return nil, err + } + + // Find the user in the database (last created) + var user entities.User + err = manager.Get("users").Collection.Find(bson.M{ + "email": bson.M{"$eq": in.Email}, + }).Sort("-registration").One(&user) + if err != nil { + return nil, err + } + + // If the user already has a certificate and certificate hash in the database, does nothing + if user.Certificate != "" || len(user.CertHash) != 0 { + return nil, errors.New("User is already registered") + } + + // Check if the delta between now and the moment the user was created (ie the moment he sent the register request) is in bound + err = checkTokenTimeout(&user) + if err != nil { + return nil, err + } + + // Check if the token is correct + if in.Token != user.RegToken { + return nil, errors.New("Token mismatch") + } + + // Generate the certificates and hash + cert, certHash, err := generateUserCert(user.Csr, pid.RootCA, pid.Pkey) + if err != nil { + return nil, err + } + + user.Certificate = string(cert) + user.CertHash = certHash + user.Expiration = time.Now().AddDate(0, 0, viper.GetInt("validity")) + + // Updating the database + ok, err := manager.Get("users").UpdateByID(user) + if !ok { + return nil, err + } + + // Update missed contracts in background + go launchMissedContracts(manager, &user) + + // Returning the RegisteredUser message + return &api.RegisteredUser{ClientCert: user.Certificate}, nil +} + +func launchMissedContracts(manager *mgdb.MongoManager, user *entities.User) { + + repository := entities.NewContractRepository(manager.Get("contracts")) + contracts, err := repository.GetWaitingForUser(user.Email) + if err != nil { + log.Println("Cannot get missed contracts for user", user.Email+":", err) + } + + lowerEmail := strings.ToLower(user.Email) + for _, c := range contracts { + + c.Ready = true + for i := range c.Signers { + if strings.ToLower(c.Signers[i].Email) == lowerEmail { + c.Signers[i].Hash = user.CertHash + c.Signers[i].UserID = user.ID + } + if len(c.Signers[i].Hash) == 0 { + c.Ready = false + } + } + + // Update contract in database + _, err = repository.Collection.UpdateByID(c) + if err != nil { + log.Println("Cannot update missed contract", c.ID, "for user", user.Email+":", err) + } + + if c.Ready { + // Send required mails + builder := contract.NewContractBuilder(manager, nil) + builder.Contract = &c + builder.SendNewContractMail() + } + } + +} diff --git a/dfssp/user/auth_test.go b/dfssp/user/auth_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bc83d9cbd2a800f304ece18939eb922424177af3 --- /dev/null +++ b/dfssp/user/auth_test.go @@ -0,0 +1,113 @@ +package user_test + +import ( + "dfss/dfssp/api" + "testing" + "time" + + "dfss/dfssp/entities" + "github.com/stretchr/testify/assert" + "golang.org/x/net/context" +) + +func TestAuthUserNotFound(t *testing.T) { + mail := "wrong@wrong.wrong" + token := "wrong" + client := clientTest(t, ValidServ) + + request := &api.AuthRequest{Email: mail, Token: token} + msg, err := client.Auth(context.Background(), request) + assert.Equal(t, (*api.RegisteredUser)(nil), msg) + if err == nil { + t.Fatal("The request user should not have been found in the database") + } +} + +func TestAuthTwice(t *testing.T) { + email := "email" + token := "token" + user := entities.NewUser() + user.Email = email + user.RegToken = token + user.Csr = string(csr) + user.Certificate = "foo" + user.CertHash = []byte{0xaa} + + _, err = repository.Collection.Insert(*user) + if err != nil { + t.Fatal(err) + } + + // User is already registered + client := clientTest(t, ValidServ) + request := &api.AuthRequest{Email: email, Token: token} + msg, err := client.Auth(context.Background(), request) + assert.Equal(t, msg, (*api.RegisteredUser)(nil)) + if err == nil { + t.Fatal("The user should have been evaluated as already registered") + } +} + +func TestWrongAuthRequestContext(t *testing.T) { + mail := "right@right.right" + token := "right" + + user := entities.NewUser() + user.Email = mail + user.RegToken = token + user.Registration = time.Now().UTC().Add(time.Hour * -48) + + _, err := repository.Collection.Insert(*user) + if err != nil { + t.Fatal(err) + } + + client := clientTest(t, ValidServ) + + request := &api.AuthRequest{Email: mail, Token: "foo"} + + // Token timeout + msg, err := client.Auth(context.Background(), request) + assert.Equal(t, (*api.RegisteredUser)(nil), msg) + if err == nil { + t.Fatal("The request should have been evaluated as invalid") + } + + // Token mismatch + user.Registration = time.Now().UTC() + + _, err = repository.Collection.UpdateByID(*user) + if err != nil { + t.Fatal(err) + } + + msg, err = client.Auth(context.Background(), request) + assert.Equal(t, (*api.RegisteredUser)(nil), msg) + if err == nil { + t.Fatal("The request should have been evaluated as invalid") + } + + res := entities.User{} + err = repository.Collection.FindByID(*user, &res) + if err != nil { + t.Fatal(err) + } + + assert.Equal(t, res.Certificate, "") + assert.Equal(t, res.CertHash, []byte{}) + + // Invalid certificate request (none here) + request.Token = token + msg, err = client.Auth(context.Background(), request) + assert.Equal(t, (*api.RegisteredUser)(nil), msg) + if err == nil { + t.Fatal("The request should have been evaluated as invalid") + } + + err = repository.Collection.FindByID(*user, &res) + if err != nil { + t.Fatal(err) + } + assert.Equal(t, res.Certificate, "") + assert.Equal(t, res.CertHash, []byte{}) +} diff --git a/dfssp/user/create.go b/dfssp/user/create.go index f908ebd0a14f544d240aedd880edb9be1077f63a..31d2c1d299844791dbce503fe448d3f81bc394fa 100644 --- a/dfssp/user/create.go +++ b/dfssp/user/create.go @@ -3,17 +3,14 @@ package user import ( "crypto/rand" - "crypto/rsa" - "crypto/x509" "errors" "fmt" "log" + "regexp" "time" "dfss/auth" "dfss/dfssp/api" - "dfss/dfssp/authority" - "dfss/dfssp/contract" "dfss/dfssp/entities" "dfss/dfssp/templates" "dfss/mgdb" @@ -21,12 +18,21 @@ import ( "gopkg.in/mgo.v2/bson" ) +var ( + mailRegex = regexp.MustCompile(`.+@.+\..+`) + maxRegistrationDelay = 24 * time.Hour +) + // Check if the registration request has usable fields func checkRegisterRequest(in *api.RegisterRequest) *api.ErrorCode { if len(in.Email) == 0 { return &api.ErrorCode{Code: api.ErrorCode_INVARG, Message: "Invalid email length"} } + if b := mailRegex.MatchString(in.Email); !b { + return &api.ErrorCode{Code: api.ErrorCode_INVARG, Message: "Invalid mail"} + } + if len(in.Request) == 0 { return &api.ErrorCode{Code: api.ErrorCode_INVARG, Message: "Invalid request length"} } @@ -97,10 +103,14 @@ func Register(manager *mgdb.MongoManager, in *api.RegisterRequest) (*api.ErrorCo } token := fmt.Sprintf("%x", b) - // If there is already an entry with the same mail, do nothing + // If there is already an entry with the same mail (case-insensitive), do nothing. var res []entities.User err = manager.Get("users").FindAll(bson.M{ - "email": bson.M{"$eq": in.Email}, + "$or": []bson.M{ + bson.M{"expiration": bson.M{"$gt": time.Now()}}, // authentified + bson.M{"registration": bson.M{"$gt": time.Now().Add(-1 * maxRegistrationDelay)}}, // authentifying + }, + "email": bson.M{"$regex": bson.RegEx{Pattern: "^" + in.Email + "$", Options: "i"}}, }, &res) if len(res) != 0 { return &api.ErrorCode{Code: api.ErrorCode_INVARG, Message: "An entry already exists with the same mail"}, nil @@ -140,137 +150,3 @@ func checkAuthRequest(in *api.AuthRequest) error { return nil } - -// Check if the authentication request was made in time -func checkTokenTimeout(user *entities.User) error { - now := time.Now().UTC() - bad := now.After(user.Registration.Add(time.Hour * 24)) - if bad { - return errors.New("Registration request is over 24 hours old") - } - - return nil -} - -// Gerenate the user's certificate and certificate hash according to the specified parameters -// -// This function should only be called AFTER checking the AuthRequest for validity -func generateUserCert(csr string, parent *x509.Certificate, key *rsa.PrivateKey) ([]byte, []byte, error) { - x509csr, err := auth.PEMToCertificateRequest([]byte(csr)) - if err != nil { - return nil, nil, err - } - - cert, err := auth.GetCertificate(viper.GetInt("validity"), auth.GenerateUID(), x509csr, parent, key) - if err != nil { - return nil, nil, err - } - - c, _ := auth.PEMToCertificate(cert) - certHash := auth.GetCertificateHash(c) - - return cert, certHash, nil -} - -// Auth checks if the authentication request is valid, and if so, -// generate the certificate and certificate hash for the user, and -// updates the user's entry in the database -// -// If there is already an entry in the database with the same email, -// and that this entry already has a certificate and certificate hash, -// evaluates the request as invalid -// -// The user's ConnectionInfo field is NOT handled here -// This data should be gathered upon beginning the signing sequence -func Auth(pid *authority.PlatformID, manager *mgdb.MongoManager, in *api.AuthRequest) (*api.RegisteredUser, error) { - // Check the request validity - err := checkAuthRequest(in) - if err != nil { - return nil, err - } - - // Find the user in the database - var user entities.User - - err = manager.Get("users").Collection.Find(bson.M{ - "email": bson.M{"$eq": in.Email}, - }).One(&user) - if err != nil { - return nil, err - } - - // If the user already has a certificate and certificate hash in the database, does nothing - if user.Certificate != "" || len(user.CertHash) != 0 { - return nil, errors.New("User is already registered") - } - - // Check if the delta between now and the moment the user was created (ie the moment he sent the register request) is in bound of 24h - err = checkTokenTimeout(&user) - if err != nil { - return nil, err - } - - // Check if the token is correct - if in.Token != user.RegToken { - return nil, errors.New("Token mismatch") - } - - // Generate the certificates and hash - cert, certHash, err := generateUserCert(user.Csr, pid.RootCA, pid.Pkey) - if err != nil { - return nil, err - } - - user.Certificate = string(cert) - user.CertHash = certHash - user.Expiration = time.Now().AddDate(0, 0, viper.GetInt("validity")) - - // Updating the database - ok, err := manager.Get("users").UpdateByID(user) - if !ok { - return nil, err - } - - // Update missed contracts in background - go launchMissedContracts(manager, &user) - - // Returning the RegisteredUser message - return &api.RegisteredUser{ClientCert: user.Certificate}, nil -} - -func launchMissedContracts(manager *mgdb.MongoManager, user *entities.User) { - - repository := entities.NewContractRepository(manager.Get("contracts")) - contracts, err := repository.GetWaitingForUser(user.Email) - if err != nil { - log.Println("Cannot get missed contracts for user", user.Email+":", err) - } - - for _, c := range contracts { - - c.Ready = true - for i := range c.Signers { - if c.Signers[i].Email == user.Email { - c.Signers[i].Hash = user.CertHash - c.Signers[i].UserID = user.ID - } - if len(c.Signers[i].Hash) == 0 { - c.Ready = false - } - } - - // Update contract in database - _, err = repository.Collection.UpdateByID(c) - if err != nil { - log.Println("Cannot update missed contract", c.ID, "for user", user.Email+":", err) - } - - if c.Ready { - // Send required mails - builder := contract.NewContractBuilder(manager, nil) - builder.Contract = &c - builder.SendNewContractMail() - } - } - -} diff --git a/dfssp/user/create_test.go b/dfssp/user/create_test.go index ac4164d214766a8829b368eace4e6a7e2e440995..184f9e24b0072a318c809f22d4b90792e9372833 100644 --- a/dfssp/user/create_test.go +++ b/dfssp/user/create_test.go @@ -2,26 +2,24 @@ package user_test import ( "dfss/dfssp/api" - "dfss/net" + "testing" + "time" + + "dfss/dfssp/entities" "github.com/stretchr/testify/assert" "golang.org/x/net/context" - "testing" ) -const ( - // ValidServ is a host/port adress to a platform server with bad setup - ValidServ = "localhost:9090" - // InvalidServ is a host/port adress to a platform server with bad setup - InvalidServ = "localhost:9091" -) +func TestSimpleRegister(t *testing.T) { + client := clientTest(t, ValidServ) -func clientTest(t *testing.T, hostPort string) api.PlatformClient { - conn, err := net.Connect(hostPort, nil, nil, rootCA, nil) - if err != nil { - t.Fatal("Unable to connect: ", err) + request := &api.RegisterRequest{ + Email: "simple@simple.simple", + Request: string(csr), } - - return api.NewPlatformClient(conn) + errCode, err := client.Register(context.Background(), request) + assert.Nil(t, err) + assert.Equal(t, errCode.Code, api.ErrorCode_SUCCESS) } func TestWrongRegisterRequest(t *testing.T) { @@ -29,29 +27,56 @@ func TestWrongRegisterRequest(t *testing.T) { request := &api.RegisterRequest{} errCode, err := client.Register(context.Background(), request) - assert.Equal(t, nil, err) + assert.Nil(t, err) assert.Equal(t, errCode.Code, api.ErrorCode_INVARG) + // Wrong email, good request request.Email = "foo" + request.Request = string(csr) errCode, err = client.Register(context.Background(), request) - assert.Equal(t, nil, err) + assert.Nil(t, err) assert.Equal(t, errCode.Code, api.ErrorCode_INVARG) + // Good email, wrong request + request.Email = "foo@foo.foo" request.Request = "foo" errCode, err = client.Register(context.Background(), request) - assert.Equal(t, nil, err) + assert.Nil(t, err) assert.Equal(t, errCode.Code, api.ErrorCode_INVARG) } -func TestAuthUserNotFound(t *testing.T) { - mail := "wrong@wrong.wrong" - token := "wrong" +// An entry already exists with the same email and a very close registration date +// -> Unable to register, even with a different case +func TestRegisterTwice(t *testing.T) { + user := entities.NewUser() + user.Email = "twice@twice.twice" + + _, err = repository.Collection.Insert(*user) + assert.Nil(t, err) + client := clientTest(t, ValidServ) - request := &api.AuthRequest{Email: mail, Token: token} - msg, err := client.Auth(context.Background(), request) - assert.Equal(t, (*api.RegisteredUser)(nil), msg) - if err == nil { - t.Fatal("The request user should not have been found in the database") - } + request := &api.RegisterRequest{Email: "twice@twice.twIce", Request: string(csr)} + errCode, err := client.Register(context.Background(), request) + assert.Equal(t, err, nil) + assert.Equal(t, errCode.Code, api.ErrorCode_INVARG) +} + +// An entry already exists with the same email, BUT expiration is behind us +// -> Able to register +func TestRegisterRenew(t *testing.T) { + user := entities.NewUser() + user.Email = "renew@renew.renew" + user.Registration = time.Now().AddDate(0, 0, -2) + user.Expiration = time.Now().Add(-1 * time.Hour) + + _, err = repository.Collection.Insert(*user) + assert.Nil(t, err) + + client := clientTest(t, ValidServ) + + request := &api.RegisterRequest{Email: "renew@renew.renew", Request: string(csr)} + errCode, err := client.Register(context.Background(), request) + assert.Equal(t, err, nil) + assert.Equal(t, errCode.Code, api.ErrorCode_SUCCESS) } diff --git a/dfssp/user/user_test.go b/dfssp/user/user_test.go index db919e4c87ce3b2fe0df0c76b4ca40bf418124ae..5e3349bd6172ed661e7e6c423d6fd6389145ee62 100644 --- a/dfssp/user/user_test.go +++ b/dfssp/user/user_test.go @@ -5,10 +5,10 @@ import ( "crypto/x509" "fmt" "io/ioutil" + "log" "os" "path/filepath" "testing" - "time" "dfss/auth" "dfss/dfssp/api" @@ -17,7 +17,6 @@ import ( "dfss/mgdb" "dfss/net" "github.com/spf13/viper" - "github.com/stretchr/testify/assert" "golang.org/x/net/context" "gopkg.in/mgo.v2/bson" ) @@ -29,6 +28,20 @@ var ( rootKey, pkey *rsa.PrivateKey ) +const ( + // ValidServ is a host/port adress to a platform server with good setup + ValidServ = "localhost:9090" +) + +func clientTest(t *testing.T, hostPort string) api.PlatformClient { + conn, err := net.Connect(hostPort, nil, nil, rootCA, nil) + if err != nil { + t.Fatal("Unable to connect: ", err) + } + + return api.NewPlatformClient(conn) +} + func init() { mail = "foo@foo.foo" pkey, _ = auth.GeneratePrivateKey(512) @@ -75,7 +88,7 @@ func TestMain(m *testing.M) { viper.Set("validity", 365) viper.Set("verbose", true) srv := server.GetServer() - go func() { _ = net.Listen(ValidServ, srv) }() + go func() { log.Fatal(net.Listen(ValidServ, srv)) }() // Run err = collection.Drop() @@ -86,7 +99,6 @@ func TestMain(m *testing.M) { fmt.Println("An error occurred while droping the collection") } manager.Close() - os.Exit(code) } @@ -182,70 +194,6 @@ func TestMongoFetchIncompleteUser(t *testing.T) { equalUsers(t, &user, fetched) } -func TestWrongAuthRequestContext(t *testing.T) { - mail := "right@right.right" - token := "right" - - user := entities.NewUser() - user.Email = mail - user.RegToken = token - user.Registration = time.Now().UTC().Add(time.Hour * -48) - - _, err := repository.Collection.Insert(*user) - if err != nil { - t.Fatal(err) - } - - client := clientTest(t, ValidServ) - - request := &api.AuthRequest{Email: mail, Token: "foo"} - - // Token timeout - msg, err := client.Auth(context.Background(), request) - assert.Equal(t, (*api.RegisteredUser)(nil), msg) - if err == nil { - t.Fatal("The request should have been evaluated as invalid") - } - - // Token mismatch - user.Registration = time.Now().UTC() - - _, err = repository.Collection.UpdateByID(*user) - if err != nil { - t.Fatal(err) - } - - msg, err = client.Auth(context.Background(), request) - assert.Equal(t, (*api.RegisteredUser)(nil), msg) - if err == nil { - t.Fatal("The request should have been evaluated as invalid") - } - - res := entities.User{} - err = repository.Collection.FindByID(*user, &res) - if err != nil { - t.Fatal(err) - } - - assert.Equal(t, res.Certificate, "") - assert.Equal(t, res.CertHash, []byte{}) - - // Invalid certificate request (none here) - request.Token = token - msg, err = client.Auth(context.Background(), request) - assert.Equal(t, (*api.RegisteredUser)(nil), msg) - if err == nil { - t.Fatal("The request should have been evaluated as invalid") - } - - err = repository.Collection.FindByID(*user, &res) - if err != nil { - t.Fatal(err) - } - assert.Equal(t, res.Certificate, "") - assert.Equal(t, res.CertHash, []byte{}) -} - func ExampleAuth() { mail := "example@example.example" token := "example" @@ -306,48 +254,3 @@ func ExampleAuth() { // Certificate successfully received // Database successfully updated with cert and certHash } - -func TestRegisterTwice(t *testing.T) { - mail := "done@done.done" - - user := entities.NewUser() - user.Email = mail - - _, err = repository.Collection.Insert(*user) - if err != nil { - fmt.Println(err) - } - - client := clientTest(t, ValidServ) - - // An entry already exists with the same email - request := &api.RegisterRequest{Email: mail, Request: string(csr)} - errCode, err := client.Register(context.Background(), request) - assert.Equal(t, err, nil) - assert.Equal(t, errCode.Code, api.ErrorCode_INVARG) -} - -func TestAuthTwice(t *testing.T) { - email := "email" - token := "token" - user := entities.NewUser() - user.Email = email - user.RegToken = token - user.Csr = string(csr) - user.Certificate = "foo" - user.CertHash = []byte{0xaa} - - _, err = repository.Collection.Insert(*user) - if err != nil { - t.Fatal(err) - } - - // User is already registered - client := clientTest(t, ValidServ) - request := &api.AuthRequest{Email: email, Token: token} - msg, err := client.Auth(context.Background(), request) - assert.Equal(t, msg, (*api.RegisteredUser)(nil)) - if err == nil { - t.Fatal("The user should have been evaluated as already registered") - } -}