migrate.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package user
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "strconv"
  7. "github.com/davecgh/go-spew/spew"
  8. ory "github.com/ory/client-go"
  9. "github.com/porter-dev/porter/internal/telemetry"
  10. "github.com/porter-dev/porter/api/server/handlers"
  11. "github.com/porter-dev/porter/api/server/shared"
  12. "github.com/porter-dev/porter/api/server/shared/apierrors"
  13. "github.com/porter-dev/porter/api/server/shared/config"
  14. )
  15. type MigrateUsersHandler struct {
  16. handlers.PorterHandler
  17. }
  18. func NewMigrateUsersHandler(
  19. config *config.Config,
  20. decoderValidator shared.RequestDecoderValidator,
  21. writer shared.ResultWriter,
  22. ) *MigrateUsersHandler {
  23. return &MigrateUsersHandler{
  24. PorterHandler: handlers.NewDefaultPorterHandler(config, decoderValidator, writer),
  25. }
  26. }
  27. func (u *MigrateUsersHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  28. ctx, span := telemetry.NewSpan(r.Context(), "serve-migrate-users")
  29. defer span.End()
  30. r = r.Clone(ctx)
  31. users, err := u.Repo().User().ListUsers()
  32. if err != nil {
  33. err := telemetry.Error(ctx, span, nil, "error listing users")
  34. u.HandleAPIError(w, r, apierrors.NewErrPassThroughToClient(err, http.StatusInternalServerError))
  35. return
  36. }
  37. for _, user := range users {
  38. createIdentityBody := ory.CreateIdentityBody{
  39. SchemaId: "preset://email",
  40. Traits: map[string]interface{}{"email": user.Email},
  41. }
  42. if user.EmailVerified {
  43. createIdentityBody.VerifiableAddresses = []ory.VerifiableIdentityAddress{
  44. {
  45. Value: user.Email,
  46. Verified: true,
  47. Via: "email",
  48. Status: "completed",
  49. },
  50. }
  51. }
  52. if user.Password != "" {
  53. password := user.Password
  54. createIdentityBody.Credentials = &ory.IdentityWithCredentials{
  55. Oidc: nil,
  56. Password: &ory.IdentityWithCredentialsPassword{
  57. Config: &ory.IdentityWithCredentialsPasswordConfig{
  58. HashedPassword: &password,
  59. },
  60. },
  61. AdditionalProperties: nil,
  62. }
  63. } else if user.GithubUserID != 0 {
  64. createIdentityBody.Credentials = &ory.IdentityWithCredentials{
  65. Oidc: &ory.IdentityWithCredentialsOidc{
  66. Config: &ory.IdentityWithCredentialsOidcConfig{
  67. Config: nil,
  68. Providers: []ory.IdentityWithCredentialsOidcConfigProvider{
  69. {
  70. Provider: "github",
  71. Subject: strconv.Itoa(int(user.GithubUserID)),
  72. },
  73. },
  74. },
  75. },
  76. }
  77. } else if user.GoogleUserID != "" {
  78. createIdentityBody.Credentials = &ory.IdentityWithCredentials{
  79. Oidc: &ory.IdentityWithCredentialsOidc{
  80. Config: &ory.IdentityWithCredentialsOidcConfig{
  81. Config: nil,
  82. Providers: []ory.IdentityWithCredentialsOidcConfigProvider{
  83. {
  84. Provider: "google",
  85. Subject: user.GoogleUserID,
  86. },
  87. },
  88. },
  89. },
  90. }
  91. } else {
  92. continue
  93. }
  94. createdIdentity, resp, err := u.Config().Ory.IdentityAPI.CreateIdentity(context.WithValue(ctx, ory.ContextAccessToken, u.Config().OryApiKey)).CreateIdentityBody(createIdentityBody).Execute()
  95. if err != nil {
  96. switch resp.StatusCode {
  97. // identity already exists, so we need to list the identities and find the one that matches
  98. case 409:
  99. identities, _, err := u.Config().Ory.IdentityAPI.ListIdentities(context.WithValue(ctx, ory.ContextAccessToken, u.Config().OryApiKey)).CredentialsIdentifier(user.Email).Execute()
  100. if err != nil {
  101. fmt.Printf("Error when calling `IdentityApi.ListIdentities``: %v\n", err)
  102. continue
  103. }
  104. if len(identities) != 1 {
  105. fmt.Printf("Error when calling `IdentityApi.ListIdentities``: expected 1 identity, got %d\n", len(identities))
  106. continue
  107. }
  108. createdIdentity = &identities[0]
  109. default:
  110. fmt.Printf("Error when calling `IdentityApi.CreateIdentity``: %v\n", err)
  111. continue
  112. }
  113. }
  114. user.AuthProvider = "ory"
  115. user.ExternalId = createdIdentity.Id
  116. _, err = u.Repo().User().UpdateUser(user)
  117. if err != nil {
  118. fmt.Printf("Error when updating user: %v\n", err)
  119. }
  120. spew.Dump(createdIdentity)
  121. }
  122. }