// Post creates a new device func Post(render render.Render, r doorbot.Repositories, vm DeviceViewModel) { repo := r.DeviceRepository() vm.Device.Token = security.GenerateAPIToken() err := repo.Create(r.DB(), vm.Device) if err != nil { log.WithFields(log.Fields{ "error": err, "account_id": r.AccountScope(), }).Error("Api::Devices->Post database error") render.JSON(http.StatusInternalServerError, doorbot.NewInternalServerErrorResponse([]string{})) return } log.WithFields(log.Fields{ "account_id": r.AccountScope(), "device_id": vm.Device.ID, }).Info("Api::Devices->Put device created") render.JSON(http.StatusCreated, vm) }
// Password will authenticate a person using the provided email and password. // A token will be generated if the authentication succeeds. func Password(render render.Render, account *doorbot.Account, r doorbot.Repositories, vm PasswordRequest) { personRepo := r.PersonRepository() authRepo := r.AuthenticationRepository() // Find the person by email person, err := personRepo.FindByEmail(r.DB(), vm.Authentication.Email) if err != nil { log.WithFields(log.Fields{ "error": err, "email": vm.Authentication.Email, "account_id": account.ID, "step": "find-person-by-email", }).Error("Api::Auth->Password database error") render.JSON(http.StatusUnauthorized, doorbot.NewUnauthorizedErrorResponse([]string{"Invalid email or password"})) return } if person == nil { log.WithFields(log.Fields{ "account_id": account.ID, "email": vm.Authentication.Email, "step": "find-person-by-email", }).Info("Api::Auth->Password invalid email.") render.JSON(http.StatusUnauthorized, doorbot.NewUnauthorizedErrorResponse([]string{"Invalid email or password"})) return } //Fetch the password authentication record authentication, err := authRepo.FindByPersonIDAndProviderID(r.DB(), person.ID, auth.ProviderPassword) if err != nil { log.WithFields(log.Fields{ "error": err, "account_id": account.ID, "person_id": person.ID, "step": "find-person-authentication", }).Error("Api::Auth->Password database error") render.JSON(http.StatusUnauthorized, doorbot.NewUnauthorizedErrorResponse([]string{"Invalid email or password"})) return } if authentication == nil { log.WithFields(log.Fields{ "account_id": account.ID, "person_id": person.ID, "step": "find-person-authentication", }).Info("Api::Auth->Password no authentication") render.JSON(http.StatusUnauthorized, doorbot.NewUnauthorizedErrorResponse([]string{"Invalid email or password"})) return } //Compare the passwords err = security.PasswordCompare([]byte(authentication.Token), []byte(vm.Authentication.Password)) if err != nil { log.WithFields(log.Fields{ "error": err, "person_id": person.ID, "account_id": account.ID, "step": "compare-password", }).Info("Api::Auth->Password compare password error") render.JSON(http.StatusUnauthorized, doorbot.NewUnauthorizedErrorResponse([]string{"Invalid email or password"})) return } // Find the first active API token for this person. token, err := authRepo.FindByPersonIDAndProviderID(r.DB(), person.ID, auth.ProviderAPIToken) if err != nil { log.WithFields(log.Fields{ "error": err, "account_id": account.ID, "person_id": person.ID, "step": "find-authentication", }).Error("Api::Auth->Password database error") render.JSON(http.StatusInternalServerError, doorbot.NewInternalServerErrorResponse([]string{})) return } // No active token or the person has not yet signed in. Generate a new token. if token == nil { token = &doorbot.Authentication{ PersonID: person.ID, ProviderID: auth.ProviderAPIToken, Token: security.GenerateAPIToken(), } err = authRepo.Create(r.DB(), token) if err != nil { log.WithFields(log.Fields{ "error": err, "person_id": person.ID, "account_id": account.ID, "step": "save-authentication", }).Error("Api::Auth->Password database error") render.JSON(http.StatusInternalServerError, doorbot.NewInternalServerErrorResponse([]string{})) return } } log.WithFields(log.Fields{ "account_id": account.ID, "person_id": person.ID, }).Info("Api::Auth->Password user logged in") resp := APITokenResponse{} resp.Authentication.Token = fmt.Sprintf("%d.%s", person.ID, token.Token) resp.Person = person resp.Policy = getPolicyForPerson(person) render.JSON(http.StatusOK, resp) }