Merge 5df42b40f4
into d0fef4395f
This commit is contained in:
commit
b945906506
|
@ -318,6 +318,11 @@ DEFAULT_KEEP_EMAIL_PRIVATE = false
|
||||||
; Default value for AllowCreateOrganization
|
; Default value for AllowCreateOrganization
|
||||||
; Every new user will have rights set to create organizations depending on this setting
|
; Every new user will have rights set to create organizations depending on this setting
|
||||||
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
||||||
|
; Either "public", "limited" or "private", default is "public"
|
||||||
|
; Limited is for signed user only
|
||||||
|
; Private is only for member of the organization
|
||||||
|
; Public is for everyone
|
||||||
|
DEFAULT_VISIBILITY = public
|
||||||
; Default value for EnableDependencies
|
; Default value for EnableDependencies
|
||||||
; Repositories will use depencies by default depending on this setting
|
; Repositories will use depencies by default depending on this setting
|
||||||
DEFAULT_ENABLE_DEPENDENCIES = true
|
DEFAULT_ENABLE_DEPENDENCIES = true
|
||||||
|
|
|
@ -194,6 +194,8 @@ var migrations = []Migration{
|
||||||
NewMigration("move team units to team_unit table", moveTeamUnitsToTeamUnitTable),
|
NewMigration("move team units to team_unit table", moveTeamUnitsToTeamUnitTable),
|
||||||
// v70 -> v71
|
// v70 -> v71
|
||||||
NewMigration("add issue_dependencies", addIssueDependencies),
|
NewMigration("add issue_dependencies", addIssueDependencies),
|
||||||
|
// v71 -> v72
|
||||||
|
NewMigration("add visibility for user and org", addVisibilityForUserAndOrg),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate database to current version
|
// Migrate database to current version
|
||||||
|
|
22
models/migrations/v71.go
Normal file
22
models/migrations/v71.go
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2018 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 migrations
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/go-xorm/xorm"
|
||||||
|
)
|
||||||
|
|
||||||
|
func addVisibilityForUserAndOrg(x *xorm.Engine) error {
|
||||||
|
type User struct {
|
||||||
|
Visibility int `xorm:"NOT NULL DEFAULT 1"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := x.Sync2(new(User)); err != nil {
|
||||||
|
return fmt.Errorf("Sync2: %v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -366,6 +367,42 @@ func getOwnedOrgsByUserID(sess *xorm.Session, userID int64) ([]*User, error) {
|
||||||
Find(&orgs)
|
Find(&orgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasOrgVisible tell if the given user can see one of the given orgs
|
||||||
|
func HasOrgVisible(orgs []*User, user *User) bool {
|
||||||
|
if len(orgs) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not SignedUser
|
||||||
|
if user == nil {
|
||||||
|
for _, org := range orgs {
|
||||||
|
if org.Visibility == 1 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if user.IsAdmin {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, org := range orgs {
|
||||||
|
switch org.Visibility {
|
||||||
|
case VisibleTypePublic:
|
||||||
|
return true
|
||||||
|
case VisibleTypeLimited:
|
||||||
|
return true
|
||||||
|
case VisibleTypePrivate:
|
||||||
|
if org.IsUserOrgPartOf(user.ID) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// GetOwnedOrgsByUserID returns a list of organizations are owned by given user ID.
|
// GetOwnedOrgsByUserID returns a list of organizations are owned by given user ID.
|
||||||
func GetOwnedOrgsByUserID(userID int64) ([]*User, error) {
|
func GetOwnedOrgsByUserID(userID int64) ([]*User, error) {
|
||||||
sess := x.NewSession()
|
sess := x.NewSession()
|
||||||
|
|
|
@ -544,3 +544,72 @@ func TestAccessibleReposEnv_MirrorRepos(t *testing.T) {
|
||||||
testSuccess(2, []int64{5})
|
testSuccess(2, []int64{5})
|
||||||
testSuccess(4, []int64{})
|
testSuccess(4, []int64{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHasOrgVisibleTypePublic(t *testing.T) {
|
||||||
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
|
owner := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||||
|
user3 := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User)
|
||||||
|
|
||||||
|
const newOrgName = "test-org-public"
|
||||||
|
org := &User{
|
||||||
|
Name: newOrgName,
|
||||||
|
Visibility: VisibleTypePublic,
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertNotExistsBean(t, &User{Name: org.Name, Type: UserTypeOrganization})
|
||||||
|
assert.NoError(t, CreateOrganization(org, owner))
|
||||||
|
org = AssertExistsAndLoadBean(t,
|
||||||
|
&User{Name: org.Name, Type: UserTypeOrganization}).(*User)
|
||||||
|
test1 := HasOrgVisible([]*User{org}, owner)
|
||||||
|
test2 := HasOrgVisible([]*User{org}, user3)
|
||||||
|
test3 := HasOrgVisible([]*User{org}, nil)
|
||||||
|
assert.Equal(t, test1, true) // owner of org
|
||||||
|
assert.Equal(t, test2, true) // user not a part of org
|
||||||
|
assert.Equal(t, test3, true) // logged out user
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHasOrgVisibleTypeLimited(t *testing.T) {
|
||||||
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
|
owner := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||||
|
user3 := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User)
|
||||||
|
|
||||||
|
const newOrgName = "test-org-limited"
|
||||||
|
org := &User{
|
||||||
|
Name: newOrgName,
|
||||||
|
Visibility: VisibleTypeLimited,
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertNotExistsBean(t, &User{Name: org.Name, Type: UserTypeOrganization})
|
||||||
|
assert.NoError(t, CreateOrganization(org, owner))
|
||||||
|
org = AssertExistsAndLoadBean(t,
|
||||||
|
&User{Name: org.Name, Type: UserTypeOrganization}).(*User)
|
||||||
|
test1 := HasOrgVisible([]*User{org}, owner)
|
||||||
|
test2 := HasOrgVisible([]*User{org}, user3)
|
||||||
|
test3 := HasOrgVisible([]*User{org}, nil)
|
||||||
|
assert.Equal(t, test1, true) // owner of org
|
||||||
|
assert.Equal(t, test2, true) // user not a part of org
|
||||||
|
assert.Equal(t, test3, false) // logged out user
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHasOrgVisibleTypePrivate(t *testing.T) {
|
||||||
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
|
owner := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
|
||||||
|
user3 := AssertExistsAndLoadBean(t, &User{ID: 3}).(*User)
|
||||||
|
|
||||||
|
const newOrgName = "test-org-private"
|
||||||
|
org := &User{
|
||||||
|
Name: newOrgName,
|
||||||
|
Visibility: VisibleTypePrivate,
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertNotExistsBean(t, &User{Name: org.Name, Type: UserTypeOrganization})
|
||||||
|
assert.NoError(t, CreateOrganization(org, owner))
|
||||||
|
org = AssertExistsAndLoadBean(t,
|
||||||
|
&User{Name: org.Name, Type: UserTypeOrganization}).(*User)
|
||||||
|
test1 := HasOrgVisible([]*User{org}, owner)
|
||||||
|
test2 := HasOrgVisible([]*User{org}, user3)
|
||||||
|
test3 := HasOrgVisible([]*User{org}, nil)
|
||||||
|
assert.Equal(t, test1, true) // owner of org
|
||||||
|
assert.Equal(t, test2, false) // user not a part of org
|
||||||
|
assert.Equal(t, test3, false) // logged out user
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -73,6 +74,20 @@ var (
|
||||||
ErrUnsupportedLoginType = errors.New("Login source is unknown")
|
ErrUnsupportedLoginType = errors.New("Login source is unknown")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// VisibleType define the visibility (Organization only)
|
||||||
|
type VisibleType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// VisibleTypePublic Visible for everyone
|
||||||
|
VisibleTypePublic VisibleType = iota + 1
|
||||||
|
|
||||||
|
// VisibleTypeLimited Visible for every connected user
|
||||||
|
VisibleTypeLimited
|
||||||
|
|
||||||
|
// VisibleTypePrivate Visible only for organization's members
|
||||||
|
VisibleTypePrivate
|
||||||
|
)
|
||||||
|
|
||||||
// User represents the object of individual and member of organization.
|
// User represents the object of individual and member of organization.
|
||||||
type User struct {
|
type User struct {
|
||||||
ID int64 `xorm:"pk autoincr"`
|
ID int64 `xorm:"pk autoincr"`
|
||||||
|
@ -128,8 +143,9 @@ type User struct {
|
||||||
Description string
|
Description string
|
||||||
NumTeams int
|
NumTeams int
|
||||||
NumMembers int
|
NumMembers int
|
||||||
Teams []*Team `xorm:"-"`
|
Teams []*Team `xorm:"-"`
|
||||||
Members []*User `xorm:"-"`
|
Members []*User `xorm:"-"`
|
||||||
|
Visibility VisibleType `xorm:"DEFAULT 1"`
|
||||||
|
|
||||||
// Preferences
|
// Preferences
|
||||||
DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"`
|
DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"`
|
||||||
|
@ -530,6 +546,16 @@ func (u *User) IsUserOrgOwner(orgID int64) bool {
|
||||||
return isOwner
|
return isOwner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsUserOrgPartOf returns true if user is part of the organization
|
||||||
|
func (u *User) IsUserOrgPartOf(userID int64) bool {
|
||||||
|
isMember, err := IsOrganizationMember(u.ID, userID)
|
||||||
|
if err != nil {
|
||||||
|
log.Error(4, "IsOrganizationMember: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return isMember
|
||||||
|
}
|
||||||
|
|
||||||
// IsPublicMember returns true if user public his/her membership in given organization.
|
// IsPublicMember returns true if user public his/her membership in given organization.
|
||||||
func (u *User) IsPublicMember(orgID int64) bool {
|
func (u *User) IsPublicMember(orgID int64) bool {
|
||||||
isMember, err := IsPublicMembership(orgID, u.ID)
|
isMember, err := IsPublicMembership(orgID, u.ID)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -35,6 +36,7 @@ type UpdateOrgSettingForm struct {
|
||||||
Description string `binding:"MaxSize(255)"`
|
Description string `binding:"MaxSize(255)"`
|
||||||
Website string `binding:"ValidUrl;MaxSize(255)"`
|
Website string `binding:"ValidUrl;MaxSize(255)"`
|
||||||
Location string `binding:"MaxSize(50)"`
|
Location string `binding:"MaxSize(50)"`
|
||||||
|
Visibility models.VisibleType
|
||||||
MaxRepoCreation int
|
MaxRepoCreation int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1164,6 +1164,8 @@ func NewContext() {
|
||||||
|
|
||||||
// Service settings
|
// Service settings
|
||||||
var Service struct {
|
var Service struct {
|
||||||
|
DefaultVisibility string
|
||||||
|
DefaultVisibilityMode int
|
||||||
ActiveCodeLives int
|
ActiveCodeLives int
|
||||||
ResetPwdCodeLives int
|
ResetPwdCodeLives int
|
||||||
RegisterEmailConfirm bool
|
RegisterEmailConfirm bool
|
||||||
|
@ -1193,6 +1195,12 @@ var Service struct {
|
||||||
OpenIDBlacklist []*regexp.Regexp
|
OpenIDBlacklist []*regexp.Regexp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var visibilityModes = map[string]int{
|
||||||
|
"public": 1,
|
||||||
|
"limited": 2,
|
||||||
|
"private": 3,
|
||||||
|
}
|
||||||
|
|
||||||
func newService() {
|
func newService() {
|
||||||
sec := Cfg.Section("service")
|
sec := Cfg.Section("service")
|
||||||
Service.ActiveCodeLives = sec.Key("ACTIVE_CODE_LIVE_MINUTES").MustInt(180)
|
Service.ActiveCodeLives = sec.Key("ACTIVE_CODE_LIVE_MINUTES").MustInt(180)
|
||||||
|
@ -1216,6 +1224,8 @@ func newService() {
|
||||||
Service.DefaultEnableDependencies = sec.Key("DEFAULT_ENABLE_DEPENDENCIES").MustBool(true)
|
Service.DefaultEnableDependencies = sec.Key("DEFAULT_ENABLE_DEPENDENCIES").MustBool(true)
|
||||||
Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true)
|
Service.DefaultAllowOnlyContributorsToTrackTime = sec.Key("DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME").MustBool(true)
|
||||||
Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply.example.org")
|
Service.NoReplyAddress = sec.Key("NO_REPLY_ADDRESS").MustString("noreply.example.org")
|
||||||
|
Service.DefaultVisibility = sec.Key("DEFAULT_VISIBILITY").In("public", []string{"public", "limited", "private"})
|
||||||
|
Service.DefaultVisibilityMode = visibilityModes[Service.DefaultVisibility]
|
||||||
|
|
||||||
sec = Cfg.Section("openid")
|
sec = Cfg.Section("openid")
|
||||||
Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(!InstallLock)
|
Service.EnableOpenIDSignIn = sec.Key("ENABLE_OPENID_SIGNIN").MustBool(!InstallLock)
|
||||||
|
|
|
@ -1227,6 +1227,11 @@ settings.options = Organization
|
||||||
settings.full_name = Full Name
|
settings.full_name = Full Name
|
||||||
settings.website = Website
|
settings.website = Website
|
||||||
settings.location = Location
|
settings.location = Location
|
||||||
|
settings.visibility = Visibility
|
||||||
|
settings.visibility.public = Public
|
||||||
|
settings.visibility.limited = Limited (Visible to logged in users only)
|
||||||
|
settings.visibility.private = Private (Visible only to organization members)
|
||||||
|
|
||||||
settings.update_settings = Update Settings
|
settings.update_settings = Update Settings
|
||||||
settings.update_setting_success = Organization settings have been updated.
|
settings.update_setting_success = Organization settings have been updated.
|
||||||
settings.change_orgname_prompt = Note: changing the organization name also changes the organization's URL.
|
settings.change_orgname_prompt = Note: changing the organization name also changes the organization's URL.
|
||||||
|
@ -1526,6 +1531,7 @@ config.enable_timetracking = Enable Time Tracking
|
||||||
config.default_enable_timetracking = Enable Time Tracking by Default
|
config.default_enable_timetracking = Enable Time Tracking by Default
|
||||||
config.default_allow_only_contributors_to_track_time = Let Only Contributors Track Time
|
config.default_allow_only_contributors_to_track_time = Let Only Contributors Track Time
|
||||||
config.no_reply_address = Hidden Email Domain
|
config.no_reply_address = Hidden Email Domain
|
||||||
|
config.default_visibility_organization = Default visibility for new Organizations
|
||||||
config.default_enable_dependencies = Enable Issue Dependencies by Default
|
config.default_enable_dependencies = Enable Issue Dependencies by Default
|
||||||
|
|
||||||
config.webhook_config = Webhook Configuration
|
config.webhook_config = Webhook Configuration
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2015 The Gogs Authors. All rights reserved.
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -78,6 +79,11 @@ func Get(ctx *context.APIContext) {
|
||||||
// responses:
|
// responses:
|
||||||
// "200":
|
// "200":
|
||||||
// "$ref": "#/responses/Organization"
|
// "$ref": "#/responses/Organization"
|
||||||
|
canSeeOrg := models.HasOrgVisible([]*models.User{ctx.Org.Organization}, ctx.User)
|
||||||
|
if !canSeeOrg {
|
||||||
|
ctx.NotFound("HasOrgVisible", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
ctx.JSON(200, convert.ToOrganization(ctx.Org.Organization))
|
ctx.JSON(200, convert.ToOrganization(ctx.Org.Organization))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -257,6 +258,12 @@ func CreateOrgRepo(ctx *context.APIContext, opt api.CreateRepoOption) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canSeeOrg := models.HasOrgVisible([]*models.User{org}, ctx.User)
|
||||||
|
if !canSeeOrg {
|
||||||
|
ctx.NotFound("HasOrgVisible", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if !ctx.User.IsAdmin {
|
if !ctx.User.IsAdmin {
|
||||||
isOwner, err := org.IsOwnedBy(ctx.User.ID)
|
isOwner, err := org.IsOwnedBy(ctx.User.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -23,6 +24,7 @@ const (
|
||||||
// Create render the page for create organization
|
// Create render the page for create organization
|
||||||
func Create(ctx *context.Context) {
|
func Create(ctx *context.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("new_org")
|
ctx.Data["Title"] = ctx.Tr("new_org")
|
||||||
|
ctx.Data["DefaultVisibilityMode"] = setting.Service.DefaultVisibilityMode
|
||||||
if !ctx.User.CanCreateOrganization() {
|
if !ctx.User.CanCreateOrganization() {
|
||||||
ctx.ServerError("Not allowed", errors.New(ctx.Tr("org.form.create_org_not_allowed")))
|
ctx.ServerError("Not allowed", errors.New(ctx.Tr("org.form.create_org_not_allowed")))
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -29,6 +30,7 @@ const (
|
||||||
func Settings(ctx *context.Context) {
|
func Settings(ctx *context.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("org.settings")
|
ctx.Data["Title"] = ctx.Tr("org.settings")
|
||||||
ctx.Data["PageIsSettingsOptions"] = true
|
ctx.Data["PageIsSettingsOptions"] = true
|
||||||
|
ctx.Data["CurrentVisibility"] = models.VisibleType(ctx.Org.Organization.Visibility)
|
||||||
ctx.HTML(200, tplSettingsOptions)
|
ctx.HTML(200, tplSettingsOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +81,7 @@ func SettingsPost(ctx *context.Context, form auth.UpdateOrgSettingForm) {
|
||||||
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.Visibility = form.Visibility
|
||||||
if err := models.UpdateUser(org); err != nil {
|
if err := models.UpdateUser(org); err != nil {
|
||||||
ctx.ServerError("UpdateUser", err)
|
ctx.ServerError("UpdateUser", err)
|
||||||
return
|
return
|
||||||
|
|
|
@ -276,6 +276,12 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
|
||||||
|
|
||||||
// Home render repository home page
|
// Home render repository home page
|
||||||
func Home(ctx *context.Context) {
|
func Home(ctx *context.Context) {
|
||||||
|
|
||||||
|
canSeeOrg := models.HasOrgVisible([]*models.User{ctx.Repo.Repository.Owner}, ctx.User)
|
||||||
|
if !canSeeOrg {
|
||||||
|
ctx.NotFound("HasOrgVisible", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
if len(ctx.Repo.Repository.Units) > 0 {
|
if len(ctx.Repo.Repository.Units) > 0 {
|
||||||
var firstUnit *models.Unit
|
var firstUnit *models.Unit
|
||||||
for _, repoUnit := range ctx.Repo.Repository.Units {
|
for _, repoUnit := range ctx.Repo.Repository.Units {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -362,6 +363,13 @@ func showOrgProfile(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
org := ctx.Org.Organization
|
org := ctx.Org.Organization
|
||||||
|
|
||||||
|
canSeeOrg := models.HasOrgVisible([]*models.User{org}, ctx.User)
|
||||||
|
if !canSeeOrg {
|
||||||
|
ctx.NotFound("HasOrgVisible", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
ctx.Data["Title"] = org.DisplayName()
|
ctx.Data["Title"] = org.DisplayName()
|
||||||
|
|
||||||
page := ctx.QueryInt("page")
|
page := ctx.QueryInt("page")
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2015 The Gogs Authors. All rights reserved.
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a MIT-style
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -96,6 +97,7 @@ func Profile(ctx *context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Data["Orgs"] = orgs
|
ctx.Data["Orgs"] = orgs
|
||||||
|
ctx.Data["HasOrgsVisible"] = models.HasOrgVisible(orgs, ctx.User)
|
||||||
|
|
||||||
tab := ctx.Query("tab")
|
tab := ctx.Query("tab")
|
||||||
ctx.Data["TabName"] = tab
|
ctx.Data["TabName"] = tab
|
||||||
|
|
|
@ -148,6 +148,9 @@
|
||||||
<dt>{{.i18n.Tr "admin.config.default_allow_only_contributors_to_track_time"}}</dt>
|
<dt>{{.i18n.Tr "admin.config.default_allow_only_contributors_to_track_time"}}</dt>
|
||||||
<dd><i class="fa fa{{if .Service.DefaultAllowOnlyContributorsToTrackTime}}-check{{end}}-square-o"></i></dd>
|
<dd><i class="fa fa{{if .Service.DefaultAllowOnlyContributorsToTrackTime}}-check{{end}}-square-o"></i></dd>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
<dt>{{.i18n.Tr "admin.config.default_visibility_organization"}}</dt>
|
||||||
|
<dd>{{.Service.DefaultVisibility}}</dd>
|
||||||
|
|
||||||
<dt>{{.i18n.Tr "admin.config.no_reply_address"}}</dt>
|
<dt>{{.i18n.Tr "admin.config.no_reply_address"}}</dt>
|
||||||
<dd>{{if .Service.NoReplyAddress}}{{.Service.NoReplyAddress}}{{else}}-{{end}}</dd>
|
<dd>{{if .Service.NoReplyAddress}}{{.Service.NoReplyAddress}}{{else}}-{{end}}</dd>
|
||||||
<dt>{{.i18n.Tr "admin.config.default_enable_dependencies"}}</dt>
|
<dt>{{.i18n.Tr "admin.config.default_enable_dependencies"}}</dt>
|
||||||
|
|
|
@ -29,7 +29,12 @@
|
||||||
{{range .Users}}
|
{{range .Users}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{.ID}}</td>
|
<td>{{.ID}}</td>
|
||||||
<td><a href="{{.HomeLink}}">{{.Name}}</a></td>
|
<td>
|
||||||
|
<a href="{{.HomeLink}}">{{.Name}}</a>
|
||||||
|
{{if eq .Visibility 3}}
|
||||||
|
<span class="text gold"><i class="octicon octicon-lock"></i></span>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
<td>{{.NumTeams}}</td>
|
<td>{{.NumTeams}}</td>
|
||||||
<td>{{.NumMembers}}</td>
|
<td>{{.NumMembers}}</td>
|
||||||
<td>{{.NumRepos}}</td>
|
<td>{{.NumRepos}}</td>
|
||||||
|
|
|
@ -30,7 +30,12 @@
|
||||||
{{range .Repos}}
|
{{range .Repos}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{.ID}}</td>
|
<td>{{.ID}}</td>
|
||||||
<td><a href="{{AppSubUrl}}/{{.Owner.Name}}">{{.Owner.Name}}</a></td>
|
<td>
|
||||||
|
<a href="{{AppSubUrl}}/{{.Owner.Name}}">{{.Owner.Name}}</a>
|
||||||
|
{{if eq .Owner.Visibility 3}}
|
||||||
|
<span class="text gold"><i class="octicon octicon-lock"></i></span>
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
<td><a href="{{AppSubUrl}}/{{.Owner.Name}}/{{.Name}}">{{.Name}}</a></td>
|
<td><a href="{{AppSubUrl}}/{{.Owner.Name}}/{{.Name}}">{{.Name}}</a></td>
|
||||||
<td><i class="fa fa{{if .IsPrivate}}-check{{end}}-square-o"></i></td>
|
<td><i class="fa fa{{if .IsPrivate}}-check{{end}}-square-o"></i></td>
|
||||||
<td>{{.NumWatches}}</td>
|
<td>{{.NumWatches}}</td>
|
||||||
|
|
|
@ -6,10 +6,16 @@
|
||||||
|
|
||||||
<div class="ui user list">
|
<div class="ui user list">
|
||||||
{{range .Users}}
|
{{range .Users}}
|
||||||
|
{{if (or (eq .Visibility 1) (and ($.SignedUser) (or (eq .Visibility 2) (and (.IsUserOrgPartOf $.SignedUserID) (eq .Visibility 3)) ($.IsAdmin))))}}
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<img class="ui avatar image" src="{{.RelAvatarLink}}">
|
<img class="ui avatar image" src="{{.RelAvatarLink}}">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<span class="header"><a href="{{.HomeLink}}">{{.Name}}</a> {{.FullName}}</span>
|
<span class="header">
|
||||||
|
<a href="{{.HomeLink}}">{{.Name}}</a> {{.FullName}}
|
||||||
|
{{if eq .Visibility 3}}
|
||||||
|
<span class="text gold"><i class="octicon octicon-lock"></i></span>
|
||||||
|
{{end}}
|
||||||
|
</span>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
{{if .Location}}
|
{{if .Location}}
|
||||||
<i class="octicon octicon-location"></i> {{.Location}}
|
<i class="octicon octicon-location"></i> {{.Location}}
|
||||||
|
@ -22,6 +28,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<div>{{$.i18n.Tr "explore.org_no_results"}}</div>
|
<div>{{$.i18n.Tr "explore.org_no_results"}}</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
|
@ -9,12 +9,19 @@
|
||||||
<span><i class="octicon octicon-repo-forked"></i></span>
|
<span><i class="octicon octicon-repo-forked"></i></span>
|
||||||
{{else if .IsMirror}}
|
{{else if .IsMirror}}
|
||||||
<span><i class="octicon octicon-repo-clone"></i></span>
|
<span><i class="octicon octicon-repo-clone"></i></span>
|
||||||
|
{{else if .Owner}}
|
||||||
|
{{if eq .Owner.Visibility 3}}
|
||||||
|
<span class="text gold"><i class="octicon octicon-lock"></i></span>
|
||||||
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
<div class="ui right metas">
|
<div class="ui right metas">
|
||||||
<span class="text grey"><i class="octicon octicon-star"></i> {{.NumStars}}</span>
|
<span class="text grey"><i class="octicon octicon-star"></i> {{.NumStars}}</span>
|
||||||
<span class="text grey"><i class="octicon octicon-git-branch"></i> {{.NumForks}}</span>
|
<span class="text grey"><i class="octicon octicon-git-branch"></i> {{.NumForks}}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{{if .DescriptionHTML}}<p class="has-emoji">{{.DescriptionHTML}}</p>{{end}}
|
||||||
|
<p class="time">{{$.i18n.Tr "org.repo_updated"}} {{TimeSinceUnix .UpdatedUnix $.i18n.Lang}}</p>
|
||||||
</div>
|
</div>
|
||||||
{{if .DescriptionHTML}}<p class="has-emoji">{{.DescriptionHTML}}</p>{{end}}
|
{{if .DescriptionHTML}}<p class="has-emoji">{{.DescriptionHTML}}</p>{{end}}
|
||||||
{{if .Topics }}
|
{{if .Topics }}
|
||||||
|
|
|
@ -15,6 +15,28 @@
|
||||||
<span class="help">{{.i18n.Tr "org.org_name_helper"}}</span>
|
<span class="help">{{.i18n.Tr "org.org_name_helper"}}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="inline required field {{if .Err_OrgVisibility}}error{{end}}">
|
||||||
|
<label for="visibility">{{.i18n.Tr "org.settings.visibility"}}</label>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui radio checkbox">
|
||||||
|
<input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="1" {{if eq .DefaultVisibilityMode 1}}checked{{end}}/>
|
||||||
|
<label>{{.i18n.Tr "org.settings.visibility.public"}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui radio checkbox">
|
||||||
|
<input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="2" {{if eq .DefaultVisibilityMode 2}}checked{{end}}/>
|
||||||
|
<label>{{.i18n.Tr "org.settings.visibility.limited"}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui radio checkbox">
|
||||||
|
<input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="3" {{if eq .DefaultVisibilityMode 3}}checked{{end}}/>
|
||||||
|
<label>{{.i18n.Tr "org.settings.visibility.private"}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="inline field">
|
<div class="inline field">
|
||||||
<label></label>
|
<label></label>
|
||||||
<button class="ui green button">
|
<button class="ui green button">
|
||||||
|
|
|
@ -33,6 +33,29 @@
|
||||||
<input id="location" name="location" value="{{.Org.Location}}">
|
<input id="location" name="location" value="{{.Org.Location}}">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="ui divider"></div>
|
||||||
|
<div class="field" id="visibility_box">
|
||||||
|
<label for="visibility">{{.i18n.Tr "org.settings.visibility"}}</label>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui radio checkbox">
|
||||||
|
<input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="1" {{if eq .CurrentVisibility 1}}checked{{end}}/>
|
||||||
|
<label>{{.i18n.Tr "org.settings.visibility.public"}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui radio checkbox">
|
||||||
|
<input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="2" {{if eq .CurrentVisibility 2}}checked{{end}}/>
|
||||||
|
<label>{{.i18n.Tr "org.settings.visibility.limited"}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<div class="ui radio checkbox">
|
||||||
|
<input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="3" {{if eq .CurrentVisibility 3}}checked{{end}}/>
|
||||||
|
<label>{{.i18n.Tr "org.settings.visibility.private"}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{if .SignedUser.IsAdmin}}
|
{{if .SignedUser.IsAdmin}}
|
||||||
<div class="ui divider"></div>
|
<div class="ui divider"></div>
|
||||||
|
|
||||||
|
|
|
@ -61,10 +61,12 @@
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
*/}}
|
*/}}
|
||||||
{{if .Orgs}}
|
{{if and .Orgs .HasOrgsVisible}}
|
||||||
<li>
|
<li>
|
||||||
{{range .Orgs}}
|
{{range .Orgs}}
|
||||||
<a href="{{.HomeLink}}"><img class="ui mini image poping up" src="{{.RelAvatarLink}}" data-content="{{.Name}}" data-position="top center" data-variation="tiny inverted"></a>
|
{{if (or (eq .Visibility 1) (and ($.SignedUser) (or (eq .Visibility 2) (and (.IsUserOrgPartOf $.SignedUserID) (eq .Visibility 3)) ($.IsAdmin))))}}
|
||||||
|
<a href="{{.HomeLink}}"><img class="ui mini image poping up" src="{{.RelAvatarLink}}" data-content="{{.Name}}" data-position="top center" data-variation="tiny inverted"></a>
|
||||||
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
</li>
|
</li>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user