Grab info from the Discord user's HMN membership

and turn showcase back on
This commit is contained in:
Ben Visness 2023-05-05 21:46:59 -05:00
parent a826f1918e
commit a95bb8cfbe
5 changed files with 40 additions and 73 deletions

View File

@ -388,8 +388,9 @@ func GuildFromMap(m interface{}, k string) *Guild {
// https://discord.com/developers/docs/resources/guild#guild-member-object
type GuildMember struct {
User *User `json:"user"`
Nick *string `json:"nick"`
User *User `json:"user"`
Nick *string `json:"nick"`
Avatar *string `json:"avatar"`
// more fields not yet handled here
}
@ -410,8 +411,9 @@ func GuildMemberFromMap(m interface{}, k string) *GuildMember {
}
gm := &GuildMember{
User: UserFromMap(m, "user"),
Nick: maybeStringP(mmap, "nick"),
User: UserFromMap(m, "user"),
Nick: maybeStringP(mmap, "nick"),
Avatar: maybeStringP(mmap, "avatar"),
}
return gm

View File

@ -1,51 +0,0 @@
package migrations
import (
"context"
"time"
"git.handmade.network/hmn/hmn/src/migration/types"
"github.com/jackc/pgx/v5"
)
func init() {
registerMigration(NoDefaultDiscordShowcase{})
}
type NoDefaultDiscordShowcase struct{}
func (m NoDefaultDiscordShowcase) Version() types.MigrationVersion {
return types.MigrationVersion(time.Date(2023, 5, 5, 0, 32, 8, 0, time.UTC))
}
func (m NoDefaultDiscordShowcase) Name() string {
return "NoDefaultDiscordShowcase"
}
func (m NoDefaultDiscordShowcase) Description() string {
return "Make the Discord showcase setting default to false"
}
func (m NoDefaultDiscordShowcase) Up(ctx context.Context, tx pgx.Tx) error {
_, err := tx.Exec(ctx, `
ALTER TABLE hmn_user
ALTER COLUMN discord_save_showcase SET DEFAULT FALSE
`)
if err != nil {
return err
}
return nil
}
func (m NoDefaultDiscordShowcase) Down(ctx context.Context, tx pgx.Tx) error {
_, err := tx.Exec(ctx, `
ALTER TABLE hmn_user
ALTER COLUMN discord_save_showcase SET DEFAULT TRUE
`)
if err != nil {
return err
}
return nil
}

View File

@ -180,8 +180,7 @@ func seedUser(ctx context.Context, conn db.ConnOrTx, input models.User) *models.
name, bio, blurb, signature,
darktheme,
showemail,
date_joined, registration_ip, avatar_asset_id,
discord_save_showcase
date_joined, registration_ip, avatar_asset_id
)
VALUES (
$1, $2, $3,
@ -190,8 +189,7 @@ func seedUser(ctx context.Context, conn db.ConnOrTx, input models.User) *models.
$6, $7, $8, $9,
TRUE,
$10,
'2017-01-01T00:00:00Z', '192.168.2.1', NULL,
TRUE
'2017-01-01T00:00:00Z', '192.168.2.1', NULL
)
RETURNING $columns
`,

View File

@ -269,13 +269,8 @@ func RegisterNewUserSubmit(c *RequestContext) ResponseData {
var newUserId int
err = tx.QueryRow(c,
`
INSERT INTO hmn_user (
username, email, password, date_joined, name, registration_ip,
discord_save_showcase
) VALUES (
$1, $2, $3, $4, $5, $6,
TRUE
)
INSERT INTO hmn_user (username, email, password, date_joined, name, registration_ip)
VALUES ($1, $2, $3, $4, $5, $6)
RETURNING id
`,
username, emailAddress, hashed.String(), now, displayName, c.GetIP(),

View File

@ -128,6 +128,15 @@ func DiscordOAuthCallback(c *RequestContext) ResponseData {
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to fetch Discord user info"))
}
hmnMember, err := discord.GetGuildMember(c, config.Config.Discord.GuildID, user.ID)
if err != nil {
if err == discord.NotFound {
// nothing, this is fine
} else {
c.Logger.Error().Err(err).Msg("failed to get HMN Discord member for Discord user")
}
}
// Make the necessary updates in our database (see table above)
// Determine which HMN user to associate this Discord login with. This
@ -197,8 +206,20 @@ func DiscordOAuthCallback(c *RequestContext) ResponseData {
return c.RejectRequest(fmt.Sprintf("There is already a Handmade Network account with the username \"%s\".", user.Username))
}
var displayName string
if hmnMember != nil && hmnMember.Nick != nil {
displayName = *hmnMember.Nick
}
var avatarHash *string
if hmnMember != nil && hmnMember.Avatar != nil {
avatarHash = hmnMember.Avatar
} else if user.Avatar != nil {
avatarHash = user.Avatar
}
var avatarAssetID *uuid.UUID
if user.Avatar != nil {
if avatarHash != nil {
// Note! Not using the transaction here. Don't want to fail the login due to avatars.
if avatarAsset, err := saveDiscordAvatar(c, c.Conn, user.ID, *user.Avatar); err == nil {
avatarAssetID = &avatarAsset.ID
@ -210,13 +231,13 @@ func DiscordOAuthCallback(c *RequestContext) ResponseData {
newHMNUser, err := db.QueryOne[models.User](c, tx,
`
INSERT INTO hmn_user (
username, email, password, avatar_asset_id, date_joined, registration_ip
username, name, email, password, avatar_asset_id, date_joined, registration_ip
) VALUES (
$1, $2, '', $3, $4, $5
$1, $2, $3, '', $4, $5, $6
)
RETURNING $columns
`,
user.Username, strings.ToLower(user.Email), avatarAssetID, time.Now(), c.GetIP(),
user.Username, displayName, strings.ToLower(user.Email), avatarAssetID, time.Now(), c.GetIP(),
)
if err != nil {
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to create new HMN user for Discord login"))
@ -275,9 +296,11 @@ func DiscordOAuthCallback(c *RequestContext) ResponseData {
}
// Add the role on Discord
err = discord.AddGuildMemberRole(c, user.ID, config.Config.Discord.MemberRoleID)
if err != nil {
return c.ErrorResponse(http.StatusInternalServerError, oops.New(err, "failed to add member role"))
if hmnMember != nil {
err = discord.AddGuildMemberRole(c, user.ID, config.Config.Discord.MemberRoleID)
if err != nil {
c.Logger.Error().Err(err).Msg("failed to add member role")
}
}
res := c.Redirect(destinationUrl, http.StatusSeeOther)