2020-03-02 21:25:36 +03:00
// Copyright 2020 The Gitea Authors.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2020-03-02 21:25:36 +03:00
package admin
import (
"bytes"
2021-04-05 18:30:52 +03:00
"net/http"
2020-03-02 21:25:36 +03:00
"net/url"
2021-09-24 14:32:56 +03:00
"code.gitea.io/gitea/models/db"
2021-11-11 10:03:30 +03:00
user_model "code.gitea.io/gitea/models/user"
2020-03-02 21:25:36 +03:00
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
)
const (
tplEmails base . TplName = "admin/emails/list"
)
// Emails show all emails
func Emails ( ctx * context . Context ) {
ctx . Data [ "Title" ] = ctx . Tr ( "admin.emails" )
ctx . Data [ "PageIsAdminEmails" ] = true
2021-11-28 17:11:58 +03:00
opts := & user_model . SearchEmailOptions {
2021-09-24 14:32:56 +03:00
ListOptions : db . ListOptions {
2020-03-02 21:25:36 +03:00
PageSize : setting . UI . Admin . UserPagingNum ,
2021-07-29 04:42:15 +03:00
Page : ctx . FormInt ( "page" ) ,
2020-03-02 21:25:36 +03:00
} ,
}
if opts . Page <= 1 {
opts . Page = 1
}
type ActiveEmail struct {
2021-11-28 17:11:58 +03:00
user_model . SearchEmailResult
2020-03-02 21:25:36 +03:00
CanChange bool
}
var (
2021-11-28 17:11:58 +03:00
baseEmails [ ] * user_model . SearchEmailResult
2020-03-02 21:25:36 +03:00
emails [ ] ActiveEmail
count int64
err error
2021-11-28 17:11:58 +03:00
orderBy user_model . SearchEmailOrderBy
2020-03-02 21:25:36 +03:00
)
2021-08-11 03:31:13 +03:00
ctx . Data [ "SortType" ] = ctx . FormString ( "sort" )
switch ctx . FormString ( "sort" ) {
2020-03-02 21:25:36 +03:00
case "email" :
2021-11-28 17:11:58 +03:00
orderBy = user_model . SearchEmailOrderByEmail
2020-03-02 21:25:36 +03:00
case "reverseemail" :
2021-11-28 17:11:58 +03:00
orderBy = user_model . SearchEmailOrderByEmailReverse
2020-03-02 21:25:36 +03:00
case "username" :
2021-11-28 17:11:58 +03:00
orderBy = user_model . SearchEmailOrderByName
2020-03-02 21:25:36 +03:00
case "reverseusername" :
2021-11-28 17:11:58 +03:00
orderBy = user_model . SearchEmailOrderByNameReverse
2020-03-02 21:25:36 +03:00
default :
ctx . Data [ "SortType" ] = "email"
2021-11-28 17:11:58 +03:00
orderBy = user_model . SearchEmailOrderByEmail
2020-03-02 21:25:36 +03:00
}
2021-07-29 04:42:15 +03:00
opts . Keyword = ctx . FormTrim ( "q" )
2020-03-02 21:25:36 +03:00
opts . SortType = orderBy
2021-08-11 03:31:13 +03:00
if len ( ctx . FormString ( "is_activated" ) ) != 0 {
2021-07-29 04:42:15 +03:00
opts . IsActivated = util . OptionalBoolOf ( ctx . FormBool ( "activated" ) )
2020-03-02 21:25:36 +03:00
}
2021-08-11 03:31:13 +03:00
if len ( ctx . FormString ( "is_primary" ) ) != 0 {
2021-07-29 04:42:15 +03:00
opts . IsPrimary = util . OptionalBoolOf ( ctx . FormBool ( "primary" ) )
2020-03-02 21:25:36 +03:00
}
if len ( opts . Keyword ) == 0 || isKeywordValid ( opts . Keyword ) {
2021-11-28 17:11:58 +03:00
baseEmails , count , err = user_model . SearchEmails ( opts )
2020-03-02 21:25:36 +03:00
if err != nil {
ctx . ServerError ( "SearchEmails" , err )
return
}
emails = make ( [ ] ActiveEmail , len ( baseEmails ) )
for i := range baseEmails {
emails [ i ] . SearchEmailResult = * baseEmails [ i ]
// Don't let the admin deactivate its own primary email address
// We already know the user is admin
2022-03-22 10:03:22 +03:00
emails [ i ] . CanChange = ctx . Doer . ID != emails [ i ] . UID || ! emails [ i ] . IsPrimary
2020-03-02 21:25:36 +03:00
}
}
ctx . Data [ "Keyword" ] = opts . Keyword
ctx . Data [ "Total" ] = count
ctx . Data [ "Emails" ] = emails
pager := context . NewPagination ( int ( count ) , opts . PageSize , opts . Page , 5 )
pager . SetDefaultParams ( ctx )
ctx . Data [ "Page" ] = pager
2021-04-05 18:30:52 +03:00
ctx . HTML ( http . StatusOK , tplEmails )
2020-03-02 21:25:36 +03:00
}
2022-01-20 20:46:10 +03:00
var nullByte = [ ] byte { 0x00 }
2020-03-02 21:25:36 +03:00
func isKeywordValid ( keyword string ) bool {
return ! bytes . Contains ( [ ] byte ( keyword ) , nullByte )
}
// ActivateEmail serves a POST request for activating/deactivating a user's email
func ActivateEmail ( ctx * context . Context ) {
truefalse := map [ string ] bool { "1" : true , "0" : false }
2021-07-29 04:42:15 +03:00
uid := ctx . FormInt64 ( "uid" )
2021-08-11 03:31:13 +03:00
email := ctx . FormString ( "email" )
primary , okp := truefalse [ ctx . FormString ( "primary" ) ]
activate , oka := truefalse [ ctx . FormString ( "activate" ) ]
2020-03-02 21:25:36 +03:00
if uid == 0 || len ( email ) == 0 || ! okp || ! oka {
2021-04-05 18:30:52 +03:00
ctx . Error ( http . StatusBadRequest )
2020-03-02 21:25:36 +03:00
return
}
log . Info ( "Changing activation for User ID: %d, email: %s, primary: %v to %v" , uid , email , primary , activate )
2021-11-28 17:11:58 +03:00
if err := user_model . ActivateUserEmail ( uid , email , activate ) ; err != nil {
2021-07-13 23:59:27 +03:00
log . Error ( "ActivateUserEmail(%v,%v,%v): %v" , uid , email , activate , err )
2021-11-11 10:03:30 +03:00
if user_model . IsErrEmailAlreadyUsed ( err ) {
2020-03-02 21:25:36 +03:00
ctx . Flash . Error ( ctx . Tr ( "admin.emails.duplicate_active" ) )
} else {
ctx . Flash . Error ( ctx . Tr ( "admin.emails.not_updated" , err ) )
}
} else {
log . Info ( "Activation for User ID: %d, email: %s, primary: %v changed to %v" , uid , email , primary , activate )
ctx . Flash . Info ( ctx . Tr ( "admin.emails.updated" ) )
}
redirect , _ := url . Parse ( setting . AppSubURL + "/admin/emails" )
q := url . Values { }
2021-07-29 04:42:15 +03:00
if val := ctx . FormTrim ( "q" ) ; len ( val ) > 0 {
2020-03-02 21:25:36 +03:00
q . Set ( "q" , val )
}
2021-07-29 04:42:15 +03:00
if val := ctx . FormTrim ( "sort" ) ; len ( val ) > 0 {
2020-03-02 21:25:36 +03:00
q . Set ( "sort" , val )
}
2021-07-29 04:42:15 +03:00
if val := ctx . FormTrim ( "is_primary" ) ; len ( val ) > 0 {
2020-03-02 21:25:36 +03:00
q . Set ( "is_primary" , val )
}
2021-07-29 04:42:15 +03:00
if val := ctx . FormTrim ( "is_activated" ) ; len ( val ) > 0 {
2020-03-02 21:25:36 +03:00
q . Set ( "is_activated" , val )
}
redirect . RawQuery = q . Encode ( )
ctx . Redirect ( redirect . String ( ) )
}