user invitations
This commit is contained in:
parent
aa6e183dac
commit
82e9e65565
|
@ -45,11 +45,16 @@ type Mail struct {
|
|||
|
||||
func (m Mail) buildMessage(s Service) []byte {
|
||||
var buf bytes.Buffer
|
||||
|
||||
buf.WriteString("To: ")
|
||||
buf.WriteString(m.To)
|
||||
buf.WriteString("\r\n")
|
||||
buf.WriteString("Subject: ")
|
||||
buf.WriteString(s.SubjectPrefix)
|
||||
|
||||
if len(s.SubjectPrefix) > 0 {
|
||||
buf.WriteString(fmt.Sprintf("%s%s%s", "[", s.SubjectPrefix, "] "))
|
||||
}
|
||||
|
||||
buf.WriteString(m.Subject)
|
||||
buf.WriteString("\r\n")
|
||||
buf.WriteString(m.Body)
|
||||
|
|
|
@ -157,15 +157,21 @@ func ActivateAccountPostHandler(ctx *middleware.AppContext, w http.ResponseWrite
|
|||
user.Password = []byte(password)
|
||||
user.Active = true
|
||||
|
||||
_, err = ctx.UserService.CreateUser(user)
|
||||
|
||||
if err != nil {
|
||||
if _, err := ctx.UserService.CreateUser(user); err != nil {
|
||||
return &middleware.Template{
|
||||
Name: tplAdminActivateAccount,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
if err := ctx.UserInviteService.RemoveInvite(ui.ID); err != nil {
|
||||
return &middleware.Template{
|
||||
Name: tplAdminUserDelete,
|
||||
Active: "users",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
return &middleware.Template{
|
||||
RedirectPath: "admin",
|
||||
SuccessMsg: "The account was successfully activated. You can now log in.",
|
||||
|
|
|
@ -56,6 +56,43 @@ func AdminUserInviteNewPostHandler(ctx *middleware.AppContext, w http.ResponseWr
|
|||
}
|
||||
}
|
||||
|
||||
func AdminUserInviteResendPostHandler(ctx *middleware.AppContext, w http.ResponseWriter, r *http.Request) *middleware.Template {
|
||||
inviteID, err := parseInt(getVar(r, "inviteID"))
|
||||
|
||||
if err != nil {
|
||||
return &middleware.Template{
|
||||
RedirectPath: "admin/user-invite",
|
||||
Active: "users",
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
ui, err := ctx.UserInviteService.GetInvite(inviteID)
|
||||
|
||||
if err != nil {
|
||||
return &middleware.Template{
|
||||
Name: tplAdminUsers,
|
||||
Err: err,
|
||||
Active: "users",
|
||||
}
|
||||
}
|
||||
|
||||
err = ctx.Mailer.SendActivationLink(ui)
|
||||
|
||||
if err != nil {
|
||||
logger.Log.Error(err)
|
||||
}
|
||||
|
||||
return &middleware.Template{
|
||||
RedirectPath: "admin/users",
|
||||
Active: "users",
|
||||
SuccessMsg: "Successfully invited user " + ui.Email,
|
||||
Data: map[string]interface{}{
|
||||
"userID": inviteID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func AdminUserInviteDeleteHandler(ctx *middleware.AppContext, w http.ResponseWriter, r *http.Request) *middleware.Template {
|
||||
inviteID, err := parseInt(getVar(r, "inviteID"))
|
||||
|
|
@ -42,7 +42,7 @@ blog_articles_per_page = 20
|
|||
blog_rss_feed_items = 10
|
||||
|
||||
# mail server server
|
||||
mail_smtp_address =
|
||||
mail_smtp_host =
|
||||
mail_smtp_port =
|
||||
mail_smtp_user =
|
||||
mail_smtp_password =
|
||||
|
|
|
@ -19,7 +19,7 @@ func (m Mailer) SendActivationLink(ui *UserInvite) error {
|
|||
mail := mail.Mail{
|
||||
To: ui.Email,
|
||||
Subject: "Password change",
|
||||
Body: fmt.Sprintf("Hi %s, \n\n you are invited join %s. Please click the following link to enter a password and activate your account: %s", ui.DisplayName, m.AppConfig.Title, activation),
|
||||
Body: fmt.Sprintf("Hi %s, \n\n you are invited join %s. To activate your account click the following link and enter a password %s", ui.DisplayName, m.AppConfig.Title, activation),
|
||||
}
|
||||
|
||||
return m.MailService.SendAsync(mail)
|
||||
|
|
|
@ -35,6 +35,7 @@ type UserInviteDatasourceService interface {
|
|||
Get(inviteID int) (*UserInvite, error)
|
||||
GetByHash(hash string) (*UserInvite, error)
|
||||
Create(ui *UserInvite) (int, error)
|
||||
Update(ui *UserInvite) error
|
||||
Remove(inviteID int) error
|
||||
}
|
||||
|
||||
|
@ -62,8 +63,14 @@ func (uis UserInviteService) ListUserInvites() ([]UserInvite, error) {
|
|||
return uis.Datasource.List()
|
||||
}
|
||||
|
||||
func (uis UserInviteService) ResendUserInvites() ([]UserInvite, error) {
|
||||
return uis.Datasource.List()
|
||||
func (uis UserInviteService) UpdateUserInvites(ui *UserInvite) error {
|
||||
ui.Hash = utils.RandomHash(32)
|
||||
|
||||
if err := ui.validate(uis); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return uis.Datasource.Update(ui)
|
||||
}
|
||||
|
||||
func (uis UserInviteService) CreateUserInvite(ui *UserInvite) (int, error) {
|
||||
|
|
|
@ -54,13 +54,13 @@ func (rdb SQLiteUserInviteDatasource) Get(inviteID int) (*UserInvite, error) {
|
|||
var u User
|
||||
var ui UserInvite
|
||||
|
||||
if err := rdb.SQLConn.QueryRow("SELECT ui.rowid, ui.username, ui.email, ui.display_name, ui.created_at, ui.is_admin, "+
|
||||
if err := rdb.SQLConn.QueryRow("SELECT ui.rowid, ui.hash, ui.username, ui.email, ui.display_name, ui.created_at, ui.is_admin, "+
|
||||
"u.rowid, u.username, u.email, u.display_name "+
|
||||
"FROM user_invite as ui "+
|
||||
"INNER JOIN user as u "+
|
||||
"ON u.rowid = ui.created_by "+
|
||||
"WHERE ui.rowid=? ", inviteID).
|
||||
Scan(&ui.ID, &ui.Username, &ui.Email, &ui.DisplayName, &ui.CreatedAt, &ui.IsAdmin, &u.ID, &u.Username, &u.Email, &u.DisplayName); err != nil {
|
||||
Scan(&ui.ID, &ui.Hash, &ui.Username, &ui.Email, &ui.DisplayName, &ui.CreatedAt, &ui.IsAdmin, &u.ID, &u.Username, &u.Email, &u.DisplayName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -73,13 +73,13 @@ func (rdb SQLiteUserInviteDatasource) GetByHash(hash string) (*UserInvite, error
|
|||
var ui UserInvite
|
||||
var u User
|
||||
|
||||
if err := rdb.SQLConn.QueryRow("SELECT ui.rowid, ui.username, ui.email, ui.display_name, ui.created_at, ui.is_admin, "+
|
||||
if err := rdb.SQLConn.QueryRow("SELECT ui.rowid, ui.hash, ui.username, ui.email, ui.display_name, ui.created_at, ui.is_admin, "+
|
||||
"u.rowid, u.username, u.email, u.display_name "+
|
||||
"FROM user_invite as ui "+
|
||||
"INNER JOIN user as u "+
|
||||
"ON u.rowid = ui.created_by "+
|
||||
"WHERE ui.hash=? ", hash).
|
||||
Scan(&ui.ID, &ui.Username, &ui.Email, &ui.DisplayName, &ui.CreatedAt, &ui.IsAdmin, &u.ID, &u.Username, &u.Email, &u.DisplayName); err != nil {
|
||||
Scan(&ui.ID, &ui.Hash, &ui.Username, &ui.Email, &ui.DisplayName, &ui.CreatedAt, &ui.IsAdmin, &u.ID, &u.Username, &u.Email, &u.DisplayName); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,16 @@ func (rdb SQLiteUserInviteDatasource) GetByHash(hash string) (*UserInvite, error
|
|||
return &ui, nil
|
||||
}
|
||||
|
||||
//Create creates an new user
|
||||
func (rdb SQLiteUserInviteDatasource) Update(ui *UserInvite) error {
|
||||
if _, err := rdb.SQLConn.Exec("UPDATE user_invite SET hash=?, username=?, email=?, display_name=?, is_admin=?, created_at=?, created_by=? "+
|
||||
"WHERE rowid=? ", ui.Hash, ui.Username, ui.Email, ui.DisplayName, ui.IsAdmin, ui.CreatedBy.ID, ui.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//Create creates an new user invitation
|
||||
func (rdb SQLiteUserInviteDatasource) Create(ui *UserInvite) (int, error) {
|
||||
res, err := rdb.SQLConn.Exec("INSERT INTO user_invite (hash, username, email, display_name, is_admin, created_at, created_by) VALUES(?, ?, ?, ?, ?, ?, ?);",
|
||||
ui.Hash, ui.Username, ui.Email, ui.DisplayName, ui.IsAdmin, time.Now(), ui.CreatedBy.ID)
|
||||
|
@ -105,7 +114,7 @@ func (rdb SQLiteUserInviteDatasource) Create(ui *UserInvite) (int, error) {
|
|||
return int(i), nil
|
||||
}
|
||||
|
||||
//Count retuns the amount of users
|
||||
//Count retuns the amount of users invitations
|
||||
func (rdb SQLiteUserInviteDatasource) Count() (int, error) {
|
||||
var total int
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ func restrictedRoutes(ctx *m.AppContext, router *mux.Router, chain alice.Chain)
|
|||
//user invites
|
||||
router.Handle("/user-invite/new", chain.Append(ctx.RequireAdmin).Then(useTemplateHandler(ctx, c.AdminUserInviteNewHandler))).Methods("GET")
|
||||
router.Handle("/user-invite/new", chain.Append(ctx.RequireAdmin).Then(useTemplateHandler(ctx, c.AdminUserInviteNewPostHandler))).Methods("POST")
|
||||
router.Handle("/user-invite/resend/{inviteID}", chain.Append(ctx.RequireAdmin).Then(useTemplateHandler(ctx, c.AdminUserInviteResendPostHandler))).Methods("POST")
|
||||
router.Handle("/user-invite/delete/{inviteID}", chain.Append(ctx.RequireAdmin).Then(useTemplateHandler(ctx, c.AdminUserInviteDeleteHandler))).Methods("GET")
|
||||
router.Handle("/user-invite/delete/{inviteID}", chain.Append(ctx.RequireAdmin).Then(useTemplateHandler(ctx, c.AdminUserInviteDeletePostHandler))).Methods("POST")
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<input type="text" value="{{.DisplayName}}" id="displayname" name="displayname" placeholder="Display name..." required>
|
||||
|
||||
<label for="password">New password</label>
|
||||
<input type="password" id="password" name="password" placeholder="Password..." required>
|
||||
<input type="password" id="password" name="password" placeholder="Password...">
|
||||
|
||||
<div class="checkbox">
|
||||
<label><input type="checkbox" id="admin" name="admin" value="on"{{if .IsAdmin}} checked{{end}}>Admin?</label>
|
||||
|
|
|
@ -34,7 +34,12 @@
|
|||
<td>{{.IsAdmin | BoolToIcon}}</td>
|
||||
<td>{{.CreatedBy.DisplayName}}</td>
|
||||
<td class="action-data">
|
||||
<a href="/admin/user-invite/resend/{{.ID}}" title="Invite">Resend invite link</a>
|
||||
<form method="post" action="/admin/user-invite/resend/{{.ID}}">
|
||||
<button type="submit" name="direction" value="resendinvite">
|
||||
Resend invite link
|
||||
</button>
|
||||
{{$.csrfField}}
|
||||
</form>
|
||||
<a href="/admin/user-invite/delete/{{.ID}}" title="Remove">Remove</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
Loading…
Reference in New Issue