code.gitea.io/gitea@v1.21.7/routers/web/admin/emails.go (about)

     1  // Copyright 2020 The Gitea Authors.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package admin
     5  
     6  import (
     7  	"bytes"
     8  	"net/http"
     9  	"net/url"
    10  
    11  	"code.gitea.io/gitea/models/db"
    12  	user_model "code.gitea.io/gitea/models/user"
    13  	"code.gitea.io/gitea/modules/base"
    14  	"code.gitea.io/gitea/modules/context"
    15  	"code.gitea.io/gitea/modules/log"
    16  	"code.gitea.io/gitea/modules/setting"
    17  	"code.gitea.io/gitea/modules/util"
    18  )
    19  
    20  const (
    21  	tplEmails base.TplName = "admin/emails/list"
    22  )
    23  
    24  // Emails show all emails
    25  func Emails(ctx *context.Context) {
    26  	ctx.Data["Title"] = ctx.Tr("admin.emails")
    27  	ctx.Data["PageIsAdminEmails"] = true
    28  
    29  	opts := &user_model.SearchEmailOptions{
    30  		ListOptions: db.ListOptions{
    31  			PageSize: setting.UI.Admin.UserPagingNum,
    32  			Page:     ctx.FormInt("page"),
    33  		},
    34  	}
    35  
    36  	if opts.Page <= 1 {
    37  		opts.Page = 1
    38  	}
    39  
    40  	type ActiveEmail struct {
    41  		user_model.SearchEmailResult
    42  		CanChange bool
    43  	}
    44  
    45  	var (
    46  		baseEmails []*user_model.SearchEmailResult
    47  		emails     []ActiveEmail
    48  		count      int64
    49  		err        error
    50  		orderBy    user_model.SearchEmailOrderBy
    51  	)
    52  
    53  	ctx.Data["SortType"] = ctx.FormString("sort")
    54  	switch ctx.FormString("sort") {
    55  	case "email":
    56  		orderBy = user_model.SearchEmailOrderByEmail
    57  	case "reverseemail":
    58  		orderBy = user_model.SearchEmailOrderByEmailReverse
    59  	case "username":
    60  		orderBy = user_model.SearchEmailOrderByName
    61  	case "reverseusername":
    62  		orderBy = user_model.SearchEmailOrderByNameReverse
    63  	default:
    64  		ctx.Data["SortType"] = "email"
    65  		orderBy = user_model.SearchEmailOrderByEmail
    66  	}
    67  
    68  	opts.Keyword = ctx.FormTrim("q")
    69  	opts.SortType = orderBy
    70  	if len(ctx.FormString("is_activated")) != 0 {
    71  		opts.IsActivated = util.OptionalBoolOf(ctx.FormBool("activated"))
    72  	}
    73  	if len(ctx.FormString("is_primary")) != 0 {
    74  		opts.IsPrimary = util.OptionalBoolOf(ctx.FormBool("primary"))
    75  	}
    76  
    77  	if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) {
    78  		baseEmails, count, err = user_model.SearchEmails(ctx, opts)
    79  		if err != nil {
    80  			ctx.ServerError("SearchEmails", err)
    81  			return
    82  		}
    83  		emails = make([]ActiveEmail, len(baseEmails))
    84  		for i := range baseEmails {
    85  			emails[i].SearchEmailResult = *baseEmails[i]
    86  			// Don't let the admin deactivate its own primary email address
    87  			// We already know the user is admin
    88  			emails[i].CanChange = ctx.Doer.ID != emails[i].UID || !emails[i].IsPrimary
    89  		}
    90  	}
    91  	ctx.Data["Keyword"] = opts.Keyword
    92  	ctx.Data["Total"] = count
    93  	ctx.Data["Emails"] = emails
    94  
    95  	pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5)
    96  	pager.SetDefaultParams(ctx)
    97  	ctx.Data["Page"] = pager
    98  
    99  	ctx.HTML(http.StatusOK, tplEmails)
   100  }
   101  
   102  var nullByte = []byte{0x00}
   103  
   104  func isKeywordValid(keyword string) bool {
   105  	return !bytes.Contains([]byte(keyword), nullByte)
   106  }
   107  
   108  // ActivateEmail serves a POST request for activating/deactivating a user's email
   109  func ActivateEmail(ctx *context.Context) {
   110  	truefalse := map[string]bool{"1": true, "0": false}
   111  
   112  	uid := ctx.FormInt64("uid")
   113  	email := ctx.FormString("email")
   114  	primary, okp := truefalse[ctx.FormString("primary")]
   115  	activate, oka := truefalse[ctx.FormString("activate")]
   116  
   117  	if uid == 0 || len(email) == 0 || !okp || !oka {
   118  		ctx.Error(http.StatusBadRequest)
   119  		return
   120  	}
   121  
   122  	log.Info("Changing activation for User ID: %d, email: %s, primary: %v to %v", uid, email, primary, activate)
   123  
   124  	if err := user_model.ActivateUserEmail(ctx, uid, email, activate); err != nil {
   125  		log.Error("ActivateUserEmail(%v,%v,%v): %v", uid, email, activate, err)
   126  		if user_model.IsErrEmailAlreadyUsed(err) {
   127  			ctx.Flash.Error(ctx.Tr("admin.emails.duplicate_active"))
   128  		} else {
   129  			ctx.Flash.Error(ctx.Tr("admin.emails.not_updated", err))
   130  		}
   131  	} else {
   132  		log.Info("Activation for User ID: %d, email: %s, primary: %v changed to %v", uid, email, primary, activate)
   133  		ctx.Flash.Info(ctx.Tr("admin.emails.updated"))
   134  	}
   135  
   136  	redirect, _ := url.Parse(setting.AppSubURL + "/admin/emails")
   137  	q := url.Values{}
   138  	if val := ctx.FormTrim("q"); len(val) > 0 {
   139  		q.Set("q", val)
   140  	}
   141  	if val := ctx.FormTrim("sort"); len(val) > 0 {
   142  		q.Set("sort", val)
   143  	}
   144  	if val := ctx.FormTrim("is_primary"); len(val) > 0 {
   145  		q.Set("is_primary", val)
   146  	}
   147  	if val := ctx.FormTrim("is_activated"); len(val) > 0 {
   148  		q.Set("is_activated", val)
   149  	}
   150  	redirect.RawQuery = q.Encode()
   151  	ctx.Redirect(redirect.String())
   152  }