create.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package invite
  2. import (
  3. "fmt"
  4. "net/http"
  5. "time"
  6. "github.com/porter-dev/porter/api/server/handlers"
  7. "github.com/porter-dev/porter/api/server/shared"
  8. "github.com/porter-dev/porter/api/server/shared/apierrors"
  9. "github.com/porter-dev/porter/api/server/shared/config"
  10. "github.com/porter-dev/porter/api/types"
  11. "github.com/porter-dev/porter/internal/models"
  12. "github.com/porter-dev/porter/internal/notifier"
  13. "github.com/porter-dev/porter/internal/oauth"
  14. )
  15. type InviteCreateHandler struct {
  16. handlers.PorterHandlerReadWriter
  17. }
  18. func NewInviteCreateHandler(
  19. config *config.Config,
  20. decoderValidator shared.RequestDecoderValidator,
  21. writer shared.ResultWriter,
  22. ) *InviteCreateHandler {
  23. return &InviteCreateHandler{
  24. PorterHandlerReadWriter: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
  25. }
  26. }
  27. func (c *InviteCreateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  28. user, _ := r.Context().Value(types.UserScope).(*models.User)
  29. project, _ := r.Context().Value(types.ProjectScope).(*models.Project)
  30. request := &types.CreateInviteRequest{}
  31. if ok := c.DecodeAndValidate(w, r, request); !ok {
  32. return
  33. }
  34. // create invite model
  35. invite, err := CreateInviteWithProject(request, project.ID)
  36. if err != nil {
  37. c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
  38. return
  39. }
  40. // write to database
  41. invite, err = c.Repo().Invite().CreateInvite(invite)
  42. if err != nil {
  43. c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
  44. return
  45. }
  46. // app.Logger.Info().Msgf("New invite created: %d", invite.ID)
  47. if err := c.Config().UserNotifier.SendProjectInviteEmail(
  48. &notifier.SendProjectInviteEmailOpts{
  49. InviteeEmail: request.Email,
  50. URL: fmt.Sprintf("%s/api/projects/%d/invites/%s", c.Config().ServerConf.ServerURL, project.ID, invite.Token),
  51. Project: project.Name,
  52. ProjectOwnerEmail: user.Email,
  53. },
  54. ); err != nil {
  55. c.HandleAPIError(w, r, apierrors.NewErrInternal(err))
  56. return
  57. }
  58. res := types.CreateInviteResponse{
  59. Invite: invite.ToInviteType(),
  60. }
  61. c.WriteResult(w, r, res)
  62. }
  63. func CreateInviteWithProject(invite *types.CreateInviteRequest, projectID uint) (*models.Invite, error) {
  64. // generate a token and an expiry time
  65. expiry := time.Now().Add(24 * time.Hour)
  66. return &models.Invite{
  67. Email: invite.Email,
  68. Kind: invite.Kind,
  69. Expiry: &expiry,
  70. ProjectID: projectID,
  71. Token: oauth.CreateRandomState(),
  72. }, nil
  73. }