mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	#1193 Make organization emails non-mandatory
This commit is contained in:
		@@ -630,7 +630,6 @@ release.tag_name_already_exist = Release with this tag name has already existed.
 | 
				
			|||||||
[org]
 | 
					[org]
 | 
				
			||||||
org_name_holder = Organization Name
 | 
					org_name_holder = Organization Name
 | 
				
			||||||
org_name_helper = Great organization names are short and memorable.
 | 
					org_name_helper = Great organization names are short and memorable.
 | 
				
			||||||
org_email_helper = Organization's E-mail receives all notifications and confirmations.
 | 
					 | 
				
			||||||
create_org = Create Organization
 | 
					create_org = Create Organization
 | 
				
			||||||
repo_updated = Updated
 | 
					repo_updated = Updated
 | 
				
			||||||
people = People
 | 
					people = People
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,8 +9,6 @@ import (
 | 
				
			|||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/gogits/gogs/modules/base"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
@@ -93,17 +91,6 @@ func (org *User) RemoveOrgRepo(repoID int64) error {
 | 
				
			|||||||
	return org.removeOrgRepo(x, repoID)
 | 
						return org.removeOrgRepo(x, repoID)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// IsOrgEmailUsed returns true if the e-mail has been used in organization account.
 | 
					 | 
				
			||||||
func IsOrgEmailUsed(email string) (bool, error) {
 | 
					 | 
				
			||||||
	if len(email) == 0 {
 | 
					 | 
				
			||||||
		return false, nil
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return x.Get(&User{
 | 
					 | 
				
			||||||
		Email: email,
 | 
					 | 
				
			||||||
		Type:  ORGANIZATION,
 | 
					 | 
				
			||||||
	})
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// CreateOrganization creates record of a new organization.
 | 
					// CreateOrganization creates record of a new organization.
 | 
				
			||||||
func CreateOrganization(org, owner *User) (err error) {
 | 
					func CreateOrganization(org, owner *User) (err error) {
 | 
				
			||||||
	if err = IsUsableName(org.Name); err != nil {
 | 
						if err = IsUsableName(org.Name); err != nil {
 | 
				
			||||||
@@ -117,18 +104,9 @@ func CreateOrganization(org, owner *User) (err error) {
 | 
				
			|||||||
		return ErrUserAlreadyExist{org.Name}
 | 
							return ErrUserAlreadyExist{org.Name}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	isExist, err = IsOrgEmailUsed(org.Email)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	} else if isExist {
 | 
					 | 
				
			||||||
		return ErrEmailAlreadyUsed{org.Email}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	org.LowerName = strings.ToLower(org.Name)
 | 
						org.LowerName = strings.ToLower(org.Name)
 | 
				
			||||||
	org.FullName = org.Name
 | 
						org.FullName = org.Name
 | 
				
			||||||
	org.Avatar = base.EncodeMd5(org.Email)
 | 
						org.UseCustomAvatar = true
 | 
				
			||||||
	org.AvatarEmail = org.Email
 | 
					 | 
				
			||||||
	// No password for organization.
 | 
					 | 
				
			||||||
	org.NumTeams = 1
 | 
						org.NumTeams = 1
 | 
				
			||||||
	org.NumMembers = 1
 | 
						org.NumMembers = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -141,6 +119,17 @@ func CreateOrganization(org, owner *User) (err error) {
 | 
				
			|||||||
	if _, err = sess.Insert(org); err != nil {
 | 
						if _, err = sess.Insert(org); err != nil {
 | 
				
			||||||
		return fmt.Errorf("insert organization: %v", err)
 | 
							return fmt.Errorf("insert organization: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						org.GenerateRandomAvatar()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Add initial creator to organization and owner team.
 | 
				
			||||||
 | 
						if _, err = sess.Insert(&OrgUser{
 | 
				
			||||||
 | 
							Uid:      owner.Id,
 | 
				
			||||||
 | 
							OrgID:    org.Id,
 | 
				
			||||||
 | 
							IsOwner:  true,
 | 
				
			||||||
 | 
							NumTeams: 1,
 | 
				
			||||||
 | 
						}); err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("insert org-user relation: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Create default owner team.
 | 
						// Create default owner team.
 | 
				
			||||||
	t := &Team{
 | 
						t := &Team{
 | 
				
			||||||
@@ -154,23 +143,11 @@ func CreateOrganization(org, owner *User) (err error) {
 | 
				
			|||||||
		return fmt.Errorf("insert owner team: %v", err)
 | 
							return fmt.Errorf("insert owner team: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Add initial creator to organization and owner team.
 | 
						if _, err = sess.Insert(&TeamUser{
 | 
				
			||||||
	ou := &OrgUser{
 | 
					 | 
				
			||||||
		Uid:      owner.Id,
 | 
					 | 
				
			||||||
		OrgID:    org.Id,
 | 
					 | 
				
			||||||
		IsOwner:  true,
 | 
					 | 
				
			||||||
		NumTeams: 1,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if _, err = sess.Insert(ou); err != nil {
 | 
					 | 
				
			||||||
		return fmt.Errorf("insert org-user relation: %v", err)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	tu := &TeamUser{
 | 
					 | 
				
			||||||
		Uid:    owner.Id,
 | 
							Uid:    owner.Id,
 | 
				
			||||||
		OrgID:  org.Id,
 | 
							OrgID:  org.Id,
 | 
				
			||||||
		TeamID: t.ID,
 | 
							TeamID: t.ID,
 | 
				
			||||||
	}
 | 
						}); err != nil {
 | 
				
			||||||
	if _, err = sess.Insert(tu); err != nil {
 | 
					 | 
				
			||||||
		return fmt.Errorf("insert team-user relation: %v", err)
 | 
							return fmt.Errorf("insert team-user relation: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,12 +55,12 @@ type User struct {
 | 
				
			|||||||
	Name      string `xorm:"UNIQUE NOT NULL"`
 | 
						Name      string `xorm:"UNIQUE NOT NULL"`
 | 
				
			||||||
	FullName  string
 | 
						FullName  string
 | 
				
			||||||
	// Email is the primary email address (to be used for communication).
 | 
						// Email is the primary email address (to be used for communication).
 | 
				
			||||||
	Email       string `xorm:"UNIQUE(s) NOT NULL"`
 | 
						Email       string `xorm:"NOT NULL"`
 | 
				
			||||||
	Passwd      string `xorm:"NOT NULL"`
 | 
						Passwd      string `xorm:"NOT NULL"`
 | 
				
			||||||
	LoginType   LoginType
 | 
						LoginType   LoginType
 | 
				
			||||||
	LoginSource int64 `xorm:"NOT NULL DEFAULT 0"`
 | 
						LoginSource int64 `xorm:"NOT NULL DEFAULT 0"`
 | 
				
			||||||
	LoginName   string
 | 
						LoginName   string
 | 
				
			||||||
	Type        UserType      `xorm:"UNIQUE(s)"`
 | 
						Type        UserType
 | 
				
			||||||
	Orgs        []*User       `xorm:"-"`
 | 
						Orgs        []*User       `xorm:"-"`
 | 
				
			||||||
	Repos       []*Repository `xorm:"-"`
 | 
						Repos       []*Repository `xorm:"-"`
 | 
				
			||||||
	Location    string
 | 
						Location    string
 | 
				
			||||||
@@ -132,42 +132,56 @@ func (u *User) HomeLink() string {
 | 
				
			|||||||
	return setting.AppSubUrl + "/" + u.Name
 | 
						return setting.AppSubUrl + "/" + u.Name
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CustomAvatarPath returns user custom avatar file path.
 | 
				
			||||||
 | 
					func (u *User) CustomAvatarPath() string {
 | 
				
			||||||
 | 
						return filepath.Join(setting.AvatarUploadPath, com.ToStr(u.Id))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// GenerateRandomAvatar generates a random avatar for user.
 | 
				
			||||||
 | 
					func (u *User) GenerateRandomAvatar() error {
 | 
				
			||||||
 | 
						seed := u.Email
 | 
				
			||||||
 | 
						if len(seed) == 0 {
 | 
				
			||||||
 | 
							seed = u.Name
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						img, err := avatar.RandomImage([]byte(seed))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("RandomImage: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err = os.MkdirAll(path.Dir(u.CustomAvatarPath()), os.ModePerm); err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("MkdirAll: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fw, err := os.Create(u.CustomAvatarPath())
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("Create: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer fw.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err = jpeg.Encode(fw, img, nil); err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("Encode: %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						log.Info("New random avatar created: %d", u.Id)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (u *User) RelAvatarLink() string {
 | 
					func (u *User) RelAvatarLink() string {
 | 
				
			||||||
	defaultImgUrl := "/img/avatar_default.jpg"
 | 
						defaultImgUrl := "/img/avatar_default.jpg"
 | 
				
			||||||
	if u.Id == -1 {
 | 
						if u.Id == -1 {
 | 
				
			||||||
		return defaultImgUrl
 | 
							return defaultImgUrl
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	imgPath := path.Join(setting.AvatarUploadPath, com.ToStr(u.Id))
 | 
					 | 
				
			||||||
	switch {
 | 
						switch {
 | 
				
			||||||
	case u.UseCustomAvatar:
 | 
						case u.UseCustomAvatar:
 | 
				
			||||||
		if !com.IsExist(imgPath) {
 | 
							if !com.IsExist(u.CustomAvatarPath()) {
 | 
				
			||||||
			return defaultImgUrl
 | 
								return defaultImgUrl
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return "/avatars/" + com.ToStr(u.Id)
 | 
							return "/avatars/" + com.ToStr(u.Id)
 | 
				
			||||||
	case setting.DisableGravatar, setting.OfflineMode:
 | 
						case setting.DisableGravatar, setting.OfflineMode:
 | 
				
			||||||
		if !com.IsExist(imgPath) {
 | 
							if !com.IsExist(u.CustomAvatarPath()) {
 | 
				
			||||||
			img, err := avatar.RandomImage([]byte(u.Email))
 | 
								if err := u.GenerateRandomAvatar(); err != nil {
 | 
				
			||||||
			if err != nil {
 | 
									log.Error(3, "GenerateRandomAvatar: %v", err)
 | 
				
			||||||
				log.Error(3, "RandomImage: %v", err)
 | 
					 | 
				
			||||||
				return defaultImgUrl
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if err = os.MkdirAll(path.Dir(imgPath), os.ModePerm); err != nil {
 | 
					 | 
				
			||||||
				log.Error(3, "MkdirAll: %v", err)
 | 
					 | 
				
			||||||
				return defaultImgUrl
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			fw, err := os.Create(imgPath)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				log.Error(3, "Create: %v", err)
 | 
					 | 
				
			||||||
				return defaultImgUrl
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			defer fw.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if err = jpeg.Encode(fw, img, nil); err != nil {
 | 
					 | 
				
			||||||
				log.Error(3, "Encode: %v", err)
 | 
					 | 
				
			||||||
				return defaultImgUrl
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			log.Info("New random avatar created: %d", u.Id)
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return "/avatars/" + com.ToStr(u.Id)
 | 
							return "/avatars/" + com.ToStr(u.Id)
 | 
				
			||||||
@@ -208,11 +222,6 @@ func (u *User) ValidatePassword(passwd string) bool {
 | 
				
			|||||||
	return u.Passwd == newUser.Passwd
 | 
						return u.Passwd == newUser.Passwd
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CustomAvatarPath returns user custom avatar file path.
 | 
					 | 
				
			||||||
func (u *User) CustomAvatarPath() string {
 | 
					 | 
				
			||||||
	return filepath.Join(setting.AvatarUploadPath, com.ToStr(u.Id))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// UploadAvatar saves custom avatar for user.
 | 
					// UploadAvatar saves custom avatar for user.
 | 
				
			||||||
// FIXME: split uploads to different subdirs in case we have massive users.
 | 
					// FIXME: split uploads to different subdirs in case we have massive users.
 | 
				
			||||||
func (u *User) UploadAvatar(data []byte) error {
 | 
					func (u *User) UploadAvatar(data []byte) error {
 | 
				
			||||||
@@ -494,6 +503,8 @@ func ChangeUserName(u *User, newUserName string) (err error) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func updateUser(e Engine, u *User) error {
 | 
					func updateUser(e Engine, u *User) error {
 | 
				
			||||||
 | 
						// Organization does not need e-mail.
 | 
				
			||||||
 | 
						if !u.IsOrganization() {
 | 
				
			||||||
		u.Email = strings.ToLower(u.Email)
 | 
							u.Email = strings.ToLower(u.Email)
 | 
				
			||||||
		has, err := e.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
 | 
							has, err := e.Where("id!=?", u.Id).And("type=?", u.Type).And("email=?", u.Email).Get(new(User))
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
@@ -502,6 +513,12 @@ func updateUser(e Engine, u *User) error {
 | 
				
			|||||||
			return ErrEmailAlreadyUsed{u.Email}
 | 
								return ErrEmailAlreadyUsed{u.Email}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if len(u.AvatarEmail) == 0 {
 | 
				
			||||||
 | 
								u.AvatarEmail = u.Email
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							u.Avatar = avatar.HashEmail(u.AvatarEmail)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u.LowerName = strings.ToLower(u.Name)
 | 
						u.LowerName = strings.ToLower(u.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(u.Location) > 255 {
 | 
						if len(u.Location) > 255 {
 | 
				
			||||||
@@ -514,13 +531,8 @@ func updateUser(e Engine, u *User) error {
 | 
				
			|||||||
		u.Description = u.Description[:255]
 | 
							u.Description = u.Description[:255]
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if u.AvatarEmail == "" {
 | 
					 | 
				
			||||||
		u.AvatarEmail = u.Email
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	u.Avatar = avatar.HashEmail(u.AvatarEmail)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u.FullName = base.Sanitizer.Sanitize(u.FullName)
 | 
						u.FullName = base.Sanitizer.Sanitize(u.FullName)
 | 
				
			||||||
	_, err = e.Id(u.Id).AllCols().Update(u)
 | 
						_, err := e.Id(u.Id).AllCols().Update(u)
 | 
				
			||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,8 +17,7 @@ import (
 | 
				
			|||||||
//         \/     /_____/     \/     \/         \/     \/                    \/
 | 
					//         \/     /_____/     \/     \/         \/     \/                    \/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type CreateOrgForm struct {
 | 
					type CreateOrgForm struct {
 | 
				
			||||||
	OrgName string `form:"org_name" binding:"Required;AlphaDashDot;MaxSize(30)"`
 | 
						OrgName string `binding:"Required;AlphaDashDot;MaxSize(30)"`
 | 
				
			||||||
	Email   string `form:"email" binding:"Required;Email;MaxSize(50)"`
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
 | 
					func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
 | 
				
			||||||
@@ -28,11 +27,9 @@ func (f *CreateOrgForm) Validate(ctx *macaron.Context, errs binding.Errors) bind
 | 
				
			|||||||
type UpdateOrgSettingForm struct {
 | 
					type UpdateOrgSettingForm struct {
 | 
				
			||||||
	OrgUserName string `form:"uname" binding:"Required;AlphaDashDot;MaxSize(30)" locale:"org.org_name_holder"`
 | 
						OrgUserName string `form:"uname" binding:"Required;AlphaDashDot;MaxSize(30)" locale:"org.org_name_holder"`
 | 
				
			||||||
	OrgFullName string `form:"fullname" binding:"MaxSize(100)"`
 | 
						OrgFullName string `form:"fullname" binding:"MaxSize(100)"`
 | 
				
			||||||
	Email       string `form:"email" binding:"Required;Email;MaxSize(50)"`
 | 
					 | 
				
			||||||
	Description string `form:"desc" binding:"MaxSize(255)"`
 | 
						Description string `form:"desc" binding:"MaxSize(255)"`
 | 
				
			||||||
	Website     string `form:"website" binding:"Url;MaxSize(100)"`
 | 
						Website     string `form:"website" binding:"Url;MaxSize(100)"`
 | 
				
			||||||
	Location    string `form:"location" binding:"MaxSize(50)"`
 | 
						Location    string `form:"location" binding:"MaxSize(50)"`
 | 
				
			||||||
	Avatar      string `form:"avatar" binding:"Required;Email;MaxSize(50)"`
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *UpdateOrgSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
 | 
					func (f *UpdateOrgSettingForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								public/css/gogs.min.css
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								public/css/gogs.min.css
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -17,11 +17,8 @@
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.repository {
 | 
					@create-page-form-input-padding: 250px !important;
 | 
				
			||||||
	@input-padding: 250px !important;
 | 
					#create-page-form {
 | 
				
			||||||
	&.new.repo,
 | 
					 | 
				
			||||||
	&.new.migrate,
 | 
					 | 
				
			||||||
	&.new.fork {
 | 
					 | 
				
			||||||
	form {
 | 
						form {
 | 
				
			||||||
		margin: auto;
 | 
							margin: auto;
 | 
				
			||||||
		width: 800px!important;
 | 
							width: 800px!important;
 | 
				
			||||||
@@ -29,16 +26,32 @@
 | 
				
			|||||||
			text-align: center;
 | 
								text-align: center;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		.header {
 | 
							.header {
 | 
				
			||||||
				padding-left: @input-padding+30px;
 | 
								padding-left: @create-page-form-input-padding+30px;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		.inline.field > label {
 | 
							.inline.field > label {
 | 
				
			||||||
			text-align: right;
 | 
								text-align: right;
 | 
				
			||||||
				width: @input-padding;
 | 
								width: @create-page-form-input-padding;
 | 
				
			||||||
			word-wrap: break-word;
 | 
								word-wrap: break-word;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		.help {
 | 
							.help {
 | 
				
			||||||
				margin-left: @input-padding+15px;
 | 
								margin-left: @create-page-form-input-padding+15px;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							.optional .title {
 | 
				
			||||||
 | 
								margin-left: @create-page-form-input-padding;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							input,
 | 
				
			||||||
 | 
							textarea {
 | 
				
			||||||
 | 
								width: 50%!important;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.repository {
 | 
				
			||||||
 | 
						&.new.repo,
 | 
				
			||||||
 | 
						&.new.migrate,
 | 
				
			||||||
 | 
						&.new.fork {
 | 
				
			||||||
 | 
							#create-page-form;
 | 
				
			||||||
 | 
							form {
 | 
				
			||||||
			.dropdown {
 | 
								.dropdown {
 | 
				
			||||||
				.dropdown.icon {
 | 
									.dropdown.icon {
 | 
				
			||||||
					margin-top: -7px!important;
 | 
										margin-top: -7px!important;
 | 
				
			||||||
@@ -50,13 +63,6 @@
 | 
				
			|||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			.optional .title {
 | 
					 | 
				
			||||||
				margin-left: @input-padding;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			input,
 | 
					 | 
				
			||||||
			textarea {
 | 
					 | 
				
			||||||
				width: 50%!important;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -66,7 +72,7 @@
 | 
				
			|||||||
				width: 50%!important;
 | 
									width: 50%!important;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			#auto-init {
 | 
								#auto-init {
 | 
				
			||||||
				margin-left: @input-padding+15px;
 | 
									margin-left: @create-page-form-input-padding+15px;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,4 +14,8 @@
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						&.new.org {
 | 
				
			||||||
 | 
							#create-page-form;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -59,25 +59,18 @@ func CreatePost(ctx *middleware.Context, form auth.CreateOrgForm) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	org := &models.User{
 | 
						org := &models.User{
 | 
				
			||||||
		Name:     form.OrgName,
 | 
							Name:     form.OrgName,
 | 
				
			||||||
		Email:    form.Email,
 | 
					 | 
				
			||||||
		IsActive: true,
 | 
							IsActive: true,
 | 
				
			||||||
		Type:     models.ORGANIZATION,
 | 
							Type:     models.ORGANIZATION,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var err error
 | 
						if err := models.CreateOrganization(org, ctx.User); err != nil {
 | 
				
			||||||
	if err = models.CreateOrganization(org, ctx.User); err != nil {
 | 
							ctx.Data["Err_OrgName"] = true
 | 
				
			||||||
		switch {
 | 
							switch {
 | 
				
			||||||
		case models.IsErrUserAlreadyExist(err):
 | 
							case models.IsErrUserAlreadyExist(err):
 | 
				
			||||||
			ctx.Data["Err_OrgName"] = true
 | 
					 | 
				
			||||||
			ctx.RenderWithErr(ctx.Tr("form.org_name_been_taken"), CREATE, &form)
 | 
								ctx.RenderWithErr(ctx.Tr("form.org_name_been_taken"), CREATE, &form)
 | 
				
			||||||
		case models.IsErrEmailAlreadyUsed(err):
 | 
					 | 
				
			||||||
			ctx.Data["Err_Email"] = true
 | 
					 | 
				
			||||||
			ctx.RenderWithErr(ctx.Tr("form.email_been_used"), CREATE, &form)
 | 
					 | 
				
			||||||
		case models.IsErrNameReserved(err):
 | 
							case models.IsErrNameReserved(err):
 | 
				
			||||||
			ctx.Data["Err_OrgName"] = true
 | 
					 | 
				
			||||||
			ctx.RenderWithErr(ctx.Tr("org.form.name_reserved", err.(models.ErrNameReserved).Name), CREATE, &form)
 | 
								ctx.RenderWithErr(ctx.Tr("org.form.name_reserved", err.(models.ErrNameReserved).Name), CREATE, &form)
 | 
				
			||||||
		case models.IsErrNamePatternNotAllowed(err):
 | 
							case models.IsErrNamePatternNotAllowed(err):
 | 
				
			||||||
			ctx.Data["Err_OrgName"] = true
 | 
					 | 
				
			||||||
			ctx.RenderWithErr(ctx.Tr("org.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), CREATE, &form)
 | 
								ctx.RenderWithErr(ctx.Tr("org.form.name_pattern_not_allowed", err.(models.ErrNamePatternNotAllowed).Pattern), CREATE, &form)
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			ctx.Handle(500, "CreateOrganization", err)
 | 
								ctx.Handle(500, "CreateOrganization", err)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,19 +61,11 @@ func SettingsPost(ctx *middleware.Context, form auth.UpdateOrgSettingForm) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	org.FullName = form.OrgFullName
 | 
						org.FullName = form.OrgFullName
 | 
				
			||||||
	org.Email = form.Email
 | 
					 | 
				
			||||||
	org.Description = form.Description
 | 
						org.Description = form.Description
 | 
				
			||||||
	org.Website = form.Website
 | 
						org.Website = form.Website
 | 
				
			||||||
	org.Location = form.Location
 | 
						org.Location = form.Location
 | 
				
			||||||
	org.Avatar = base.EncodeMd5(form.Avatar)
 | 
					 | 
				
			||||||
	org.AvatarEmail = form.Avatar
 | 
					 | 
				
			||||||
	if err := models.UpdateUser(org); err != nil {
 | 
						if err := models.UpdateUser(org); err != nil {
 | 
				
			||||||
		if models.IsErrEmailAlreadyUsed(err) {
 | 
					 | 
				
			||||||
			ctx.Data["Err_Email"] = true
 | 
					 | 
				
			||||||
			ctx.RenderWithErr(ctx.Tr("form.email_been_used"), SETTINGS_OPTIONS, &form)
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
		ctx.Handle(500, "UpdateUser", err)
 | 
							ctx.Handle(500, "UpdateUser", err)
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	log.Trace("Organization setting updated: %s", org.Name)
 | 
						log.Trace("Organization setting updated: %s", org.Name)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,31 +1,30 @@
 | 
				
			|||||||
{{template "ng/base/head" .}}
 | 
					{{template "base/head" .}}
 | 
				
			||||||
{{template "ng/base/header" .}}
 | 
					<div class="organization new org">
 | 
				
			||||||
<div id="sign-wrapper">
 | 
					  <div class="ui middle very relaxed page grid">
 | 
				
			||||||
    <form class="form-align form panel sign-panel sign-form container panel-radius" id="sign-up-form" action="{{AppSubUrl}}/org/create" method="post">
 | 
					    <div class="column">
 | 
				
			||||||
 | 
					      <form class="ui form" action="{{.Link}}" method="post">
 | 
				
			||||||
        {{.CsrfTokenHtml}}
 | 
					        {{.CsrfTokenHtml}}
 | 
				
			||||||
        <div class="panel-header">
 | 
					        <h3 class="ui top attached header">
 | 
				
			||||||
            <h2>{{.i18n.Tr "new_org"}}</h2>
 | 
					          {{.i18n.Tr "new_org"}}
 | 
				
			||||||
        </div>
 | 
					        </h3>
 | 
				
			||||||
        <div class="panel-content">
 | 
					        <div class="ui attached segment">
 | 
				
			||||||
            {{template "ng/base/alert" .}}
 | 
					          {{template "base/alert" .}}
 | 
				
			||||||
            <div class="field">
 | 
					          <div class="inline required field {{if .Err_OrgName}}error{{end}}">
 | 
				
			||||||
                <label class="req" for="org_name">{{.i18n.Tr "org.org_name_holder"}}</label>
 | 
					            <label for="org_name">{{.i18n.Tr "org.org_name_holder"}}</label>
 | 
				
			||||||
                <input class="ipt ipt-large ipt-radius {{if .Err_OrgName}}ipt-error{{end}}" id="org_name" name="org_name" type="text" value="{{.org_name}}" required/>
 | 
					            <input id="org_name" name="org_name" value="{{.org_name}}" autofocus required>
 | 
				
			||||||
                <label></label>
 | 
					 | 
				
			||||||
            <span class="help">{{.i18n.Tr "org.org_name_helper"}}</span>
 | 
					            <span class="help">{{.i18n.Tr "org.org_name_helper"}}</span>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
            <div class="field">
 | 
					
 | 
				
			||||||
                <label class="req" for="email">{{.i18n.Tr "email"}}</label>
 | 
					          <div class="inline field">
 | 
				
			||||||
                <input class="ipt ipt-large ipt-radius {{if .Err_Email}}ipt-error{{end}}" id="email" name="email" type="email" value="{{.email}}" required/>
 | 
					 | 
				
			||||||
            <label></label>
 | 
					            <label></label>
 | 
				
			||||||
                <span class="help">{{.i18n.Tr "org.org_email_helper"}}</span>
 | 
					            <button class="ui green button">
 | 
				
			||||||
            </div>
 | 
					              {{.i18n.Tr "org.create_org"}}
 | 
				
			||||||
            <div class="field">
 | 
					            </button>
 | 
				
			||||||
                <span class="form-label"></span>
 | 
					            <a class="ui button" href="{{AppSubUrl}}/">{{.i18n.Tr "cancel"}}</a>
 | 
				
			||||||
                <button class="btn btn-large btn-blue btn-radius">{{.i18n.Tr "org.create_org"}}</button>
 | 
					 | 
				
			||||||
                <a class="btn btn-small btn-gray btn-radius" id="repo-create-cancel" href="{{AppSubUrl}}/"><strong>{{.i18n.Tr "cancel"}}</strong></a>
 | 
					 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </form>
 | 
					      </form>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
{{template "ng/base/footer" .}}
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					{{template "base/footer" .}}
 | 
				
			||||||
@@ -30,10 +30,6 @@
 | 
				
			|||||||
                <label for="full-name">{{.i18n.Tr "org.settings.full_name"}}</label>
 | 
					                <label for="full-name">{{.i18n.Tr "org.settings.full_name"}}</label>
 | 
				
			||||||
                <input class="ipt ipt-large ipt-radius {{if .Err_FullName}}ipt-error{{end}}" id="full-name" name="fullname" value="{{.Org.FullName}}" />
 | 
					                <input class="ipt ipt-large ipt-radius {{if .Err_FullName}}ipt-error{{end}}" id="full-name" name="fullname" value="{{.Org.FullName}}" />
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
              <div class="field">
 | 
					 | 
				
			||||||
                <label class="req" for="email">{{.i18n.Tr "email"}}</label>
 | 
					 | 
				
			||||||
                <input class="ipt ipt-large ipt-radius {{if .Err_Email}}ipt-error{{end}}" id="email" name="email" type="email" value="{{.Org.Email}}" required />
 | 
					 | 
				
			||||||
              </div>
 | 
					 | 
				
			||||||
              <div class="field clear">
 | 
					              <div class="field clear">
 | 
				
			||||||
                <label class="left" for="desc">{{.i18n.Tr "org.org_desc"}}</label>
 | 
					                <label class="left" for="desc">{{.i18n.Tr "org.org_desc"}}</label>
 | 
				
			||||||
                <textarea class="ipt ipt-large ipt-radius {{if .Err_Description}}ipt-error{{end}}" id="desc" name="desc">{{.Org.Description}}</textarea>
 | 
					                <textarea class="ipt ipt-large ipt-radius {{if .Err_Description}}ipt-error{{end}}" id="desc" name="desc">{{.Org.Description}}</textarea>
 | 
				
			||||||
@@ -46,10 +42,6 @@
 | 
				
			|||||||
                <label for="location">{{.i18n.Tr "org.settings.location"}}</label>
 | 
					                <label for="location">{{.i18n.Tr "org.settings.location"}}</label>
 | 
				
			||||||
                <input class="ipt ipt-large ipt-radius {{if .Err_Location}}ipt-error{{end}}" id="location" name="location" type="text" value="{{.Org.Location}}" />
 | 
					                <input class="ipt ipt-large ipt-radius {{if .Err_Location}}ipt-error{{end}}" id="location" name="location" type="text" value="{{.Org.Location}}" />
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
              <div class="field {{if DisableGravatar}}hide{{end}}">
 | 
					 | 
				
			||||||
                <label class="req" for="gravatar-email">Gravatar {{.i18n.Tr "email"}}</label>
 | 
					 | 
				
			||||||
                <input class="ipt ipt-large ipt-radius {{if .Err_Avatar}}ipt-error{{end}}" id="gravatar-email" name="avatar" type="text" value="{{.Org.AvatarEmail}}" />
 | 
					 | 
				
			||||||
              </div>
 | 
					 | 
				
			||||||
              <div class="field">
 | 
					              <div class="field">
 | 
				
			||||||
                <span class="form-label"></span>
 | 
					                <span class="form-label"></span>
 | 
				
			||||||
                <button class="btn btn-green btn-large btn-radius" id="change-orgname-btn" href="#change-orgname-modal">{{.i18n.Tr "org.settings.update_settings"}}</button>
 | 
					                <button class="btn btn-green btn-large btn-radius" id="change-orgname-btn" href="#change-orgname-modal">{{.i18n.Tr "org.settings.update_settings"}}</button>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user