@@ -7,6 +7,7 @@ package auth
7
7
import (
8
8
"errors"
9
9
"fmt"
10
+ "html/template"
10
11
"net/http"
11
12
"strings"
12
13
@@ -37,12 +38,10 @@ import (
37
38
)
38
39
39
40
const (
40
- // tplSignIn template for sign in page
41
- tplSignIn base.TplName = "user/auth/signin"
42
- // tplSignUp template path for sign up page
43
- tplSignUp base.TplName = "user/auth/signup"
44
- // TplActivate template path for activate user
45
- TplActivate base.TplName = "user/auth/activate"
41
+ tplSignIn base.TplName = "user/auth/signin" // for sign in page
42
+ tplSignUp base.TplName = "user/auth/signup" // for sign up page
43
+ TplActivate base.TplName = "user/auth/activate" // for activate user
44
+ TplActivatePrompt base.TplName = "user/auth/activate_prompt" // for showing a message for user activation
46
45
)
47
46
48
47
// autoSignIn reads cookie and try to auto-login.
@@ -613,72 +612,83 @@ func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth.
613
612
}
614
613
}
615
614
616
- // Send confirmation email
617
- if ! u .IsActive && u .ID > 1 {
618
- if setting .Service .RegisterManualConfirm {
619
- ctx .Data ["ManualActivationOnly" ] = true
620
- ctx .HTML (http .StatusOK , TplActivate )
621
- return false
622
- }
615
+ // for active user or the first (admin) user, we don't need to send confirmation email
616
+ if u .IsActive || u .ID == 1 {
617
+ return true
618
+ }
623
619
624
- mailer .SendActivateAccountMail (ctx .Locale , u )
620
+ if setting .Service .RegisterManualConfirm {
621
+ renderActivationPromptMessage (ctx , ctx .Locale .Tr ("auth.manual_activation_only" ))
622
+ return false
623
+ }
625
624
626
- ctx .Data ["IsSendRegisterMail" ] = true
627
- ctx .Data ["Email" ] = u .Email
628
- ctx .Data ["ActiveCodeLives" ] = timeutil .MinutesToFriendly (setting .Service .ActiveCodeLives , ctx .Locale )
629
- ctx .HTML (http .StatusOK , TplActivate )
625
+ sendActivateEmail (ctx , u )
626
+ return false
627
+ }
630
628
631
- if err := ctx .Cache .Put ("MailResendLimit_" + u .LowerName , u .LowerName , 180 ); err != nil {
632
- log .Error ("Set cache(MailResendLimit) fail: %v" , err )
633
- }
634
- return false
629
+ func renderActivationPromptMessage (ctx * context.Context , msg template.HTML ) {
630
+ ctx .Data ["ActivationPromptMessage" ] = msg
631
+ ctx .HTML (http .StatusOK , TplActivatePrompt )
632
+ }
633
+
634
+ func sendActivateEmail (ctx * context.Context , u * user_model.User ) {
635
+ if ctx .Cache .IsExist ("MailResendLimit_" + u .LowerName ) {
636
+ renderActivationPromptMessage (ctx , ctx .Locale .Tr ("auth.resent_limit_prompt" ))
637
+ return
635
638
}
636
639
637
- return true
640
+ if err := ctx .Cache .Put ("MailResendLimit_" + u .LowerName , u .LowerName , 180 ); err != nil {
641
+ log .Error ("Set cache(MailResendLimit) fail: %v" , err )
642
+ renderActivationPromptMessage (ctx , ctx .Locale .Tr ("auth.resent_limit_prompt" ))
643
+ return
644
+ }
645
+
646
+ mailer .SendActivateAccountMail (ctx .Locale , u )
647
+
648
+ activeCodeLives := timeutil .MinutesToFriendly (setting .Service .ActiveCodeLives , ctx .Locale )
649
+ msgHTML := ctx .Locale .Tr ("auth.confirmation_mail_sent_prompt" , u .Email , activeCodeLives )
650
+ renderActivationPromptMessage (ctx , msgHTML )
651
+ }
652
+
653
+ func renderActivationVerifyPassword (ctx * context.Context , code string ) {
654
+ ctx .Data ["ActivationCode" ] = code
655
+ ctx .Data ["NeedVerifyLocalPassword" ] = true
656
+ ctx .HTML (http .StatusOK , TplActivate )
638
657
}
639
658
640
659
// Activate render activate user page
641
660
func Activate (ctx * context.Context ) {
642
661
code := ctx .FormString ("code" )
643
662
644
- if len (code ) == 0 {
645
- ctx .Data ["IsActivatePage" ] = true
646
- if ctx .Doer == nil || ctx .Doer .IsActive {
647
- ctx .NotFound ("invalid user" , nil )
663
+ if code == "" {
664
+ if ctx .Doer == nil {
665
+ ctx .Redirect (setting .AppSubURL + "/user/login" )
666
+ return
667
+ } else if ctx .Doer .IsActive {
668
+ ctx .Redirect (setting .AppSubURL + "/" )
648
669
return
649
670
}
650
- // Resend confirmation email.
651
- if setting .Service .RegisterEmailConfirm {
652
- if ctx .Cache .IsExist ("MailResendLimit_" + ctx .Doer .LowerName ) {
653
- ctx .Data ["ResendLimited" ] = true
654
- } else {
655
- ctx .Data ["ActiveCodeLives" ] = timeutil .MinutesToFriendly (setting .Service .ActiveCodeLives , ctx .Locale )
656
- mailer .SendActivateAccountMail (ctx .Locale , ctx .Doer )
657
671
658
- if err := ctx .Cache .Put ("MailResendLimit_" + ctx .Doer .LowerName , ctx .Doer .LowerName , 180 ); err != nil {
659
- log .Error ("Set cache(MailResendLimit) fail: %v" , err )
660
- }
661
- }
662
- } else {
663
- ctx .Data ["ServiceNotEnabled" ] = true
672
+ if setting .MailService == nil || ! setting .Service .RegisterEmailConfirm {
673
+ renderActivationPromptMessage (ctx , ctx .Tr ("auth.disable_register_mail" ))
674
+ return
664
675
}
665
- ctx .HTML (http .StatusOK , TplActivate )
676
+
677
+ // Resend confirmation email.
678
+ sendActivateEmail (ctx , ctx .Doer )
666
679
return
667
680
}
668
681
682
+ // TODO: ctx.Doer/ctx.Data["SignedUser"] could be nil or not the same user as the one being activated
669
683
user := user_model .VerifyUserActiveCode (ctx , code )
670
- // if code is wrong
671
- if user == nil {
672
- ctx .Data ["IsCodeInvalid" ] = true
673
- ctx .HTML (http .StatusOK , TplActivate )
684
+ if user == nil { // if code is wrong
685
+ renderActivationPromptMessage (ctx , ctx .Locale .Tr ("auth.invalid_code" ))
674
686
return
675
687
}
676
688
677
689
// if account is local account, verify password
678
690
if user .LoginSource == 0 {
679
- ctx .Data ["Code" ] = code
680
- ctx .Data ["NeedsPassword" ] = true
681
- ctx .HTML (http .StatusOK , TplActivate )
691
+ renderActivationVerifyPassword (ctx , code )
682
692
return
683
693
}
684
694
@@ -688,31 +698,28 @@ func Activate(ctx *context.Context) {
688
698
// ActivatePost handles account activation with password check
689
699
func ActivatePost (ctx * context.Context ) {
690
700
code := ctx .FormString ("code" )
691
- if len ( code ) == 0 {
701
+ if code == "" || ( ctx . Doer != nil && ctx . Doer . IsActive ) {
692
702
ctx .Redirect (setting .AppSubURL + "/user/activate" )
693
703
return
694
704
}
695
705
706
+ // TODO: ctx.Doer/ctx.Data["SignedUser"] could be nil or not the same user as the one being activated
696
707
user := user_model .VerifyUserActiveCode (ctx , code )
697
- // if code is wrong
698
- if user == nil {
699
- ctx .Data ["IsCodeInvalid" ] = true
700
- ctx .HTML (http .StatusOK , TplActivate )
708
+ if user == nil { // if code is wrong
709
+ renderActivationPromptMessage (ctx , ctx .Locale .Tr ("auth.invalid_code" ))
701
710
return
702
711
}
703
712
704
713
// if account is local account, verify password
705
714
if user .LoginSource == 0 {
706
715
password := ctx .FormString ("password" )
707
- if len (password ) == 0 {
708
- ctx .Data ["Code" ] = code
709
- ctx .Data ["NeedsPassword" ] = true
710
- ctx .HTML (http .StatusOK , TplActivate )
716
+ if password == "" {
717
+ renderActivationVerifyPassword (ctx , code )
711
718
return
712
719
}
713
720
if ! user .ValidatePassword (password ) {
714
- ctx .Data [ "IsPasswordInvalid" ] = true
715
- ctx . HTML ( http . StatusOK , TplActivate )
721
+ ctx .Flash . Error ( ctx . Locale . Tr ( "auth.invalid_password" ), true )
722
+ renderActivationVerifyPassword ( ctx , code )
716
723
return
717
724
}
718
725
}
0 commit comments