mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-25 19:42:43 +01:00
Finish create organization team
This commit is contained in:
parent
e57aebb316
commit
465dc962b5
13 changed files with 389 additions and 247 deletions
|
@ -195,9 +195,10 @@ func runWeb(*cli.Context) {
|
|||
r.Get("/:org/dashboard", org.Dashboard)
|
||||
r.Get("/:org/members", org.Members)
|
||||
|
||||
r.Get("/:org/teams/:team/edit", org.EditTeam)
|
||||
r.Get("/:org/teams/new", org.NewTeam)
|
||||
r.Get("/:org/teams", org.Teams)
|
||||
r.Get("/:org/teams/new", org.NewTeam)
|
||||
r.Post("/:org/teams/new", bindIgnErr(auth.CreateTeamForm{}), org.NewTeamPost)
|
||||
r.Get("/:org/teams/:team/edit", org.EditTeam)
|
||||
|
||||
r.Get("/:org/settings", org.Settings)
|
||||
r.Post("/:org/settings", bindIgnErr(auth.OrgSettingForm{}), org.SettingsPost)
|
||||
|
|
2
gogs.go
2
gogs.go
|
@ -17,7 +17,7 @@ import (
|
|||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
const APP_VER = "0.4.5.0629 Alpha"
|
||||
const APP_VER = "0.4.5.0702 Alpha"
|
||||
|
||||
func init() {
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
|
|
@ -5,11 +5,17 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrOrgNotExist = errors.New("Organization does not exist")
|
||||
ErrTeamAlreadyExist = errors.New("Team already exist")
|
||||
)
|
||||
|
||||
// IsOrgOwner returns true if given user is in the owner team.
|
||||
func (org *User) IsOrgOwner(uid int64) bool {
|
||||
return IsOrganizationOwner(org.Id, uid)
|
||||
|
@ -156,6 +162,13 @@ func DeleteOrganization(org *User) (err error) {
|
|||
return sess.Commit()
|
||||
}
|
||||
|
||||
// ___________
|
||||
// \__ ___/___ _____ _____
|
||||
// | |_/ __ \\__ \ / \
|
||||
// | |\ ___/ / __ \| Y Y \
|
||||
// |____| \___ >____ /__|_| /
|
||||
// \/ \/ \/
|
||||
|
||||
type AuthorizeType int
|
||||
|
||||
const (
|
||||
|
@ -192,11 +205,41 @@ func (t *Team) GetMembers() (err error) {
|
|||
}
|
||||
|
||||
// NewTeam creates a record of new team.
|
||||
// It's caller's responsibility to assign organization ID.
|
||||
func NewTeam(t *Team) error {
|
||||
// TODO: check if same name team of organization exists.
|
||||
has, err := x.Id(t.OrgId).Get(new(User))
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return ErrOrgNotExist
|
||||
}
|
||||
|
||||
t.LowerName = strings.ToLower(t.Name)
|
||||
_, err := x.Insert(t)
|
||||
return err
|
||||
has, err = x.Where("org_id=?", t.OrgId).And("lower_name=?", t.LowerName).Get(new(Team))
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
return ErrTeamAlreadyExist
|
||||
}
|
||||
|
||||
sess := x.NewSession()
|
||||
defer sess.Close()
|
||||
if err = sess.Begin(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err = sess.Insert(t); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
|
||||
// Update organization number of teams.
|
||||
rawSql := "UPDATE `user` SET num_teams = num_teams + 1 WHERE id = ?"
|
||||
if _, err = sess.Exec(rawSql, t.OrgId); err != nil {
|
||||
sess.Rollback()
|
||||
return err
|
||||
}
|
||||
return sess.Commit()
|
||||
}
|
||||
|
||||
// UpdateTeam updates information of team.
|
||||
|
|
|
@ -158,7 +158,7 @@ func IsRepositoryExist(u *User, repoName string) (bool, error) {
|
|||
}
|
||||
|
||||
var (
|
||||
illegalEquals = []string{"raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin"}
|
||||
illegalEquals = []string{"raw", "install", "api", "avatar", "user", "org", "help", "stars", "issues", "pulls", "commits", "repo", "template", "admin", "new"}
|
||||
illegalSuffixs = []string{".git"}
|
||||
)
|
||||
|
||||
|
|
|
@ -7,183 +7,49 @@ package auth
|
|||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/go-martini/martini"
|
||||
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware/binding"
|
||||
)
|
||||
|
||||
// Web form interface.
|
||||
type Form interface {
|
||||
Name(field string) string
|
||||
type AuthenticationForm struct {
|
||||
Id int64 `form:"id"`
|
||||
Type int `form:"type"`
|
||||
AuthName string `form:"name" binding:"Required;MaxSize(50)"`
|
||||
Domain string `form:"domain"`
|
||||
Host string `form:"host"`
|
||||
Port int `form:"port"`
|
||||
UseSSL bool `form:"usessl"`
|
||||
BaseDN string `form:"base_dn"`
|
||||
Attributes string `form:"attributes"`
|
||||
Filter string `form:"filter"`
|
||||
MsAdSA string `form:"ms_ad_sa"`
|
||||
IsActived bool `form:"is_actived"`
|
||||
SmtpAuth string `form:"smtpauth"`
|
||||
SmtpHost string `form:"smtphost"`
|
||||
SmtpPort int `form:"smtpport"`
|
||||
Tls bool `form:"tls"`
|
||||
AllowAutoRegister bool `form:"allowautoregister"`
|
||||
}
|
||||
|
||||
type RegisterForm struct {
|
||||
UserName string `form:"username" binding:"Required;AlphaDashDot;MaxSize(30)"`
|
||||
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
|
||||
Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"`
|
||||
RetypePasswd string `form:"retypepasswd"`
|
||||
LoginType string `form:"logintype"`
|
||||
LoginName string `form:"loginname"`
|
||||
}
|
||||
|
||||
func (f *RegisterForm) Name(field string) string {
|
||||
func (f *AuthenticationForm) Name(field string) string {
|
||||
names := map[string]string{
|
||||
"UserName": "Username",
|
||||
"Email": "E-mail address",
|
||||
"Password": "Password",
|
||||
"RetypePasswd": "Re-type password",
|
||||
"AuthName": "Authentication's name",
|
||||
"Domain": "Domain name",
|
||||
"Host": "Host address",
|
||||
"Port": "Port Number",
|
||||
"UseSSL": "Use SSL",
|
||||
"BaseDN": "Base DN",
|
||||
"Attributes": "Search attributes",
|
||||
"Filter": "Search filter",
|
||||
"MsAdSA": "Ms Ad SA",
|
||||
}
|
||||
return names[field]
|
||||
}
|
||||
|
||||
func (f *RegisterForm) Validate(errs *binding.Errors, req *http.Request, ctx martini.Context) {
|
||||
data := ctx.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
|
||||
validate(errs, data, f)
|
||||
}
|
||||
|
||||
type LogInForm struct {
|
||||
UserName string `form:"username" binding:"Required;MaxSize(35)"`
|
||||
Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"`
|
||||
Remember bool `form:"remember"`
|
||||
}
|
||||
|
||||
func (f *LogInForm) Name(field string) string {
|
||||
names := map[string]string{
|
||||
"UserName": "Username",
|
||||
"Password": "Password",
|
||||
}
|
||||
return names[field]
|
||||
}
|
||||
|
||||
func (f *LogInForm) Validate(errs *binding.Errors, req *http.Request, ctx martini.Context) {
|
||||
data := ctx.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
|
||||
validate(errs, data, f)
|
||||
}
|
||||
|
||||
func GetMinMaxSize(field reflect.StructField) string {
|
||||
for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {
|
||||
if strings.HasPrefix(rule, "MinSize(") || strings.HasPrefix(rule, "MaxSize(") {
|
||||
return rule[8 : len(rule)-1]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func validate(errs *binding.Errors, data base.TmplData, f Form) {
|
||||
if errs.Count() == 0 {
|
||||
return
|
||||
} else if len(errs.Overall) > 0 {
|
||||
for _, err := range errs.Overall {
|
||||
log.Error("%s: %v", reflect.TypeOf(f), err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
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 err, ok := errs.Fields[field.Name]; ok {
|
||||
data["Err_"+field.Name] = true
|
||||
switch err {
|
||||
case binding.BindingRequireError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " cannot be empty"
|
||||
case binding.BindingAlphaDashError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " must be valid alpha or numeric or dash(-_) characters"
|
||||
case binding.BindingAlphaDashDotError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " must be valid alpha or numeric or dash(-_) or dot characters"
|
||||
case binding.BindingMinSizeError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " must contain at least " + GetMinMaxSize(field) + " characters"
|
||||
case binding.BindingMaxSizeError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " must contain at most " + GetMinMaxSize(field) + " characters"
|
||||
case binding.BindingEmailError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " is not a valid e-mail address"
|
||||
case binding.BindingUrlError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " is not a valid URL"
|
||||
default:
|
||||
data["ErrorMsg"] = "Unknown error: " + err
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AssignForm assign form values back to the template data.
|
||||
func AssignForm(form interface{}, data base.TmplData) {
|
||||
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
|
||||
}
|
||||
|
||||
data[fieldName] = val.Field(i).Interface()
|
||||
}
|
||||
}
|
||||
|
||||
type InstallForm struct {
|
||||
Database string `form:"database" binding:"Required"`
|
||||
Host string `form:"host"`
|
||||
User string `form:"user"`
|
||||
Passwd string `form:"passwd"`
|
||||
DatabaseName string `form:"database_name"`
|
||||
SslMode string `form:"ssl_mode"`
|
||||
DatabasePath string `form:"database_path"`
|
||||
RepoRootPath string `form:"repo_path"`
|
||||
RunUser string `form:"run_user"`
|
||||
Domain string `form:"domain"`
|
||||
AppUrl string `form:"app_url"`
|
||||
AdminName string `form:"admin_name" binding:"Required;AlphaDashDot;MaxSize(30)"`
|
||||
AdminPasswd string `form:"admin_pwd" binding:"Required;MinSize(6);MaxSize(30)"`
|
||||
AdminEmail string `form:"admin_email" binding:"Required;Email;MaxSize(50)"`
|
||||
SmtpHost string `form:"smtp_host"`
|
||||
SmtpEmail string `form:"mailer_user"`
|
||||
SmtpPasswd string `form:"mailer_pwd"`
|
||||
RegisterConfirm string `form:"register_confirm"`
|
||||
MailNotify string `form:"mail_notify"`
|
||||
}
|
||||
|
||||
func (f *InstallForm) Name(field string) string {
|
||||
names := map[string]string{
|
||||
"Database": "Database name",
|
||||
"AdminName": "Admin user name",
|
||||
"AdminPasswd": "Admin password",
|
||||
"AdminEmail": "Admin e-maill address",
|
||||
}
|
||||
return names[field]
|
||||
}
|
||||
|
||||
func (f *InstallForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) {
|
||||
func (f *AuthenticationForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) {
|
||||
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
|
||||
validate(errors, data, f)
|
||||
}
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
// 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 auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/go-martini/martini"
|
||||
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/middleware/binding"
|
||||
)
|
||||
|
||||
type AuthenticationForm struct {
|
||||
Id int64 `form:"id"`
|
||||
Type int `form:"type"`
|
||||
AuthName string `form:"name" binding:"Required;MaxSize(50)"`
|
||||
Domain string `form:"domain"`
|
||||
Host string `form:"host"`
|
||||
Port int `form:"port"`
|
||||
UseSSL bool `form:"usessl"`
|
||||
BaseDN string `form:"base_dn"`
|
||||
Attributes string `form:"attributes"`
|
||||
Filter string `form:"filter"`
|
||||
MsAdSA string `form:"ms_ad_sa"`
|
||||
IsActived bool `form:"is_actived"`
|
||||
SmtpAuth string `form:"smtpauth"`
|
||||
SmtpHost string `form:"smtphost"`
|
||||
SmtpPort int `form:"smtpport"`
|
||||
Tls bool `form:"tls"`
|
||||
AllowAutoRegister bool `form:"allowautoregister"`
|
||||
}
|
||||
|
||||
func (f *AuthenticationForm) Name(field string) string {
|
||||
names := map[string]string{
|
||||
"AuthName": "Authentication's name",
|
||||
"Domain": "Domain name",
|
||||
"Host": "Host address",
|
||||
"Port": "Port Number",
|
||||
"UseSSL": "Use SSL",
|
||||
"BaseDN": "Base DN",
|
||||
"Attributes": "Search attributes",
|
||||
"Filter": "Search filter",
|
||||
"MsAdSA": "Ms Ad SA",
|
||||
}
|
||||
return names[field]
|
||||
}
|
||||
|
||||
func (f *AuthenticationForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) {
|
||||
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
|
||||
validate(errors, data, f)
|
||||
}
|
|
@ -14,6 +14,13 @@ import (
|
|||
"github.com/gogits/gogs/modules/middleware/binding"
|
||||
)
|
||||
|
||||
// ________ .__ __ .__
|
||||
// \_____ \_______ _________ ____ |__|____________ _/ |_|__| ____ ____
|
||||
// / | \_ __ \/ ___\__ \ / \| \___ /\__ \\ __\ |/ _ \ / \
|
||||
// / | \ | \/ /_/ > __ \| | \ |/ / / __ \| | | ( <_> ) | \
|
||||
// \_______ /__| \___ (____ /___| /__/_____ \(____ /__| |__|\____/|___| /
|
||||
// \/ /_____/ \/ \/ \/ \/ \/
|
||||
|
||||
type CreateOrgForm struct {
|
||||
OrgName string `form:"orgname" binding:"Required;AlphaDashDot;MaxSize(30)"`
|
||||
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
|
||||
|
@ -55,3 +62,29 @@ func (f *OrgSettingForm) Validate(errors *binding.Errors, req *http.Request, con
|
|||
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
|
||||
validate(errors, data, f)
|
||||
}
|
||||
|
||||
// ___________
|
||||
// \__ ___/___ _____ _____
|
||||
// | |_/ __ \\__ \ / \
|
||||
// | |\ ___/ / __ \| Y Y \
|
||||
// |____| \___ >____ /__|_| /
|
||||
// \/ \/ \/
|
||||
|
||||
type CreateTeamForm struct {
|
||||
TeamName string `form:"name" binding:"Required;AlphaDashDot;MaxSize(30)"`
|
||||
Description string `form:"desc" binding:"MaxSize(255)"`
|
||||
Permission string `form:"permission"`
|
||||
}
|
||||
|
||||
func (f *CreateTeamForm) Name(field string) string {
|
||||
names := map[string]string{
|
||||
"TeamName": "Team name",
|
||||
"Description": "Team description",
|
||||
}
|
||||
return names[field]
|
||||
}
|
||||
|
||||
func (f *CreateTeamForm) Validate(errs *binding.Errors, req *http.Request, ctx martini.Context) {
|
||||
data := ctx.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
|
||||
validate(errs, data, f)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ package auth
|
|||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/go-martini/martini"
|
||||
|
||||
|
@ -19,6 +20,178 @@ import (
|
|||
"github.com/gogits/gogs/modules/setting"
|
||||
)
|
||||
|
||||
// Web form interface.
|
||||
type Form interface {
|
||||
Name(field string) string
|
||||
}
|
||||
|
||||
type RegisterForm struct {
|
||||
UserName string `form:"username" binding:"Required;AlphaDashDot;MaxSize(30)"`
|
||||
Email string `form:"email" binding:"Required;Email;MaxSize(50)"`
|
||||
Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"`
|
||||
RetypePasswd string `form:"retypepasswd"`
|
||||
LoginType string `form:"logintype"`
|
||||
LoginName string `form:"loginname"`
|
||||
}
|
||||
|
||||
func (f *RegisterForm) Name(field string) string {
|
||||
names := map[string]string{
|
||||
"UserName": "Username",
|
||||
"Email": "E-mail address",
|
||||
"Password": "Password",
|
||||
"RetypePasswd": "Re-type password",
|
||||
}
|
||||
return names[field]
|
||||
}
|
||||
|
||||
func (f *RegisterForm) Validate(errs *binding.Errors, req *http.Request, ctx martini.Context) {
|
||||
data := ctx.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
|
||||
validate(errs, data, f)
|
||||
}
|
||||
|
||||
type LogInForm struct {
|
||||
UserName string `form:"username" binding:"Required;MaxSize(35)"`
|
||||
Password string `form:"passwd" binding:"Required;MinSize(6);MaxSize(30)"`
|
||||
Remember bool `form:"remember"`
|
||||
}
|
||||
|
||||
func (f *LogInForm) Name(field string) string {
|
||||
names := map[string]string{
|
||||
"UserName": "Username",
|
||||
"Password": "Password",
|
||||
}
|
||||
return names[field]
|
||||
}
|
||||
|
||||
func (f *LogInForm) Validate(errs *binding.Errors, req *http.Request, ctx martini.Context) {
|
||||
data := ctx.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
|
||||
validate(errs, data, f)
|
||||
}
|
||||
|
||||
func GetMinMaxSize(field reflect.StructField) string {
|
||||
for _, rule := range strings.Split(field.Tag.Get("binding"), ";") {
|
||||
if strings.HasPrefix(rule, "MinSize(") || strings.HasPrefix(rule, "MaxSize(") {
|
||||
return rule[8 : len(rule)-1]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func validate(errs *binding.Errors, data base.TmplData, f Form) {
|
||||
if errs.Count() == 0 {
|
||||
return
|
||||
} else if len(errs.Overall) > 0 {
|
||||
for _, err := range errs.Overall {
|
||||
log.Error("%s: %v", reflect.TypeOf(f), err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
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 err, ok := errs.Fields[field.Name]; ok {
|
||||
data["Err_"+field.Name] = true
|
||||
switch err {
|
||||
case binding.BindingRequireError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " cannot be empty"
|
||||
case binding.BindingAlphaDashError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " must be valid alpha or numeric or dash(-_) characters"
|
||||
case binding.BindingAlphaDashDotError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " must be valid alpha or numeric or dash(-_) or dot characters"
|
||||
case binding.BindingMinSizeError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " must contain at least " + GetMinMaxSize(field) + " characters"
|
||||
case binding.BindingMaxSizeError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " must contain at most " + GetMinMaxSize(field) + " characters"
|
||||
case binding.BindingEmailError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " is not a valid e-mail address"
|
||||
case binding.BindingUrlError:
|
||||
data["ErrorMsg"] = f.Name(field.Name) + " is not a valid URL"
|
||||
default:
|
||||
data["ErrorMsg"] = "Unknown error: " + err
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AssignForm assign form values back to the template data.
|
||||
func AssignForm(form interface{}, data base.TmplData) {
|
||||
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
|
||||
}
|
||||
|
||||
data[fieldName] = val.Field(i).Interface()
|
||||
}
|
||||
}
|
||||
|
||||
type InstallForm struct {
|
||||
Database string `form:"database" binding:"Required"`
|
||||
Host string `form:"host"`
|
||||
User string `form:"user"`
|
||||
Passwd string `form:"passwd"`
|
||||
DatabaseName string `form:"database_name"`
|
||||
SslMode string `form:"ssl_mode"`
|
||||
DatabasePath string `form:"database_path"`
|
||||
RepoRootPath string `form:"repo_path"`
|
||||
RunUser string `form:"run_user"`
|
||||
Domain string `form:"domain"`
|
||||
AppUrl string `form:"app_url"`
|
||||
AdminName string `form:"admin_name" binding:"Required;AlphaDashDot;MaxSize(30)"`
|
||||
AdminPasswd string `form:"admin_pwd" binding:"Required;MinSize(6);MaxSize(30)"`
|
||||
AdminEmail string `form:"admin_email" binding:"Required;Email;MaxSize(50)"`
|
||||
SmtpHost string `form:"smtp_host"`
|
||||
SmtpEmail string `form:"mailer_user"`
|
||||
SmtpPasswd string `form:"mailer_pwd"`
|
||||
RegisterConfirm string `form:"register_confirm"`
|
||||
MailNotify string `form:"mail_notify"`
|
||||
}
|
||||
|
||||
func (f *InstallForm) Name(field string) string {
|
||||
names := map[string]string{
|
||||
"Database": "Database name",
|
||||
"AdminName": "Admin user name",
|
||||
"AdminPasswd": "Admin password",
|
||||
"AdminEmail": "Admin e-maill address",
|
||||
}
|
||||
return names[field]
|
||||
}
|
||||
|
||||
func (f *InstallForm) Validate(errors *binding.Errors, req *http.Request, context martini.Context) {
|
||||
data := context.Get(reflect.TypeOf(base.TmplData{})).Interface().(base.TmplData)
|
||||
validate(errors, data, f)
|
||||
}
|
||||
|
||||
// SignedInId returns the id of signed in user.
|
||||
func SignedInId(header http.Header, sess session.SessionStore) int64 {
|
||||
if !models.HasEngine {
|
||||
|
|
|
@ -8,12 +8,15 @@ import (
|
|||
"github.com/go-martini/martini"
|
||||
|
||||
"github.com/gogits/gogs/models"
|
||||
"github.com/gogits/gogs/modules/auth"
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/middleware"
|
||||
)
|
||||
|
||||
const (
|
||||
TEAMS base.TplName = "org/teams"
|
||||
TEAMS base.TplName = "org/teams"
|
||||
TEAM_NEW base.TplName = "org/team_new"
|
||||
)
|
||||
|
||||
func Teams(ctx *middleware.Context, params martini.Params) {
|
||||
|
@ -46,8 +49,80 @@ func Teams(ctx *middleware.Context, params martini.Params) {
|
|||
}
|
||||
|
||||
func NewTeam(ctx *middleware.Context, params martini.Params) {
|
||||
ctx.Data["Title"] = "Organization " + params["org"] + " New Team"
|
||||
ctx.HTML(200, "org/new_team")
|
||||
org, err := models.GetUserByName(params["org"])
|
||||
if err != nil {
|
||||
if err == models.ErrUserNotExist {
|
||||
ctx.Handle(404, "org.NewTeam(GetUserByName)", err)
|
||||
} else {
|
||||
ctx.Handle(500, "org.NewTeam(GetUserByName)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
ctx.Data["Org"] = org
|
||||
|
||||
// Check ownership of organization.
|
||||
if !org.IsOrgOwner(ctx.User.Id) {
|
||||
ctx.Error(403)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.HTML(200, TEAM_NEW)
|
||||
}
|
||||
|
||||
func NewTeamPost(ctx *middleware.Context, params martini.Params, form auth.CreateTeamForm) {
|
||||
org, err := models.GetUserByName(params["org"])
|
||||
if err != nil {
|
||||
if err == models.ErrUserNotExist {
|
||||
ctx.Handle(404, "org.NewTeamPost(GetUserByName)", err)
|
||||
} else {
|
||||
ctx.Handle(500, "org.NewTeamPost(GetUserByName)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
ctx.Data["Org"] = org
|
||||
|
||||
// Check ownership of organization.
|
||||
if !org.IsOrgOwner(ctx.User.Id) {
|
||||
ctx.Error(403)
|
||||
return
|
||||
}
|
||||
|
||||
if ctx.HasError() {
|
||||
ctx.HTML(200, TEAM_NEW)
|
||||
return
|
||||
}
|
||||
|
||||
// Validate permission level.
|
||||
var auth models.AuthorizeType
|
||||
switch form.Permission {
|
||||
case "read":
|
||||
auth = models.ORG_READABLE
|
||||
case "write":
|
||||
auth = models.ORG_WRITABLE
|
||||
case "admin":
|
||||
auth = models.ORG_ADMIN
|
||||
default:
|
||||
ctx.Error(401)
|
||||
return
|
||||
}
|
||||
|
||||
t := &models.Team{
|
||||
OrgId: org.Id,
|
||||
Name: form.TeamName,
|
||||
Description: form.Description,
|
||||
Authorize: auth,
|
||||
}
|
||||
if err = models.NewTeam(t); err != nil {
|
||||
if err == models.ErrTeamAlreadyExist {
|
||||
ctx.Data["Err_TeamName"] = true
|
||||
ctx.RenderWithErr("Team name has already been used", TEAM_NEW, &form)
|
||||
} else {
|
||||
ctx.Handle(500, "org.NewTeamPost(NewTeam)", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Trace("%s Team created: %s/%s", ctx.Req.RequestURI, org.Name, t.Name)
|
||||
ctx.Redirect("/org/" + org.LowerName + "/teams/" + t.LowerName)
|
||||
}
|
||||
|
||||
func EditTeam(ctx *middleware.Context, params martini.Params) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.4.5.0629 Alpha
|
||||
0.4.5.0702 Alpha
|
|
@ -13,7 +13,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group {{if .Err_Email}}has-error has-feedback{{end}}">
|
||||
<div class="form-group{{if .Err_Email}} has-error has-feedback{{end}}">
|
||||
<label class="col-md-2 control-label">Email<strong class="text-danger">*</strong></label>
|
||||
<div class="col-md-8">
|
||||
<input name="email" type="text" class="form-control" placeholder="Type organization's email" value="{{.email}}" required="required">
|
||||
|
|
|
@ -4,58 +4,63 @@
|
|||
<div class="container clearfix">
|
||||
<div id="org-nav-wrapper">
|
||||
<ul class="nav nav-pills pull-right">
|
||||
<li><a href="#"><i class="fa fa-users"></i>Members
|
||||
<span class="label label-default">5</span></a>
|
||||
<li><a href="/org/{{.Org.Name}}/members"><i class="fa fa-users"></i>Members
|
||||
<span class="label label-default">{{.Org.NumMembers}}</span></a>
|
||||
</li>
|
||||
<li class="active"><a href="#"><i class="fa fa-tags"></i>Teams
|
||||
<span class="label label-default">2</span></a>
|
||||
<li class="active"><a href="/org/{{.Org.Name}}/teams"><i class="fa fa-tags"></i>Teams
|
||||
<span class="label label-default">{{.Org.NumTeams}}</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
<img class="pull-left org-small-logo" src="https://avatars3.githubusercontent.com/u/6656686?s=140" alt="" width="60"/>
|
||||
<img class="pull-left org-small-logo" src="{{.Org.AvatarLink}}?s=140" alt="" width="60"/>
|
||||
<div id="org-nav-info">
|
||||
<h2 class="org-name">Organization Name</h2>
|
||||
<h2 class="org-name">{{.Org.FullName}}</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="body" class="container">
|
||||
<div id="org">
|
||||
<form id="org-teams-create" class="form-horizontal card">
|
||||
<form action="/org/{{.Org.Name}}/teams/new" method="post" id="org-teams-create" class="form-horizontal card">
|
||||
{{.CsrfTokenHtml}}
|
||||
<h3>Create new team</h3>
|
||||
<div class="form-group">
|
||||
{{template "base/alert" .}}
|
||||
<div class="form-group{{if .Err_TeamName}} has-error has-feedback{{end}}">
|
||||
<label class="col-md-2 control-label">Team Name<strong class="text-danger">*</strong></label>
|
||||
<div class="col-md-8">
|
||||
<input name="team" type="text" class="form-control" placeholder="Type your team name" value="" required="required">
|
||||
<input name="name" type="text" class="form-control" placeholder="Type your team name" value="{{.name}}" required="required">
|
||||
<span class="help-block">You'll use this name to mention this team in conversations.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
||||
<div class="form-group{{if .Err_Description}} has-error has-feedback{{end}}">
|
||||
<label class="col-md-2 control-label">Description</label>
|
||||
<div class="col-md-8">
|
||||
<input name="desc" type="text" class="form-control" placeholder="Type your team description (optional)" value="">
|
||||
<input name="desc" type="text" class="form-control" placeholder="Type your team description (optional)" value="{{.desc}}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
||||
<div class="form-group{{if .Err_Permission}} has-error has-feedback{{end}}">
|
||||
<label class="col-md-2 control-label">Permission</label>
|
||||
<div class="col-md-8">
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="permission" value="pull" checked="">
|
||||
<strong>Read & Clone</strong>
|
||||
<input type="radio" name="permission" value="read" checked="">
|
||||
<strong>Read Access</strong>
|
||||
</label>
|
||||
<p>This team will be able to view and clone its repositories.</p>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="permission" value="push">
|
||||
<strong>Push, Read & Clone</strong>
|
||||
<input type="radio" name="permission" value="write">
|
||||
<strong>Write Access</strong>
|
||||
</label>
|
||||
<p>This team will be able to read its repositories, as well as push to them.</p>
|
||||
</div>
|
||||
<div class="radio">
|
||||
<label>
|
||||
<input type="radio" name="permission" value="admin">
|
||||
<strong>Collaboration, Push, Read & Clone</strong>
|
||||
<strong>Admin Access</strong>
|
||||
</label>
|
||||
<p>This team will be able to push/pull to its repositories, as well as add other collaborators to them.</p>
|
||||
</div>
|
|
@ -18,6 +18,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="body" class="container">
|
||||
<div id="org">
|
||||
<div id="org-teams">
|
||||
|
|
Loading…
Reference in a new issue