| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 | // Copyright 2014 The Gogs 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 authimport (	"net/http"	"reflect"	"strings"	"github.com/Unknwon/com"	"github.com/Unknwon/macaron"	"github.com/macaron-contrib/binding"	"github.com/macaron-contrib/session"	"github.com/gogits/gogs/models"	"github.com/gogits/gogs/modules/base"	"github.com/gogits/gogs/modules/log"	"github.com/gogits/gogs/modules/setting"	"github.com/gogits/gogs/modules/uuid")func IsAPIPath(url string) bool {	return strings.HasPrefix(url, "/api/")}// SignedInId returns the id of signed in user.func SignedInId(req *http.Request, sess session.Store) int64 {	if !models.HasEngine {		return 0	}	// API calls need to check access token.	if IsAPIPath(req.URL.Path) {		auHead := req.Header.Get("Authorization")		if len(auHead) > 0 {			auths := strings.Fields(auHead)			if len(auths) == 2 && auths[0] == "token" {				t, err := models.GetAccessTokenBySha(auths[1])				if err != nil {					if err != models.ErrAccessTokenNotExist {						log.Error(4, "GetAccessTokenBySha: %v", err)					}					return 0				}				return t.Uid			}		}	}	uid := sess.Get("uid")	if uid == nil {		return 0	}	if id, ok := uid.(int64); ok {		if _, err := models.GetUserByID(id); err != nil {			if !models.IsErrUserNotExist(err) {				log.Error(4, "GetUserById: %v", err)			}			return 0		}		return id	}	return 0}// SignedInUser returns the user object of signed user.// It returns a bool value to indicate whether user uses basic auth or not.func SignedInUser(req *http.Request, sess session.Store) (*models.User, bool) {	if !models.HasEngine {		return nil, false	}	uid := SignedInId(req, sess)	if uid <= 0 {		if setting.Service.EnableReverseProxyAuth {			webAuthUser := req.Header.Get(setting.ReverseProxyAuthUser)			if len(webAuthUser) > 0 {				u, err := models.GetUserByName(webAuthUser)				if err != nil {					if !models.IsErrUserNotExist(err) {						log.Error(4, "GetUserByName: %v", err)						return nil, false					}					// Check if enabled auto-registration.					if setting.Service.EnableReverseProxyAutoRegister {						u := &models.User{							Name:     webAuthUser,							Email:    uuid.NewV4().String() + "@localhost",							Passwd:   webAuthUser,							IsActive: true,						}						if err = models.CreateUser(u); err != nil {							// FIXME: should I create a system notice?							log.Error(4, "CreateUser: %v", err)							return nil, false						} else {							return u, false						}					}				}				return u, false			}		}		// Check with basic auth.		baHead := req.Header.Get("Authorization")		if len(baHead) > 0 {			auths := strings.Fields(baHead)			if len(auths) == 2 && auths[0] == "Basic" {				uname, passwd, _ := base.BasicAuthDecode(auths[1])				u, err := models.UserSignIn(uname, passwd)				if err != nil {					if !models.IsErrUserNotExist(err) {						log.Error(4, "UserSignIn: %v", err)					}					return nil, false				}				return u, true			}		}		return nil, false	}	u, err := models.GetUserByID(uid)	if err != nil {		log.Error(4, "GetUserById: %v", err)		return nil, false	}	return u, false}type Form interface {	binding.Validator}func init() {	binding.SetNameMapper(com.ToSnakeCase)}// AssignForm assign form values back to the template data.func AssignForm(form interface{}, data map[string]interface{}) {	typ := reflect.TypeOf(form)	val := reflect.ValueOf(form)	if typ.Kind() == reflect.Ptr {		typ = typ.Elem()		val = val.Elem()	}	for i := 0; i < typ.NumField(); i++ {		field := typ.Field(i)		fieldName := field.Tag.Get("form")		// Allow ignored fields in the struct		if fieldName == "-" {			continue		} else if len(fieldName) == 0 {			fieldName = com.ToSnakeCase(field.Name)		}		data[fieldName] = val.Field(i).Interface()	}}func getSize(field reflect.StructField, prefix string) string {	for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {		if strings.HasPrefix(rule, prefix) {			return rule[len(prefix) : len(rule)-1]		}	}	return ""}func GetSize(field reflect.StructField) string {	return getSize(field, "Size(")}func GetMinSize(field reflect.StructField) string {	return getSize(field, "MinSize(")}func GetMaxSize(field reflect.StructField) string {	return getSize(field, "MaxSize(")}func validate(errs binding.Errors, data map[string]interface{}, f Form, l macaron.Locale) binding.Errors {	if errs.Len() == 0 {		return errs	}	data["HasError"] = true	AssignForm(f, data)	typ := reflect.TypeOf(f)	val := reflect.ValueOf(f)	if typ.Kind() == reflect.Ptr {		typ = typ.Elem()		val = val.Elem()	}	for i := 0; i < typ.NumField(); i++ {		field := typ.Field(i)		fieldName := field.Tag.Get("form")		// Allow ignored fields in the struct		if fieldName == "-" {			continue		}		if errs[0].FieldNames[0] == field.Name {			data["Err_"+field.Name] = true			trName := field.Tag.Get("locale")			if len(trName) == 0 {				trName = l.Tr("form." + field.Name)			} else {				trName = l.Tr(trName)			}			switch errs[0].Classification {			case binding.ERR_REQUIRED:				data["ErrorMsg"] = trName + l.Tr("form.require_error")			case binding.ERR_ALPHA_DASH:				data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_error")			case binding.ERR_ALPHA_DASH_DOT:				data["ErrorMsg"] = trName + l.Tr("form.alpha_dash_dot_error")			case binding.ERR_SIZE:				data["ErrorMsg"] = trName + l.Tr("form.size_error", GetSize(field))			case binding.ERR_MIN_SIZE:				data["ErrorMsg"] = trName + l.Tr("form.min_size_error", GetMinSize(field))			case binding.ERR_MAX_SIZE:				data["ErrorMsg"] = trName + l.Tr("form.max_size_error", GetMaxSize(field))			case binding.ERR_EMAIL:				data["ErrorMsg"] = trName + l.Tr("form.email_error")			case binding.ERR_URL:				data["ErrorMsg"] = trName + l.Tr("form.url_error")			default:				data["ErrorMsg"] = l.Tr("form.unknown_error") + " " + errs[0].Classification			}			return errs		}	}	return errs}
 |