| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | /* | 
					
						
							|  |  |  |    GoToSocial | 
					
						
							| 
									
										
										
										
											2021-12-20 18:42:19 +01:00
										 |  |  |    Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |    This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |    it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  |    the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |    (at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |    GNU Affero General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |    along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | package bundb | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"crypto/rand" | 
					
						
							|  |  |  | 	"crypto/rsa" | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	"database/sql" | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"net" | 
					
						
							|  |  |  | 	"net/mail" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/ap" | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/config" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/db" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/id" | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/log" | 
					
						
							| 
									
										
										
										
											2021-12-20 15:19:53 +01:00
										 |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/uris" | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	"golang.org/x/crypto/bcrypt" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type adminDB struct { | 
					
						
							| 
									
										
										
										
											2021-12-07 13:31:39 +01:00
										 |  |  | 	conn *DBConn | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (a *adminDB) IsUsernameAvailable(ctx context.Context, username string) (bool, db.Error) { | 
					
						
							|  |  |  | 	q := a.conn. | 
					
						
							|  |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(>smodel.Account{}). | 
					
						
							|  |  |  | 		Where("username = ?", username). | 
					
						
							|  |  |  | 		Where("domain = ?", nil) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	return a.conn.NotExists(ctx, q) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (a *adminDB) IsEmailAvailable(ctx context.Context, email string) (bool, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	// parse the domain from the email | 
					
						
							|  |  |  | 	m, err := mail.ParseAddress(email) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		return false, fmt.Errorf("error parsing email address %s: %s", email, err) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	domain := strings.Split(m.Address, "@")[1] // domain will always be the second part after @ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// check if the email domain is blocked | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	if err := a.conn. | 
					
						
							|  |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(>smodel.EmailDomainBlock{}). | 
					
						
							|  |  |  | 		Where("domain = ?", domain). | 
					
						
							|  |  |  | 		Scan(ctx); err == nil { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		// fail because we found something | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		return false, fmt.Errorf("email domain %s is blocked", domain) | 
					
						
							|  |  |  | 	} else if err != sql.ErrNoRows { | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 		return false, a.conn.ProcessError(err) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// check if this email is associated with a user already | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	q := a.conn. | 
					
						
							|  |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(>smodel.User{}). | 
					
						
							|  |  |  | 		Where("email = ?", email). | 
					
						
							|  |  |  | 		WhereOr("unconfirmed_email = ?", email) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	return a.conn.NotExists(ctx, q) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (a *adminDB) NewSignup(ctx context.Context, username string, reason string, requireApproval bool, email string, password string, signUpIP net.IP, locale string, appID string, emailVerified bool, admin bool) (*gtsmodel.User, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	key, err := rsa.GenerateKey(rand.Reader, 2048) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 		log.Errorf("error creating new rsa key: %s", err) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// if something went wrong while creating a user, we might already have an account, so check here first... | 
					
						
							|  |  |  | 	acct := >smodel.Account{} | 
					
						
							| 
									
										
										
										
											2022-01-31 16:03:47 +01:00
										 |  |  | 	q := a.conn.NewSelect(). | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		Model(acct). | 
					
						
							|  |  |  | 		Where("username = ?", username). | 
					
						
							| 
									
										
										
										
											2022-01-31 16:03:47 +01:00
										 |  |  | 		WhereGroup(" AND ", whereEmptyOrNull("domain")) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := q.Scan(ctx); err != nil { | 
					
						
							|  |  |  | 		// we just don't have an account yet so create one before we proceed | 
					
						
							| 
									
										
										
										
											2021-12-20 15:19:53 +01:00
										 |  |  | 		accountURIs := uris.GenerateURIsForAccount(username) | 
					
						
							|  |  |  | 		accountID, err := id.NewRandomULID() | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		acct = >smodel.Account{ | 
					
						
							| 
									
										
										
										
											2021-12-20 15:19:53 +01:00
										 |  |  | 			ID:                    accountID, | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 			Username:              username, | 
					
						
							|  |  |  | 			DisplayName:           username, | 
					
						
							|  |  |  | 			Reason:                reason, | 
					
						
							| 
									
										
										
										
											2021-09-13 17:35:33 +02:00
										 |  |  | 			Privacy:               gtsmodel.VisibilityDefault, | 
					
						
							| 
									
										
										
										
											2021-12-20 15:19:53 +01:00
										 |  |  | 			URL:                   accountURIs.UserURL, | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 			PrivateKey:            key, | 
					
						
							|  |  |  | 			PublicKey:             &key.PublicKey, | 
					
						
							| 
									
										
										
										
											2021-12-20 15:19:53 +01:00
										 |  |  | 			PublicKeyURI:          accountURIs.PublicKeyURI, | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 			ActorType:             ap.ActorPerson, | 
					
						
							| 
									
										
										
										
											2021-12-20 15:19:53 +01:00
										 |  |  | 			URI:                   accountURIs.UserURI, | 
					
						
							|  |  |  | 			InboxURI:              accountURIs.InboxURI, | 
					
						
							|  |  |  | 			OutboxURI:             accountURIs.OutboxURI, | 
					
						
							|  |  |  | 			FollowersURI:          accountURIs.FollowersURI, | 
					
						
							|  |  |  | 			FollowingURI:          accountURIs.FollowingURI, | 
					
						
							|  |  |  | 			FeaturedCollectionURI: accountURIs.CollectionURI, | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2022-01-31 16:03:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		if _, err = a.conn. | 
					
						
							|  |  |  | 			NewInsert(). | 
					
						
							|  |  |  | 			Model(acct). | 
					
						
							|  |  |  | 			Exec(ctx); err != nil { | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 			return nil, a.conn.ProcessError(err) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pw, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("error hashing password: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	newUserID, err := id.NewRandomULID() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-15 12:35:05 +02:00
										 |  |  | 	// if we don't require moderator approval, just pre-approve the user | 
					
						
							|  |  |  | 	approved := !requireApproval | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	u := >smodel.User{ | 
					
						
							|  |  |  | 		ID:                     newUserID, | 
					
						
							|  |  |  | 		AccountID:              acct.ID, | 
					
						
							| 
									
										
										
										
											2021-10-31 15:46:23 +01:00
										 |  |  | 		Account:                acct, | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		EncryptedPassword:      string(pw), | 
					
						
							|  |  |  | 		SignUpIP:               signUpIP.To4(), | 
					
						
							|  |  |  | 		Locale:                 locale, | 
					
						
							|  |  |  | 		UnconfirmedEmail:       email, | 
					
						
							|  |  |  | 		CreatedByApplicationID: appID, | 
					
						
							| 
									
										
										
										
											2022-08-15 12:35:05 +02:00
										 |  |  | 		Approved:               &approved, | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if emailVerified { | 
					
						
							|  |  |  | 		u.ConfirmedAt = time.Now() | 
					
						
							|  |  |  | 		u.Email = email | 
					
						
							| 
									
										
										
										
											2022-01-31 16:03:47 +01:00
										 |  |  | 		u.UnconfirmedEmail = "" | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if admin { | 
					
						
							| 
									
										
										
										
											2022-08-15 12:35:05 +02:00
										 |  |  | 		admin := true | 
					
						
							|  |  |  | 		moderator := true | 
					
						
							|  |  |  | 		u.Admin = &admin | 
					
						
							|  |  |  | 		u.Moderator = &moderator | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	if _, err = a.conn. | 
					
						
							|  |  |  | 		NewInsert(). | 
					
						
							|  |  |  | 		Model(u). | 
					
						
							|  |  |  | 		Exec(ctx); err != nil { | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 		return nil, a.conn.ProcessError(err) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return u, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (a *adminDB) CreateInstanceAccount(ctx context.Context) db.Error { | 
					
						
							| 
									
										
										
										
											2022-05-30 13:41:24 +01:00
										 |  |  | 	username := config.GetHost() | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 13:40:09 +01:00
										 |  |  | 	q := a.conn. | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(>smodel.Account{}). | 
					
						
							|  |  |  | 		Where("username = ?", username). | 
					
						
							| 
									
										
										
										
											2021-08-26 11:28:16 +02:00
										 |  |  | 		WhereGroup(" AND ", whereEmptyOrNull("domain")) | 
					
						
							| 
									
										
										
										
											2021-11-17 13:40:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	exists, err := a.conn.Exists(ctx, q) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if exists { | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 		log.Infof("instance account %s already exists", username) | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	key, err := rsa.GenerateKey(rand.Reader, 2048) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 		log.Errorf("error creating new rsa key: %s", err) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	aID, err := id.NewRandomULID() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-20 15:19:53 +01:00
										 |  |  | 	newAccountURIs := uris.GenerateURIsForAccount(username) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	acct := >smodel.Account{ | 
					
						
							|  |  |  | 		ID:                    aID, | 
					
						
							| 
									
										
										
										
											2021-12-07 13:31:39 +01:00
										 |  |  | 		Username:              username, | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		DisplayName:           username, | 
					
						
							|  |  |  | 		URL:                   newAccountURIs.UserURL, | 
					
						
							|  |  |  | 		PrivateKey:            key, | 
					
						
							|  |  |  | 		PublicKey:             &key.PublicKey, | 
					
						
							|  |  |  | 		PublicKeyURI:          newAccountURIs.PublicKeyURI, | 
					
						
							| 
									
										
										
										
											2021-08-31 15:59:12 +02:00
										 |  |  | 		ActorType:             ap.ActorPerson, | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		URI:                   newAccountURIs.UserURI, | 
					
						
							|  |  |  | 		InboxURI:              newAccountURIs.InboxURI, | 
					
						
							|  |  |  | 		OutboxURI:             newAccountURIs.OutboxURI, | 
					
						
							|  |  |  | 		FollowersURI:          newAccountURIs.FollowersURI, | 
					
						
							|  |  |  | 		FollowingURI:          newAccountURIs.FollowingURI, | 
					
						
							|  |  |  | 		FeaturedCollectionURI: newAccountURIs.CollectionURI, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	insertQ := a.conn. | 
					
						
							|  |  |  | 		NewInsert(). | 
					
						
							|  |  |  | 		Model(acct) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if _, err := insertQ.Exec(ctx); err != nil { | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 		return a.conn.ProcessError(err) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 	log.Infof("instance account %s CREATED with id %s", username, acct.ID) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (a *adminDB) CreateInstanceInstance(ctx context.Context) db.Error { | 
					
						
							| 
									
										
										
										
											2022-05-30 13:41:24 +01:00
										 |  |  | 	protocol := config.GetProtocol() | 
					
						
							|  |  |  | 	host := config.GetHost() | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// check if instance entry already exists | 
					
						
							| 
									
										
										
										
											2021-08-26 17:22:41 +02:00
										 |  |  | 	q := a.conn. | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(>smodel.Instance{}). | 
					
						
							| 
									
										
										
										
											2021-12-07 13:31:39 +01:00
										 |  |  | 		Where("domain = ?", host) | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	exists, err := a.conn.Exists(ctx, q) | 
					
						
							| 
									
										
										
										
											2021-08-26 17:22:41 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if exists { | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 		log.Infof("instance entry already exists") | 
					
						
							| 
									
										
										
										
											2021-08-26 17:46:24 +02:00
										 |  |  | 		return nil | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	iID, err := id.NewRandomULID() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	i := >smodel.Instance{ | 
					
						
							|  |  |  | 		ID:     iID, | 
					
						
							| 
									
										
										
										
											2021-12-07 13:31:39 +01:00
										 |  |  | 		Domain: host, | 
					
						
							|  |  |  | 		Title:  host, | 
					
						
							|  |  |  | 		URI:    fmt.Sprintf("%s://%s", protocol, host), | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	insertQ := a.conn. | 
					
						
							|  |  |  | 		NewInsert(). | 
					
						
							|  |  |  | 		Model(i) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-26 17:22:41 +02:00
										 |  |  | 	_, err = insertQ.Exec(ctx) | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return a.conn.ProcessError(err) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-19 09:47:55 +01:00
										 |  |  | 	log.Infof("created instance instance %s with id %s", host, i.ID) | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } |