// Copyright 2022 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package doctor import ( "context" "fmt" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" "xorm.io/builder" ) func iterateUserAccounts(ctx context.Context, each func(*user.User) error) error { err := db.Iterate( ctx, builder.Gt{"id": 0}, func(ctx context.Context, bean *user.User) error { return each(bean) }, ) return err } // Since 1.16.4 new restrictions has been set on email addresses. However users with invalid email // addresses would be currently facing a error due to their invalid email address. // Ref: https://github.com/go-gitea/gitea/pull/19085 & https://github.com/go-gitea/gitea/pull/17688 func checkUserEmail(ctx context.Context, logger log.Logger, _ bool) error { // We could use quirky SQL to get all users that start without a [a-zA-Z0-9], but that would mean // DB provider-specific SQL and only works _now_. So instead we iterate through all user accounts // and use the user.ValidateEmail function to be future-proof. var invalidUserCount int64 if err := iterateUserAccounts(ctx, func(u *user.User) error { // Only check for users, skip if u.Type != user.UserTypeIndividual { return nil } if err := user.ValidateEmail(u.Email); err != nil { invalidUserCount++ logger.Warn("User[id=%d name=%q] have not a valid e-mail: %v", u.ID, u.Name, err) } return nil }); err != nil { return fmt.Errorf("iterateUserAccounts: %w", err) } if invalidUserCount == 0 { logger.Info("All users have a valid e-mail.") } else { logger.Warn("%d user(s) have a non-valid e-mail.", invalidUserCount) } return nil } // From time to time Gitea makes changes to the reserved usernames and which symbols // are allowed for various reasons. This check helps with detecting users that, according // to our reserved names, don't have a valid username. func checkUserName(ctx context.Context, logger log.Logger, _ bool) error { var invalidUserCount int64 if err := iterateUserAccounts(ctx, func(u *user.User) error { if err := user.IsUsableUsername(u.Name); err != nil { invalidUserCount++ logger.Warn("User[id=%d] does not have a valid username: %v", u.ID, err) } return nil }); err != nil { return fmt.Errorf("iterateUserAccounts: %w", err) } if invalidUserCount == 0 { logger.Info("All users have a valid username.") } else { logger.Warn("%d user(s) have a non-valid username.", invalidUserCount) } return nil } func init() { Register(&Check{ Title: "Check if users has an valid email address", Name: "check-user-email", IsDefault: false, Run: checkUserEmail, Priority: 9, }) Register(&Check{ Title: "Check if users have a valid username", Name: "check-user-names", IsDefault: false, Run: checkUserName, Priority: 9, }) } >blob: 8c93a3d39b744c0cbe2f21666cd3b51add3774e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
 * Copyright (C) 2004 Red Hat Inc.
 * Copyright (C) 2010 TigerVNC Team
 * 
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 * USA.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <core/string.h>

#include <rdr/TLSException.h>

#include <string.h>
#include <stdio.h>
#ifdef HAVE_GNUTLS
#include <gnutls/gnutls.h>
#endif

using namespace rdr;

#ifdef HAVE_GNUTLS
tls_error::tls_error(const char* s, int err_, int alert_) noexcept
  : std::runtime_error(core::format("%s: %s (%d)", s,
                                    strerror(err_, alert_), err_)),
    err(err_), alert(alert_)
{
}

const char* tls_error::strerror(int err_, int alert_) const noexcept
{
  const char* msg;

  msg = nullptr;

  if ((alert_ != -1) &&
      ((err_ == GNUTLS_E_WARNING_ALERT_RECEIVED) ||
       (err_ == GNUTLS_E_FATAL_ALERT_RECEIVED)))
    msg = gnutls_alert_get_name((gnutls_alert_description_t)alert_);

  if (msg == nullptr)
    msg = gnutls_strerror(err_);

  return msg;
}
#endif /* HAVE_GNUTLS */