Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate user name to display name #1180

Draft
wants to merge 1 commit into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ func (r chatRoutes) handleReactTo(ctx tools.TUMLiveContext, msg []byte) {
return
}

err = r.ChatDao.ToggleReaction(ctx.User.ID, req.wsIdReq.Id, ctx.User.Name, req.Reaction)
err = r.ChatDao.ToggleReaction(ctx.User.ID, req.wsIdReq.Id, ctx.User.DisplayName, req.Reaction)
if err != nil {
log.WithError(err).Error("error reacting to message")
return
Expand Down
8 changes: 3 additions & 5 deletions api/courseimport.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import (
"errors"
"fmt"
campusonline "github.com/RBG-TUM/CAMPUSOnline"
"github.com/getsentry/sentry-go"
"github.com/gin-gonic/gin"
"github.com/TUM-Dev/gocast/model"
"github.com/TUM-Dev/gocast/tools"
"github.com/TUM-Dev/gocast/tools/tum"
"github.com/getsentry/sentry-go"
"github.com/gin-gonic/gin"
uuid "github.com/satori/go.uuid"
log "github.com/sirupsen/logrus"
"html/template"
Expand Down Expand Up @@ -118,15 +118,13 @@ func (r lectureHallRoutes) postSchedule(c *gin.Context) {
if !contact.MainContact {
continue
}
name := contact.FirstName + " " + contact.LastName
mail := contact.Email
user, err := tum.FindUserWithEmail(mail)
if err != nil || user == nil {
log.WithError(err).Errorf("can't find user %v", mail)
continue
}
time.Sleep(time.Millisecond * 200) // wait a bit, otherwise ldap locks us out
user.Name = name
user.Role = model.LecturerType
err = r.UsersDao.UpsertUser(user)
if err != nil {
Expand All @@ -140,7 +138,7 @@ func (r lectureHallRoutes) postSchedule(c *gin.Context) {
log.WithError(err).Error("can't add admin to course")
}
err := r.notifyCourseCreated(MailTmpl{
Name: user.Name,
Name: user.DisplayName,
Course: course,
Users: users,
OptIn: req.OptIn,
Expand Down
18 changes: 9 additions & 9 deletions api/courses.go
Original file line number Diff line number Diff line change
Expand Up @@ -667,9 +667,9 @@ func (r coursesRoutes) removeAdminFromCourse(c *gin.Context) {
return
}
c.JSON(http.StatusOK, userForLecturerDto{
ID: user.ID,
Name: user.Name,
Login: user.GetLoginString(),
ID: user.ID,
DisplayName: user.DisplayName,
Login: user.GetLoginString(),
})
}

Expand Down Expand Up @@ -727,9 +727,9 @@ func (r coursesRoutes) addAdminToCourse(c *gin.Context) {
}
}
c.JSON(http.StatusOK, userForLecturerDto{
ID: user.ID,
Name: user.Name,
Login: user.GetLoginString(),
ID: user.ID,
DisplayName: user.DisplayName,
Login: user.GetLoginString(),
})
}

Expand All @@ -744,9 +744,9 @@ func (r coursesRoutes) getAdmins(c *gin.Context) {
res := make([]userForLecturerDto, len(admins))
for i, admin := range admins {
res[i] = userForLecturerDto{
ID: admin.ID,
Name: admin.Name,
Login: admin.GetLoginString(),
ID: admin.ID,
DisplayName: admin.DisplayName,
Login: admin.GetLoginString(),
}
}
c.JSON(http.StatusOK, res)
Expand Down
63 changes: 30 additions & 33 deletions api/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import (
"strings"
"time"

"github.com/getsentry/sentry-go"
"github.com/gin-gonic/gin"
"github.com/TUM-Dev/gocast/dao"
"github.com/TUM-Dev/gocast/model"
"github.com/TUM-Dev/gocast/tools"
"github.com/getsentry/sentry-go"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"gorm.io/gorm"
)
Expand Down Expand Up @@ -155,10 +155,9 @@ func (r usersRoutes) SearchUserForCourse(c *gin.Context) {

for i, user := range users {
res[i] = userForLecturerDto{
ID: user.ID,
Name: user.GetPreferredName(),
LastName: user.LastName,
Login: user.GetLoginString(),
ID: user.ID,
DisplayName: user.GetPreferredName(),
Login: user.GetLoginString(),
}
}
c.JSON(http.StatusOK, res)
Expand Down Expand Up @@ -188,10 +187,9 @@ func (r usersRoutes) SearchUser(c *gin.Context) {
}

type userForLecturerDto struct {
ID uint `json:"id,omitempty"`
Name string `json:"name,omitempty"`
LastName *string `json:"lastName,omitempty"`
Login string `json:"login,omitempty"`
ID uint `json:"id,omitempty"`
DisplayName string `json:"name,omitempty"`
Login string `json:"login,omitempty"`
}

type userSearchDTO struct {
Expand Down Expand Up @@ -297,11 +295,11 @@ func (r usersRoutes) addSingleUserToCourse(name string, email string, course mod
if foundUser, err := r.UsersDao.GetUserByEmail(context.Background(), email); err != nil {
// user not in database yet. Create them & send registration link
createdUser := model.User{
Name: name,
Email: sql.NullString{String: email, Valid: true},
Role: model.GenericType,
Password: "",
Courses: []model.Course{course},
DisplayName: name,
Email: sql.NullString{String: email, Valid: true},
Role: model.GenericType,
Password: "",
Courses: []model.Course{course},
}
if err = r.UsersDao.CreateUser(context.Background(), &createdUser); err != nil {
log.Printf("%v", err)
Expand Down Expand Up @@ -440,7 +438,7 @@ func (r usersRoutes) InitUser(c *gin.Context) {
})
return
}
c.JSON(http.StatusOK, createUserResponse{Name: createdUser.Name, Email: createdUser.Email.String, Role: createdUser.Role})
c.JSON(http.StatusOK, createUserResponse{Name: createdUser.DisplayName, Email: createdUser.Email.String, Role: createdUser.Role})
}

func (r usersRoutes) CreateUser(c *gin.Context) {
Expand Down Expand Up @@ -480,14 +478,14 @@ func (r usersRoutes) CreateUser(c *gin.Context) {
})
return
}
c.JSON(http.StatusOK, createUserResponse{Name: createdUser.Name, Email: createdUser.Email.String, Role: createdUser.Role})
c.JSON(http.StatusOK, createUserResponse{Name: createdUser.DisplayName, Email: createdUser.Email.String, Role: createdUser.Role})
}

func (r usersRoutes) createUserHelper(request createUserRequest, userType uint) (user model.User, err error) {
var u = model.User{
Name: request.Name,
Email: sql.NullString{String: request.Email, Valid: true},
Role: userType,
DisplayName: request.Name,
Email: sql.NullString{String: request.Email, Valid: true},
Role: userType,
}
if userType == 1 {
err = u.SetPassword(request.Password)
Expand Down Expand Up @@ -516,6 +514,7 @@ func (r usersRoutes) forgotPassword(email string) {
log.Println("couldn't create register link")
return
}
// todo: this should be a template file
body := fmt.Sprintf("Hello!\n"+
"You have been invited to use TUM-Live. You can set a password for your account here: https://live.rbg.tum.de/setPassword/%v\n"+
"After setting a password you can log in with the email this message was sent to. Please note that this is not your TUMOnline account.\n"+
Expand Down Expand Up @@ -660,13 +659,12 @@ func (r usersRoutes) exportPersonalData(c *gin.Context) {
var resp personalData
u := c.MustGet("TUMLiveContext").(tools.TUMLiveContext).User
resp.UserData = struct {
Name string `json:"name,omitempty"`
LastName *string `json:"last_name,omitempty"`
Email string `json:"email,omitempty"`
LrzID string `json:"lrz_id,omitempty"`
MatrNr string `json:"matr_nr,omitempty"`
CreatedAt time.Time `json:"created_at"`
}{Name: u.Name, LastName: u.LastName, Email: u.Email.String, LrzID: u.LrzID, MatrNr: u.MatriculationNumber, CreatedAt: u.CreatedAt}
DisplayName string `json:"display_name,omitempty"`
Email string `json:"email,omitempty"`
LrzID string `json:"lrz_id,omitempty"`
MatrNr string `json:"matr_nr,omitempty"`
CreatedAt time.Time `json:"created_at"`
}{DisplayName: u.DisplayName, Email: u.Email.String, LrzID: u.LrzID, MatrNr: u.MatriculationNumber, CreatedAt: u.CreatedAt}
for _, course := range u.Courses {
resp.Enrollments = append(resp.Enrollments, struct {
Year int `json:"year,omitempty"`
Expand Down Expand Up @@ -757,12 +755,11 @@ func (r usersRoutes) resetPassword(c *gin.Context) {

type personalData struct {
UserData struct {
Name string `json:"name,omitempty"`
LastName *string `json:"last_name,omitempty"`
Email string `json:"email,omitempty"`
LrzID string `json:"lrz_id,omitempty"`
MatrNr string `json:"matr_nr,omitempty"`
CreatedAt time.Time `json:"created_at"`
DisplayName string `json:"display_name,omitempty"`
Email string `json:"email,omitempty"`
LrzID string `json:"lrz_id,omitempty"`
MatrNr string `json:"matr_nr,omitempty"`
CreatedAt time.Time `json:"created_at"`
} `json:"user_data"`
Enrollments []struct {
Year int `json:"year,omitempty"`
Expand Down
24 changes: 24 additions & 0 deletions dao/migrations/202310010.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package migrations

import (
"github.com/TUM-Dev/gocast/model"
"github.com/go-gormigrate/gormigrate/v2"
"gorm.io/gorm"
)

// Migrate202310010 Adds the content of "name" to "display_name" and Drops the column "name".
func Migrate202310010() *gormigrate.Migration {
return &gormigrate.Migration{
ID: "202310010",
Migrate: func(tx *gorm.DB) error {
m := tx.Migrator()
if m.HasColumn(&model.User{}, "name") {
tx.Exec("UPDATE users SET display_name = name WHERE 1")
}
return m.DropColumn(&model.User{}, "name")
},
Rollback: func(tx *gorm.DB) error {
return nil
},
}
}
3 changes: 2 additions & 1 deletion dao/migrator.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package dao

import (
"github.com/go-gormigrate/gormigrate/v2"
"github.com/TUM-Dev/gocast/dao/migrations"
"github.com/go-gormigrate/gormigrate/v2"
"gorm.io/gorm"
)

Expand Down Expand Up @@ -38,6 +38,7 @@ func newMigrator() *migrator {
migrations.Migrate202212010(),
migrations.Migrate202212020(),
migrations.Migrate202301006(),
migrations.Migrate202310010(),
},
}
}
4 changes: 2 additions & 2 deletions dao/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func (d usersDao) UpsertUser(user *model.User) error {
//User found: update
user.Model = foundUser.Model
foundUser.LrzID = user.LrzID
foundUser.Name = user.Name
foundUser.DisplayName = user.DisplayName
if user.Role != 0 {
foundUser.Role = user.Role
}
Expand All @@ -175,7 +175,7 @@ func (d usersDao) UpsertUser(user *model.User) error {
err = DB.
Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "matriculation_number"}},
DoUpdates: clause.Assignments(map[string]interface{}{"name": user.Name}),
DoUpdates: clause.Assignments(map[string]interface{}{"display_name": user.DisplayName}),
}).
Create(&user).Error
return err
Expand Down
32 changes: 17 additions & 15 deletions model/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,16 @@ const (
LecturerType = 2
GenericType = 3
StudentType = 4

maxUsernameLength = 80
)

var (
ErrUsernameTooLong = errors.New("username is too long")
ErrUsernameNoText = errors.New("username has no text")
ErrUsernameNoText = errors.New("username has no text")
)

type User struct {
gorm.Model

Name string `gorm:"type:varchar(80); not null" json:"name"`
LastName *string `json:"-"`
DisplayName string `gorm:"type:varchar(256); not null" json:"name"`
Email sql.NullString `gorm:"type:varchar(256); uniqueIndex; default:null" json:"-"`
MatriculationNumber string `gorm:"type:varchar(256); uniqueIndex; default:null" json:"-"`
LrzID string `json:"-"`
Expand Down Expand Up @@ -65,13 +61,16 @@ type UserSetting struct {
}

// GetPreferredName returns the preferred name of the user if set, otherwise the firstName from TUMOnline
func (u User) GetPreferredName() string {
func (u *User) GetPreferredName() string {
if u == nil {
return ""
}
for _, setting := range u.Settings {
if setting.Type == PreferredName {
return setting.Value
}
}
return u.Name
return u.DisplayName
}

type PlaybackSpeedSetting struct {
Expand Down Expand Up @@ -121,7 +120,10 @@ func (u *User) GetPlaybackSpeeds() (speeds PlaybackSpeedSettings) {
}

// GetPreferredGreeting returns the preferred greeting of the user if set, otherwise Moin
func (u User) GetPreferredGreeting() string {
func (u *User) GetPreferredGreeting() string {
if u == nil {
return "Moin"
}
for _, setting := range u.Settings {
if setting.Type == Greeting {
return setting.Value
Expand All @@ -131,7 +133,10 @@ func (u User) GetPreferredGreeting() string {
}

// PreferredNameChangeAllowed returns false if the user has set a preferred name within the last 3 months, otherwise true
func (u User) PreferredNameChangeAllowed() bool {
func (u *User) PreferredNameChangeAllowed() bool {
if u == nil {
return false
}
for _, setting := range u.Settings {
if setting.Type == PreferredName && time.Since(setting.UpdatedAt) < time.Hour*24*30*3 {
return false
Expand Down Expand Up @@ -322,11 +327,8 @@ func (u *User) GetLoginString() string {
// - username is empty (after trimming)
// - username is too long (>maxUsernameLength)
func (u *User) BeforeCreate(tx *gorm.DB) (err error) {
u.Name = strings.TrimSpace(u.Name)
if len(u.Name) > maxUsernameLength {
return ErrUsernameTooLong
}
if len(u.Name) == 0 {
u.DisplayName = strings.TrimSpace(u.DisplayName)
if len(u.DisplayName) == 0 {
return ErrUsernameNoText
}
return nil
Expand Down
13 changes: 5 additions & 8 deletions tools/bot/bot.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package bot

import (
"github.com/getsentry/sentry-go"
"github.com/TUM-Dev/gocast/dao"
"github.com/TUM-Dev/gocast/model"
"github.com/getsentry/sentry-go"
"github.com/microcosm-cc/bluemonday"
log "github.com/sirupsen/logrus"
"strings"
Expand Down Expand Up @@ -101,13 +101,10 @@ func GenerateInfoText(botInfo AlertMessage) string {
infoText += "</table>📢 <b>Contact information</b>\n\n<table>"
// Has the person that reported the issue entered custom contact data?
if botInfo.Name != "" {
infoText += "<tr><th>Name</th><td>" + botInfo.User.Name + "</td></tr>"
} else if botInfo.User.Name != "" {
if botInfo.User.LastName != nil {
infoText += "<tr><th>Name</th><td>" + botInfo.User.Name + " " + *botInfo.User.LastName + "</td></tr>"
} else {
infoText += "<tr><th>Name</th><td>" + botInfo.User.Name + "</td></tr>"
}
infoText += "<tr><th>Name</th><td>" + botInfo.User.DisplayName + "</td></tr>"
} else if botInfo.User.DisplayName != "" {
infoText += "<tr><th>Name</th><td>" + botInfo.User.DisplayName + "</td></tr>"

}
if botInfo.Email != "" {
infoText += "<tr><th>Email</th><td>" + botInfo.Email + "</td></tr>"
Expand Down
Loading
Loading