2021-06-09 20:53:16 +03:00
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package auth
import (
2022-08-28 12:43:25 +03:00
"context"
2021-06-09 20:53:16 +03:00
"net/http"
2022-03-28 07:46:28 +03:00
"reflect"
"strings"
2021-06-09 20:53:16 +03:00
2021-09-19 14:49:59 +03:00
"code.gitea.io/gitea/models/db"
2021-11-24 12:49:20 +03:00
user_model "code.gitea.io/gitea/models/user"
2021-06-09 20:53:16 +03:00
)
// Ensure the struct implements the interface.
var (
2021-07-24 13:16:34 +03:00
_ Method = & Group { }
_ Initializable = & Group { }
_ Freeable = & Group { }
2021-06-09 20:53:16 +03:00
)
// Group implements the Auth interface with serval Auth.
type Group struct {
2021-07-24 13:16:34 +03:00
methods [ ] Method
2021-06-09 20:53:16 +03:00
}
// NewGroup creates a new auth group
2021-07-24 13:16:34 +03:00
func NewGroup ( methods ... Method ) * Group {
2021-06-09 20:53:16 +03:00
return & Group {
methods : methods ,
}
}
2022-03-28 07:46:28 +03:00
// Add adds a new method to group
func ( b * Group ) Add ( method Method ) {
b . methods = append ( b . methods , method )
}
// Name returns group's methods name
func ( b * Group ) Name ( ) string {
names := make ( [ ] string , 0 , len ( b . methods ) )
for _ , m := range b . methods {
if n , ok := m . ( Named ) ; ok {
names = append ( names , n . Name ( ) )
} else {
names = append ( names , reflect . TypeOf ( m ) . Elem ( ) . Name ( ) )
}
}
return strings . Join ( names , "," )
}
2021-06-09 20:53:16 +03:00
// Init does nothing as the Basic implementation does not need to allocate any resources
2022-08-28 12:43:25 +03:00
func ( b * Group ) Init ( ctx context . Context ) error {
2021-07-24 13:16:34 +03:00
for _ , method := range b . methods {
initializable , ok := method . ( Initializable )
if ! ok {
continue
}
2022-08-28 12:43:25 +03:00
if err := initializable . Init ( ctx ) ; err != nil {
2021-06-09 20:53:16 +03:00
return err
}
}
return nil
}
// Free does nothing as the Basic implementation does not have to release any resources
func ( b * Group ) Free ( ) error {
2021-07-24 13:16:34 +03:00
for _ , method := range b . methods {
freeable , ok := method . ( Freeable )
if ! ok {
continue
}
if err := freeable . Free ( ) ; err != nil {
2021-06-09 20:53:16 +03:00
return err
}
}
return nil
}
// Verify extracts and validates
2021-11-24 12:49:20 +03:00
func ( b * Group ) Verify ( req * http . Request , w http . ResponseWriter , store DataStore , sess SessionStore ) * user_model . User {
2021-09-19 14:49:59 +03:00
if ! db . HasEngine {
2021-06-09 20:53:16 +03:00
return nil
}
// Try to sign in with each of the enabled plugins
for _ , ssoMethod := range b . methods {
user := ssoMethod . Verify ( req , w , store , sess )
if user != nil {
if store . GetData ( ) [ "AuthedMethod" ] == nil {
2021-07-24 13:16:34 +03:00
if named , ok := ssoMethod . ( Named ) ; ok {
store . GetData ( ) [ "AuthedMethod" ] = named . Name ( )
}
2021-06-09 20:53:16 +03:00
}
return user
}
}
return nil
}