2014-06-08 21:53:53 +00:00
|
|
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
2019-11-14 19:10:23 +00:00
|
|
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
2022-11-27 18:20:29 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
2014-05-05 09:32:47 +00:00
|
|
|
|
2022-01-02 13:12:35 +00:00
|
|
|
package auth
|
2014-04-26 06:21:04 +00:00
|
|
|
|
2014-05-03 02:48:14 +00:00
|
|
|
import (
|
2023-06-05 09:29:07 +00:00
|
|
|
"context"
|
2021-09-24 11:32:56 +00:00
|
|
|
"fmt"
|
2021-07-24 10:16:34 +00:00
|
|
|
"reflect"
|
2014-04-26 06:21:04 +00:00
|
|
|
|
2021-09-19 11:49:59 +00:00
|
|
|
"code.gitea.io/gitea/models/db"
|
2016-11-10 16:24:48 +00:00
|
|
|
"code.gitea.io/gitea/modules/log"
|
2019-08-15 14:46:21 +00:00
|
|
|
"code.gitea.io/gitea/modules/timeutil"
|
2022-10-18 05:50:37 +00:00
|
|
|
"code.gitea.io/gitea/modules/util"
|
2019-08-15 14:46:21 +00:00
|
|
|
|
2019-10-17 09:26:49 +00:00
|
|
|
"xorm.io/xorm"
|
2020-03-22 15:12:55 +00:00
|
|
|
"xorm.io/xorm/convert"
|
2014-05-03 02:48:14 +00:00
|
|
|
)
|
2014-04-26 06:21:04 +00:00
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// Type represents an login type.
|
|
|
|
type Type int
|
2014-06-08 21:53:53 +00:00
|
|
|
|
2016-08-31 08:22:41 +00:00
|
|
|
// Note: new type must append to the end of list to maintain compatibility.
|
2014-05-05 08:40:25 +00:00
|
|
|
const (
|
2021-09-24 11:32:56 +00:00
|
|
|
NoType Type = iota
|
|
|
|
Plain // 1
|
|
|
|
LDAP // 2
|
|
|
|
SMTP // 3
|
|
|
|
PAM // 4
|
|
|
|
DLDAP // 5
|
|
|
|
OAuth2 // 6
|
|
|
|
SSPI // 7
|
2014-05-05 08:40:25 +00:00
|
|
|
)
|
|
|
|
|
[F3] Forgejo driver and CLI
user, topic, project, label, milestone, repository, pull_request,
release, asset, comment, reaction, review providers
Signed-off-by: Earl Warren <contact@earl-warren.org>
Preserve file size when creating attachments
Introduced in c6f50297084ebd9ec8b8c25370b9b963167274eb
repoList.LoadAttributes has a ctx argument now
Rename `repo.GetOwner` to `repo.LoadOwner`
bd66fa586a0da58c4cf2f5f8390aef4bac9d0527
upgrade to the latest gof3
(cherry picked from commit c77071365629984c1dc39a7a83e7252fd5b298e2)
[F3] ID remapping logic is in place, remove workaround
(cherry picked from commit d0fee301670c37c0e73afb271e0a8dd6b622f6f6)
[F3] it is experimental, do not enable by default
(cherry picked from commit de325b21d0adad199ec05652cb8d9fff19248ddb)
(cherry picked from commit 547e7b3c40f15766deb569cf2acface3290cf092)
(cherry picked from commit 820df3a56bc194645b482ef77a8845255d1185fe)
(cherry picked from commit eaba87689bbea84a215558033fc7d514b1b44f3e)
(cherry picked from commit 1b86896b3b4144254ed27064a167650b4e12c690)
(cherry picked from commit 0046aac1c639e021e719408e374cfc84fcbaa1d8)
(cherry picked from commit f14220df8ff692bdcfdcc94660acf64c77e732f5)
(cherry picked from commit 559b73100149978173b0ca8085280cc7fb79982f)
(cherry picked from commit 801f7d600de923afb9f24b74f2b28cc380f09cd0)
(cherry picked from commit 6aa76e9bcf243500675b5dbd543ee89d301ca44e)
(cherry picked from commit a8757dcb071093faea8a398413ee5681193b0627)
[F3] promote F3 users to matching OAuth2 users on first sign-in
(cherry picked from commit bd7fef7496c6f50e1559eac5922ec3280745864d)
(cherry picked from commit 07412698e8828bff3e1894d57356d92bb0063665)
(cherry picked from commit d143e5b2a3dda118529d29caea5e12423b5f5116)
[F3] upgrade to gof3 50a6e740ac04
Add new methods GetIDString() & SetIDString() & ToFormatInterface()
Change the prototype of the fixture function
(cherry picked from commit d7b263ff8b6fda188fe51b2ce75fa333d4aaa23e)
(cherry picked from commit b3eaf2249d3a8b35a564890674f9f50c4e2fde35)
(cherry picked from commit d492ddd9bba3df102e513e748fcafe7808206cb2)
[F3] add GetLocalMatchingRemote with a default implementation
(cherry picked from commit 0a2201503960a18a4308fcf9c13843c6b48569b0)
(cherry picked from commit f1310c38fbc4b2b941af323be215a6313de08232)
(cherry picked from commit deb68552f24ce22e35b5c7a88ceb45190b9df0a2)
[F3] GetLocalMatchingRemote for user
(cherry picked from commit e73cb837f57be0d6c65d6ecb13da621a362351da)
(cherry picked from commit a24bc0b85e1702917a6b39282a869b26654b1aa0)
(cherry picked from commit 846a522ecc5fcdfff1e875e3d006ea68f26137dd)
[F3] GetAdminUser now has a ctx argument
(cherry picked from commit 37357a92afe74405909721a0e0062c3eebcb3454)
(cherry picked from commit 660bc1673c189a16e88bd492947280a6e25fc7dd)
(cherry picked from commit 72d692a76743279b5dd74ff69ecf85d0994be265)
[F3] introduce UserTypeF3
To avoid conflicts should UserTypeRemoteUser be used differently by Gitea
(cherry picked from commit 6de2701bb34da3ab0e9f9e6038541eecbec1d7e4)
[F3] user.Put: idempotency
(cherry picked from commit 821e38573ceaa62ffa067b4e173fad50f0f20f05)
(cherry picked from commit f7638f5414e8dadbb3d982827d52c9529a4e9298)
[F3] upgrade to urfave v2
(cherry picked from commit cc3dbdfd1d1f6814cf8f047805dccf80efd8554c)
[F3] update gof3
(cherry picked from commit 2eee960751e1481f007c00e50406104a614e1255)
[F3] move f3 under forgejo-cli
* simplify the tests by re-using the forgejo-cli helpers to capture
the output
* unify CmdF3 to be structured in the same way CmdActions is
(cherry picked from commit 4c9fe58b7475529aecae2c85a4a51f7dcee86df8)
[F3] replace f3 with forgejo-cli f3
(cherry picked from commit 7ba7ceef1b22ed43d5e89f7c4a48d883332ac512)
[F3] s/ListOptions/Paginator/
[F3] user: add unit tests
[F3] user comparison of F3 managed users is on content
[F3] issue: add unit tests
[F3] gof3 now has one more argument to Put()
[F3] re-use gof3 unit tests for the driver
(cherry picked from commit af7ee6200cba7fcc2fa8bb7ca1e0aa0a5942a7df)
Conflicts:
tests/integration/integration_test.go
because of some code removed in forgejo-development, trivial
context conflict resolution
[F3] more idempotent tests (#1275)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/1275
Co-authored-by: Loïc Dachary <loic@dachary.org>
Co-committed-by: Loïc Dachary <loic@dachary.org>
[F3] tests: do SQL update if nothing changes
[F3] tests comment idempotence
[F3] tests milestone idempotence
[F3] tests pull_request idempotence
[F3] tests release idempotence
[F3] tests asset idempotence
[F3] tests project idempotence
[F3] tests review idempotence
(cherry picked from commit 91038bb4e8d1f45d496ccf05d4fc8be88ded8093)
(cherry picked from commit a7d2a65214d30d2b75961da8eed16378eb445766)
2022-09-06 04:35:43 +00:00
|
|
|
// This should be in the above list of types but is separated to avoid conflicts with Gitea changes
|
|
|
|
const F3 Type = 129
|
|
|
|
|
2021-07-24 10:16:34 +00:00
|
|
|
// String returns the string name of the LoginType
|
2021-09-24 11:32:56 +00:00
|
|
|
func (typ Type) String() string {
|
|
|
|
return Names[typ]
|
2021-07-24 10:16:34 +00:00
|
|
|
}
|
|
|
|
|
2021-07-25 07:09:52 +00:00
|
|
|
// Int returns the int value of the LoginType
|
2021-09-24 11:32:56 +00:00
|
|
|
func (typ Type) Int() int {
|
2021-07-25 07:09:52 +00:00
|
|
|
return int(typ)
|
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// Names contains the name of LoginType values.
|
|
|
|
var Names = map[Type]string{
|
|
|
|
LDAP: "LDAP (via BindDN)",
|
|
|
|
DLDAP: "LDAP (simple auth)", // Via direct bind
|
|
|
|
SMTP: "SMTP",
|
|
|
|
PAM: "PAM",
|
|
|
|
OAuth2: "OAuth2",
|
|
|
|
SSPI: "SPNEGO with SSPI",
|
[F3] Forgejo driver and CLI
user, topic, project, label, milestone, repository, pull_request,
release, asset, comment, reaction, review providers
Signed-off-by: Earl Warren <contact@earl-warren.org>
Preserve file size when creating attachments
Introduced in c6f50297084ebd9ec8b8c25370b9b963167274eb
repoList.LoadAttributes has a ctx argument now
Rename `repo.GetOwner` to `repo.LoadOwner`
bd66fa586a0da58c4cf2f5f8390aef4bac9d0527
upgrade to the latest gof3
(cherry picked from commit c77071365629984c1dc39a7a83e7252fd5b298e2)
[F3] ID remapping logic is in place, remove workaround
(cherry picked from commit d0fee301670c37c0e73afb271e0a8dd6b622f6f6)
[F3] it is experimental, do not enable by default
(cherry picked from commit de325b21d0adad199ec05652cb8d9fff19248ddb)
(cherry picked from commit 547e7b3c40f15766deb569cf2acface3290cf092)
(cherry picked from commit 820df3a56bc194645b482ef77a8845255d1185fe)
(cherry picked from commit eaba87689bbea84a215558033fc7d514b1b44f3e)
(cherry picked from commit 1b86896b3b4144254ed27064a167650b4e12c690)
(cherry picked from commit 0046aac1c639e021e719408e374cfc84fcbaa1d8)
(cherry picked from commit f14220df8ff692bdcfdcc94660acf64c77e732f5)
(cherry picked from commit 559b73100149978173b0ca8085280cc7fb79982f)
(cherry picked from commit 801f7d600de923afb9f24b74f2b28cc380f09cd0)
(cherry picked from commit 6aa76e9bcf243500675b5dbd543ee89d301ca44e)
(cherry picked from commit a8757dcb071093faea8a398413ee5681193b0627)
[F3] promote F3 users to matching OAuth2 users on first sign-in
(cherry picked from commit bd7fef7496c6f50e1559eac5922ec3280745864d)
(cherry picked from commit 07412698e8828bff3e1894d57356d92bb0063665)
(cherry picked from commit d143e5b2a3dda118529d29caea5e12423b5f5116)
[F3] upgrade to gof3 50a6e740ac04
Add new methods GetIDString() & SetIDString() & ToFormatInterface()
Change the prototype of the fixture function
(cherry picked from commit d7b263ff8b6fda188fe51b2ce75fa333d4aaa23e)
(cherry picked from commit b3eaf2249d3a8b35a564890674f9f50c4e2fde35)
(cherry picked from commit d492ddd9bba3df102e513e748fcafe7808206cb2)
[F3] add GetLocalMatchingRemote with a default implementation
(cherry picked from commit 0a2201503960a18a4308fcf9c13843c6b48569b0)
(cherry picked from commit f1310c38fbc4b2b941af323be215a6313de08232)
(cherry picked from commit deb68552f24ce22e35b5c7a88ceb45190b9df0a2)
[F3] GetLocalMatchingRemote for user
(cherry picked from commit e73cb837f57be0d6c65d6ecb13da621a362351da)
(cherry picked from commit a24bc0b85e1702917a6b39282a869b26654b1aa0)
(cherry picked from commit 846a522ecc5fcdfff1e875e3d006ea68f26137dd)
[F3] GetAdminUser now has a ctx argument
(cherry picked from commit 37357a92afe74405909721a0e0062c3eebcb3454)
(cherry picked from commit 660bc1673c189a16e88bd492947280a6e25fc7dd)
(cherry picked from commit 72d692a76743279b5dd74ff69ecf85d0994be265)
[F3] introduce UserTypeF3
To avoid conflicts should UserTypeRemoteUser be used differently by Gitea
(cherry picked from commit 6de2701bb34da3ab0e9f9e6038541eecbec1d7e4)
[F3] user.Put: idempotency
(cherry picked from commit 821e38573ceaa62ffa067b4e173fad50f0f20f05)
(cherry picked from commit f7638f5414e8dadbb3d982827d52c9529a4e9298)
[F3] upgrade to urfave v2
(cherry picked from commit cc3dbdfd1d1f6814cf8f047805dccf80efd8554c)
[F3] update gof3
(cherry picked from commit 2eee960751e1481f007c00e50406104a614e1255)
[F3] move f3 under forgejo-cli
* simplify the tests by re-using the forgejo-cli helpers to capture
the output
* unify CmdF3 to be structured in the same way CmdActions is
(cherry picked from commit 4c9fe58b7475529aecae2c85a4a51f7dcee86df8)
[F3] replace f3 with forgejo-cli f3
(cherry picked from commit 7ba7ceef1b22ed43d5e89f7c4a48d883332ac512)
[F3] s/ListOptions/Paginator/
[F3] user: add unit tests
[F3] user comparison of F3 managed users is on content
[F3] issue: add unit tests
[F3] gof3 now has one more argument to Put()
[F3] re-use gof3 unit tests for the driver
(cherry picked from commit af7ee6200cba7fcc2fa8bb7ca1e0aa0a5942a7df)
Conflicts:
tests/integration/integration_test.go
because of some code removed in forgejo-development, trivial
context conflict resolution
[F3] more idempotent tests (#1275)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/1275
Co-authored-by: Loïc Dachary <loic@dachary.org>
Co-committed-by: Loïc Dachary <loic@dachary.org>
[F3] tests: do SQL update if nothing changes
[F3] tests comment idempotence
[F3] tests milestone idempotence
[F3] tests pull_request idempotence
[F3] tests release idempotence
[F3] tests asset idempotence
[F3] tests project idempotence
[F3] tests review idempotence
(cherry picked from commit 91038bb4e8d1f45d496ccf05d4fc8be88ded8093)
(cherry picked from commit a7d2a65214d30d2b75961da8eed16378eb445766)
2022-09-06 04:35:43 +00:00
|
|
|
F3: "F3",
|
2014-05-05 08:40:25 +00:00
|
|
|
}
|
2014-04-26 06:21:04 +00:00
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// Config represents login config as far as the db is concerned
|
|
|
|
type Config interface {
|
2021-07-24 10:16:34 +00:00
|
|
|
convert.Conversion
|
2014-04-26 06:21:04 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 10:16:34 +00:00
|
|
|
// SkipVerifiable configurations provide a IsSkipVerify to check if SkipVerify is set
|
|
|
|
type SkipVerifiable interface {
|
|
|
|
IsSkipVerify() bool
|
2016-07-07 23:25:09 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 10:16:34 +00:00
|
|
|
// HasTLSer configurations provide a HasTLS to check if TLS can be enabled
|
|
|
|
type HasTLSer interface {
|
|
|
|
HasTLS() bool
|
2014-05-11 07:49:36 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 10:16:34 +00:00
|
|
|
// UseTLSer configurations provide a HasTLS to check if TLS is enabled
|
|
|
|
type UseTLSer interface {
|
|
|
|
UseTLS() bool
|
2014-05-11 07:49:36 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 10:16:34 +00:00
|
|
|
// SSHKeyProvider configurations provide ProvidesSSHKeys to check if they provide SSHKeys
|
|
|
|
type SSHKeyProvider interface {
|
|
|
|
ProvidesSSHKeys() bool
|
2014-05-11 07:49:36 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 10:16:34 +00:00
|
|
|
// RegisterableSource configurations provide RegisterSource which needs to be run on creation
|
|
|
|
type RegisterableSource interface {
|
|
|
|
RegisterSource() error
|
|
|
|
UnregisterSource() error
|
2015-04-23 11:58:57 +00:00
|
|
|
}
|
|
|
|
|
2022-01-02 13:12:35 +00:00
|
|
|
var registeredConfigs = map[Type]func() Config{}
|
2015-04-23 11:58:57 +00:00
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// RegisterTypeConfig register a config for a provided type
|
|
|
|
func RegisterTypeConfig(typ Type, exemplar Config) {
|
2021-07-24 10:16:34 +00:00
|
|
|
if reflect.TypeOf(exemplar).Kind() == reflect.Ptr {
|
|
|
|
// Pointer:
|
2021-09-24 11:32:56 +00:00
|
|
|
registeredConfigs[typ] = func() Config {
|
|
|
|
return reflect.New(reflect.ValueOf(exemplar).Elem().Type()).Interface().(Config)
|
2021-07-24 10:16:34 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2019-11-22 23:33:31 +00:00
|
|
|
|
2021-07-24 10:16:34 +00:00
|
|
|
// Not a Pointer
|
2021-09-24 11:32:56 +00:00
|
|
|
registeredConfigs[typ] = func() Config {
|
|
|
|
return reflect.New(reflect.TypeOf(exemplar)).Elem().Interface().(Config)
|
2021-07-24 10:16:34 +00:00
|
|
|
}
|
2019-11-22 23:33:31 +00:00
|
|
|
}
|
|
|
|
|
2022-01-02 13:12:35 +00:00
|
|
|
// SourceSettable configurations can have their authSource set on them
|
|
|
|
type SourceSettable interface {
|
|
|
|
SetAuthSource(*Source)
|
|
|
|
}
|
2019-11-22 23:33:31 +00:00
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// Source represents an external way for authorizing users.
|
|
|
|
type Source struct {
|
2017-05-10 13:10:18 +00:00
|
|
|
ID int64 `xorm:"pk autoincr"`
|
2021-09-24 11:32:56 +00:00
|
|
|
Type Type
|
2020-03-22 15:12:55 +00:00
|
|
|
Name string `xorm:"UNIQUE"`
|
2021-07-24 10:16:34 +00:00
|
|
|
IsActive bool `xorm:"INDEX NOT NULL DEFAULT false"`
|
2020-03-22 15:12:55 +00:00
|
|
|
IsSyncEnabled bool `xorm:"INDEX NOT NULL DEFAULT false"`
|
|
|
|
Cfg convert.Conversion `xorm:"TEXT"`
|
2016-03-10 00:53:30 +00:00
|
|
|
|
2019-08-15 14:46:21 +00:00
|
|
|
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
|
|
|
|
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
|
2014-05-03 02:48:14 +00:00
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// TableName xorm will read the table name from this method
|
|
|
|
func (Source) TableName() string {
|
|
|
|
return "login_source"
|
|
|
|
}
|
|
|
|
|
2021-09-19 11:49:59 +00:00
|
|
|
func init() {
|
2021-09-24 11:32:56 +00:00
|
|
|
db.RegisterModel(new(Source))
|
2021-09-19 11:49:59 +00:00
|
|
|
}
|
|
|
|
|
2016-11-24 11:34:38 +00:00
|
|
|
// BeforeSet is invoked from XORM before setting the value of a field of this object.
|
2021-09-24 11:32:56 +00:00
|
|
|
func (source *Source) BeforeSet(colName string, val xorm.Cell) {
|
2019-06-12 19:41:28 +00:00
|
|
|
if colName == "type" {
|
2022-01-02 13:12:35 +00:00
|
|
|
typ := Type(db.Cell2Int64(val))
|
2021-09-24 11:32:56 +00:00
|
|
|
constructor, ok := registeredConfigs[typ]
|
2021-07-24 10:16:34 +00:00
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
source.Cfg = constructor()
|
2021-09-24 11:32:56 +00:00
|
|
|
if settable, ok := source.Cfg.(SourceSettable); ok {
|
2022-01-02 13:12:35 +00:00
|
|
|
settable.SetAuthSource(source)
|
2015-08-29 07:45:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-24 11:34:38 +00:00
|
|
|
// TypeName return name of this login source type.
|
2021-09-24 11:32:56 +00:00
|
|
|
func (source *Source) TypeName() string {
|
|
|
|
return Names[source.Type]
|
2014-05-05 08:40:25 +00:00
|
|
|
}
|
|
|
|
|
2016-11-24 11:34:38 +00:00
|
|
|
// IsLDAP returns true of this source is of the LDAP type.
|
2021-09-24 11:32:56 +00:00
|
|
|
func (source *Source) IsLDAP() bool {
|
|
|
|
return source.Type == LDAP
|
2015-09-11 16:03:08 +00:00
|
|
|
}
|
|
|
|
|
2016-11-24 11:34:38 +00:00
|
|
|
// IsDLDAP returns true of this source is of the DLDAP type.
|
2021-09-24 11:32:56 +00:00
|
|
|
func (source *Source) IsDLDAP() bool {
|
|
|
|
return source.Type == DLDAP
|
2015-09-11 16:03:08 +00:00
|
|
|
}
|
|
|
|
|
2016-11-24 11:34:38 +00:00
|
|
|
// IsSMTP returns true of this source is of the SMTP type.
|
2021-09-24 11:32:56 +00:00
|
|
|
func (source *Source) IsSMTP() bool {
|
|
|
|
return source.Type == SMTP
|
2015-09-11 16:03:08 +00:00
|
|
|
}
|
|
|
|
|
2016-11-24 11:34:38 +00:00
|
|
|
// IsPAM returns true of this source is of the PAM type.
|
2021-09-24 11:32:56 +00:00
|
|
|
func (source *Source) IsPAM() bool {
|
|
|
|
return source.Type == PAM
|
2015-09-11 16:03:08 +00:00
|
|
|
}
|
|
|
|
|
2017-02-22 07:14:37 +00:00
|
|
|
// IsOAuth2 returns true of this source is of the OAuth2 type.
|
2021-09-24 11:32:56 +00:00
|
|
|
func (source *Source) IsOAuth2() bool {
|
|
|
|
return source.Type == OAuth2
|
2017-02-22 07:14:37 +00:00
|
|
|
}
|
|
|
|
|
2019-11-22 23:33:31 +00:00
|
|
|
// IsSSPI returns true of this source is of the SSPI type.
|
2021-09-24 11:32:56 +00:00
|
|
|
func (source *Source) IsSSPI() bool {
|
|
|
|
return source.Type == SSPI
|
2019-11-22 23:33:31 +00:00
|
|
|
}
|
|
|
|
|
[F3] Forgejo driver and CLI
user, topic, project, label, milestone, repository, pull_request,
release, asset, comment, reaction, review providers
Signed-off-by: Earl Warren <contact@earl-warren.org>
Preserve file size when creating attachments
Introduced in c6f50297084ebd9ec8b8c25370b9b963167274eb
repoList.LoadAttributes has a ctx argument now
Rename `repo.GetOwner` to `repo.LoadOwner`
bd66fa586a0da58c4cf2f5f8390aef4bac9d0527
upgrade to the latest gof3
(cherry picked from commit c77071365629984c1dc39a7a83e7252fd5b298e2)
[F3] ID remapping logic is in place, remove workaround
(cherry picked from commit d0fee301670c37c0e73afb271e0a8dd6b622f6f6)
[F3] it is experimental, do not enable by default
(cherry picked from commit de325b21d0adad199ec05652cb8d9fff19248ddb)
(cherry picked from commit 547e7b3c40f15766deb569cf2acface3290cf092)
(cherry picked from commit 820df3a56bc194645b482ef77a8845255d1185fe)
(cherry picked from commit eaba87689bbea84a215558033fc7d514b1b44f3e)
(cherry picked from commit 1b86896b3b4144254ed27064a167650b4e12c690)
(cherry picked from commit 0046aac1c639e021e719408e374cfc84fcbaa1d8)
(cherry picked from commit f14220df8ff692bdcfdcc94660acf64c77e732f5)
(cherry picked from commit 559b73100149978173b0ca8085280cc7fb79982f)
(cherry picked from commit 801f7d600de923afb9f24b74f2b28cc380f09cd0)
(cherry picked from commit 6aa76e9bcf243500675b5dbd543ee89d301ca44e)
(cherry picked from commit a8757dcb071093faea8a398413ee5681193b0627)
[F3] promote F3 users to matching OAuth2 users on first sign-in
(cherry picked from commit bd7fef7496c6f50e1559eac5922ec3280745864d)
(cherry picked from commit 07412698e8828bff3e1894d57356d92bb0063665)
(cherry picked from commit d143e5b2a3dda118529d29caea5e12423b5f5116)
[F3] upgrade to gof3 50a6e740ac04
Add new methods GetIDString() & SetIDString() & ToFormatInterface()
Change the prototype of the fixture function
(cherry picked from commit d7b263ff8b6fda188fe51b2ce75fa333d4aaa23e)
(cherry picked from commit b3eaf2249d3a8b35a564890674f9f50c4e2fde35)
(cherry picked from commit d492ddd9bba3df102e513e748fcafe7808206cb2)
[F3] add GetLocalMatchingRemote with a default implementation
(cherry picked from commit 0a2201503960a18a4308fcf9c13843c6b48569b0)
(cherry picked from commit f1310c38fbc4b2b941af323be215a6313de08232)
(cherry picked from commit deb68552f24ce22e35b5c7a88ceb45190b9df0a2)
[F3] GetLocalMatchingRemote for user
(cherry picked from commit e73cb837f57be0d6c65d6ecb13da621a362351da)
(cherry picked from commit a24bc0b85e1702917a6b39282a869b26654b1aa0)
(cherry picked from commit 846a522ecc5fcdfff1e875e3d006ea68f26137dd)
[F3] GetAdminUser now has a ctx argument
(cherry picked from commit 37357a92afe74405909721a0e0062c3eebcb3454)
(cherry picked from commit 660bc1673c189a16e88bd492947280a6e25fc7dd)
(cherry picked from commit 72d692a76743279b5dd74ff69ecf85d0994be265)
[F3] introduce UserTypeF3
To avoid conflicts should UserTypeRemoteUser be used differently by Gitea
(cherry picked from commit 6de2701bb34da3ab0e9f9e6038541eecbec1d7e4)
[F3] user.Put: idempotency
(cherry picked from commit 821e38573ceaa62ffa067b4e173fad50f0f20f05)
(cherry picked from commit f7638f5414e8dadbb3d982827d52c9529a4e9298)
[F3] upgrade to urfave v2
(cherry picked from commit cc3dbdfd1d1f6814cf8f047805dccf80efd8554c)
[F3] update gof3
(cherry picked from commit 2eee960751e1481f007c00e50406104a614e1255)
[F3] move f3 under forgejo-cli
* simplify the tests by re-using the forgejo-cli helpers to capture
the output
* unify CmdF3 to be structured in the same way CmdActions is
(cherry picked from commit 4c9fe58b7475529aecae2c85a4a51f7dcee86df8)
[F3] replace f3 with forgejo-cli f3
(cherry picked from commit 7ba7ceef1b22ed43d5e89f7c4a48d883332ac512)
[F3] s/ListOptions/Paginator/
[F3] user: add unit tests
[F3] user comparison of F3 managed users is on content
[F3] issue: add unit tests
[F3] gof3 now has one more argument to Put()
[F3] re-use gof3 unit tests for the driver
(cherry picked from commit af7ee6200cba7fcc2fa8bb7ca1e0aa0a5942a7df)
Conflicts:
tests/integration/integration_test.go
because of some code removed in forgejo-development, trivial
context conflict resolution
[F3] more idempotent tests (#1275)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/1275
Co-authored-by: Loïc Dachary <loic@dachary.org>
Co-committed-by: Loïc Dachary <loic@dachary.org>
[F3] tests: do SQL update if nothing changes
[F3] tests comment idempotence
[F3] tests milestone idempotence
[F3] tests pull_request idempotence
[F3] tests release idempotence
[F3] tests asset idempotence
[F3] tests project idempotence
[F3] tests review idempotence
(cherry picked from commit 91038bb4e8d1f45d496ccf05d4fc8be88ded8093)
(cherry picked from commit a7d2a65214d30d2b75961da8eed16378eb445766)
2022-09-06 04:35:43 +00:00
|
|
|
func (source *Source) IsF3() bool {
|
|
|
|
return source.Type == F3
|
|
|
|
}
|
|
|
|
|
2016-11-24 11:34:38 +00:00
|
|
|
// HasTLS returns true of this source supports TLS.
|
2021-09-24 11:32:56 +00:00
|
|
|
func (source *Source) HasTLS() bool {
|
2021-07-24 10:16:34 +00:00
|
|
|
hasTLSer, ok := source.Cfg.(HasTLSer)
|
|
|
|
return ok && hasTLSer.HasTLS()
|
2016-07-07 23:25:09 +00:00
|
|
|
}
|
|
|
|
|
2016-11-24 11:34:38 +00:00
|
|
|
// UseTLS returns true of this source is configured to use TLS.
|
2021-09-24 11:32:56 +00:00
|
|
|
func (source *Source) UseTLS() bool {
|
2021-07-24 10:16:34 +00:00
|
|
|
useTLSer, ok := source.Cfg.(UseTLSer)
|
|
|
|
return ok && useTLSer.UseTLS()
|
2015-09-11 16:03:08 +00:00
|
|
|
}
|
|
|
|
|
2016-11-24 11:34:38 +00:00
|
|
|
// SkipVerify returns true if this source is configured to skip SSL
|
|
|
|
// verification.
|
2021-09-24 11:32:56 +00:00
|
|
|
func (source *Source) SkipVerify() bool {
|
2021-07-24 10:16:34 +00:00
|
|
|
skipVerifiable, ok := source.Cfg.(SkipVerifiable)
|
|
|
|
return ok && skipVerifiable.IsSkipVerify()
|
2019-11-22 23:33:31 +00:00
|
|
|
}
|
|
|
|
|
2022-01-02 13:12:35 +00:00
|
|
|
// CreateSource inserts a AuthSource in the DB if not already
|
2016-11-24 11:34:38 +00:00
|
|
|
// existing with the given name.
|
2021-09-24 11:32:56 +00:00
|
|
|
func CreateSource(source *Source) error {
|
|
|
|
has, err := db.GetEngine(db.DefaultContext).Where("name=?", source.Name).Exist(new(Source))
|
2016-08-31 07:56:10 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
} else if has {
|
2021-09-24 11:32:56 +00:00
|
|
|
return ErrSourceAlreadyExist{source.Name}
|
2016-08-31 07:56:10 +00:00
|
|
|
}
|
2021-07-08 11:38:13 +00:00
|
|
|
// Synchronization is only available with LDAP for now
|
2017-05-10 13:10:18 +00:00
|
|
|
if !source.IsLDAP() {
|
|
|
|
source.IsSyncEnabled = false
|
|
|
|
}
|
2016-08-31 07:56:10 +00:00
|
|
|
|
2021-09-23 15:45:36 +00:00
|
|
|
_, err = db.GetEngine(db.DefaultContext).Insert(source)
|
2021-07-24 10:16:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if !source.IsActive {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
if settable, ok := source.Cfg.(SourceSettable); ok {
|
2022-01-02 13:12:35 +00:00
|
|
|
settable.SetAuthSource(source)
|
2021-07-25 07:09:52 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 10:16:34 +00:00
|
|
|
registerableSource, ok := source.Cfg.(RegisterableSource)
|
|
|
|
if !ok {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
err = registerableSource.RegisterSource()
|
|
|
|
if err != nil {
|
2022-01-02 13:12:35 +00:00
|
|
|
// remove the AuthSource in case of errors while registering configuration
|
2021-09-23 15:45:36 +00:00
|
|
|
if _, err := db.GetEngine(db.DefaultContext).Delete(source); err != nil {
|
2021-09-24 11:32:56 +00:00
|
|
|
log.Error("CreateSource: Error while wrapOpenIDConnectInitializeError: %v", err)
|
2017-05-01 13:26:53 +00:00
|
|
|
}
|
2017-02-22 07:14:37 +00:00
|
|
|
}
|
2014-06-08 21:53:53 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// Sources returns a slice of all login sources found in DB.
|
|
|
|
func Sources() ([]*Source, error) {
|
|
|
|
auths := make([]*Source, 0, 6)
|
2021-09-23 15:45:36 +00:00
|
|
|
return auths, db.GetEngine(db.DefaultContext).Find(&auths)
|
2014-05-03 02:48:14 +00:00
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// SourcesByType returns all sources of the specified type
|
|
|
|
func SourcesByType(loginType Type) ([]*Source, error) {
|
|
|
|
sources := make([]*Source, 0, 1)
|
2021-09-23 15:45:36 +00:00
|
|
|
if err := db.GetEngine(db.DefaultContext).Where("type = ?", loginType).Find(&sources); err != nil {
|
2019-11-22 23:33:31 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return sources, nil
|
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// AllActiveSources returns all active sources
|
|
|
|
func AllActiveSources() ([]*Source, error) {
|
|
|
|
sources := make([]*Source, 0, 5)
|
2021-09-23 15:45:36 +00:00
|
|
|
if err := db.GetEngine(db.DefaultContext).Where("is_active = ?", true).Find(&sources); err != nil {
|
2021-07-24 10:16:34 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return sources, nil
|
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// ActiveSources returns all active sources of the specified type
|
|
|
|
func ActiveSources(tp Type) ([]*Source, error) {
|
|
|
|
sources := make([]*Source, 0, 1)
|
|
|
|
if err := db.GetEngine(db.DefaultContext).Where("is_active = ? and type = ?", true, tp).Find(&sources); err != nil {
|
2019-11-22 23:33:31 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return sources, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsSSPIEnabled returns true if there is at least one activated login
|
|
|
|
// source of type LoginSSPI
|
|
|
|
func IsSSPIEnabled() bool {
|
2021-09-19 11:49:59 +00:00
|
|
|
if !db.HasEngine {
|
2019-11-22 23:33:31 +00:00
|
|
|
return false
|
|
|
|
}
|
2021-09-24 11:32:56 +00:00
|
|
|
sources, err := ActiveSources(SSPI)
|
2019-11-22 23:33:31 +00:00
|
|
|
if err != nil {
|
2021-09-24 11:32:56 +00:00
|
|
|
log.Error("ActiveSources: %v", err)
|
2019-11-22 23:33:31 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
return len(sources) > 0
|
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// GetSourceByID returns login source by given ID.
|
|
|
|
func GetSourceByID(id int64) (*Source, error) {
|
|
|
|
source := new(Source)
|
2021-07-24 10:16:34 +00:00
|
|
|
if id == 0 {
|
2021-09-24 11:32:56 +00:00
|
|
|
source.Cfg = registeredConfigs[NoType]()
|
2021-07-24 10:16:34 +00:00
|
|
|
// Set this source to active
|
|
|
|
// FIXME: allow disabling of db based password authentication in future
|
|
|
|
source.IsActive = true
|
|
|
|
return source, nil
|
|
|
|
}
|
|
|
|
|
2021-09-23 15:45:36 +00:00
|
|
|
has, err := db.GetEngine(db.DefaultContext).ID(id).Get(source)
|
2014-05-05 08:40:25 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2014-06-08 21:53:53 +00:00
|
|
|
} else if !has {
|
2021-09-24 11:32:56 +00:00
|
|
|
return nil, ErrSourceNotExist{id}
|
2014-05-05 08:40:25 +00:00
|
|
|
}
|
|
|
|
return source, nil
|
|
|
|
}
|
|
|
|
|
2023-06-05 09:29:07 +00:00
|
|
|
func GetSourceByName(ctx context.Context, name string) (*Source, error) {
|
|
|
|
source := &Source{}
|
|
|
|
has, err := db.GetEngine(ctx).Where("name = ?", name).Get(source)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
} else if !has {
|
|
|
|
return nil, ErrSourceNotExist{}
|
|
|
|
}
|
|
|
|
return source, nil
|
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// UpdateSource updates a Source record in DB.
|
|
|
|
func UpdateSource(source *Source) error {
|
2022-01-02 13:12:35 +00:00
|
|
|
var originalSource *Source
|
2017-05-01 13:26:53 +00:00
|
|
|
if source.IsOAuth2() {
|
|
|
|
// keep track of the original values so we can restore in case of errors while registering OAuth2 providers
|
|
|
|
var err error
|
2022-01-02 13:12:35 +00:00
|
|
|
if originalSource, err = GetSourceByID(source.ID); err != nil {
|
2017-05-01 13:26:53 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-31 14:32:18 +00:00
|
|
|
has, err := db.GetEngine(db.DefaultContext).Where("name=? AND id!=?", source.Name, source.ID).Exist(new(Source))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
} else if has {
|
|
|
|
return ErrSourceAlreadyExist{source.Name}
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = db.GetEngine(db.DefaultContext).ID(source.ID).AllCols().Update(source)
|
2021-07-24 10:16:34 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if !source.IsActive {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
if settable, ok := source.Cfg.(SourceSettable); ok {
|
2022-01-02 13:12:35 +00:00
|
|
|
settable.SetAuthSource(source)
|
2021-07-25 07:09:52 +00:00
|
|
|
}
|
|
|
|
|
2021-07-24 10:16:34 +00:00
|
|
|
registerableSource, ok := source.Cfg.(RegisterableSource)
|
|
|
|
if !ok {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
err = registerableSource.RegisterSource()
|
|
|
|
if err != nil {
|
|
|
|
// restore original values since we cannot update the provider it self
|
2022-01-02 13:12:35 +00:00
|
|
|
if _, err := db.GetEngine(db.DefaultContext).ID(source.ID).AllCols().Update(originalSource); err != nil {
|
2021-07-24 10:16:34 +00:00
|
|
|
log.Error("UpdateSource: Error while wrapOpenIDConnectInitializeError: %v", err)
|
2017-05-01 13:26:53 +00:00
|
|
|
}
|
2017-02-22 07:14:37 +00:00
|
|
|
}
|
2014-05-03 02:48:14 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// CountSources returns number of login sources.
|
|
|
|
func CountSources() int64 {
|
|
|
|
count, _ := db.GetEngine(db.DefaultContext).Count(new(Source))
|
|
|
|
return count
|
|
|
|
}
|
2017-02-22 07:14:37 +00:00
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// ErrSourceNotExist represents a "SourceNotExist" kind of error.
|
|
|
|
type ErrSourceNotExist struct {
|
|
|
|
ID int64
|
|
|
|
}
|
2017-02-22 07:14:37 +00:00
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// IsErrSourceNotExist checks if an error is a ErrSourceNotExist.
|
|
|
|
func IsErrSourceNotExist(err error) bool {
|
|
|
|
_, ok := err.(ErrSourceNotExist)
|
|
|
|
return ok
|
|
|
|
}
|
2017-02-22 07:14:37 +00:00
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
func (err ErrSourceNotExist) Error() string {
|
|
|
|
return fmt.Sprintf("login source does not exist [id: %d]", err.ID)
|
2014-04-26 06:21:04 +00:00
|
|
|
}
|
2014-05-11 06:12:45 +00:00
|
|
|
|
2022-10-18 05:50:37 +00:00
|
|
|
// Unwrap unwraps this as a ErrNotExist err
|
|
|
|
func (err ErrSourceNotExist) Unwrap() error {
|
|
|
|
return util.ErrNotExist
|
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// ErrSourceAlreadyExist represents a "SourceAlreadyExist" kind of error.
|
|
|
|
type ErrSourceAlreadyExist struct {
|
|
|
|
Name string
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsErrSourceAlreadyExist checks if an error is a ErrSourceAlreadyExist.
|
|
|
|
func IsErrSourceAlreadyExist(err error) bool {
|
|
|
|
_, ok := err.(ErrSourceAlreadyExist)
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
|
|
|
func (err ErrSourceAlreadyExist) Error() string {
|
|
|
|
return fmt.Sprintf("login source already exists [name: %s]", err.Name)
|
|
|
|
}
|
|
|
|
|
2022-10-18 05:50:37 +00:00
|
|
|
// Unwrap unwraps this as a ErrExist err
|
|
|
|
func (err ErrSourceAlreadyExist) Unwrap() error {
|
|
|
|
return util.ErrAlreadyExist
|
|
|
|
}
|
|
|
|
|
2021-09-24 11:32:56 +00:00
|
|
|
// ErrSourceInUse represents a "SourceInUse" kind of error.
|
|
|
|
type ErrSourceInUse struct {
|
|
|
|
ID int64
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsErrSourceInUse checks if an error is a ErrSourceInUse.
|
|
|
|
func IsErrSourceInUse(err error) bool {
|
|
|
|
_, ok := err.(ErrSourceInUse)
|
|
|
|
return ok
|
|
|
|
}
|
|
|
|
|
|
|
|
func (err ErrSourceInUse) Error() string {
|
|
|
|
return fmt.Sprintf("login source is still used by some users [id: %d]", err.ID)
|
2016-08-31 08:22:41 +00:00
|
|
|
}
|