@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/structs"
)
)
@ -52,69 +53,84 @@ func packageAssignment(ctx *Context, errCb func(int, string, interface{})) {
Owner : ctx . ContextUser ,
Owner : ctx . ContextUser ,
}
}
var err error
ctx . Package . AccessMode , err = determineAccessMode ( ctx )
if err != nil {
errCb ( http . StatusInternalServerError , "determineAccessMode" , err )
return
}
packageType := ctx . Params ( "type" )
name := ctx . Params ( "name" )
version := ctx . Params ( "version" )
if packageType != "" && name != "" && version != "" {
pv , err := packages_model . GetVersionByNameAndVersion ( ctx , ctx . Package . Owner . ID , packages_model . Type ( packageType ) , name , version )
if err != nil {
if err == packages_model . ErrPackageNotExist {
errCb ( http . StatusNotFound , "GetVersionByNameAndVersion" , err )
} else {
errCb ( http . StatusInternalServerError , "GetVersionByNameAndVersion" , err )
}
return
}
ctx . Package . Descriptor , err = packages_model . GetPackageDescriptor ( ctx , pv )
if err != nil {
errCb ( http . StatusInternalServerError , "GetPackageDescriptor" , err )
return
}
}
}
func determineAccessMode ( ctx * Context ) ( perm . AccessMode , error ) {
accessMode := perm . AccessModeNone
if setting . Service . RequireSignInView && ctx . Doer == nil {
return accessMode , nil
}
if ctx . Package . Owner . IsOrganization ( ) {
if ctx . Package . Owner . IsOrganization ( ) {
org := organization . OrgFromUser ( ctx . Package . Owner )
org := organization . OrgFromUser ( ctx . Package . Owner )
// 1. Get user max authorize level for the org (may be none, if user is not member of the org)
// 1. Get user max authorize level for the org (may be none, if user is not member of the org)
if ctx . Doer != nil {
if ctx . Doer != nil {
var err error
var err error
ctx . Package . AccessMode , err = org . GetOrgUserMaxAuthorizeLevel ( ctx . Doer . ID )
a ccessMode, err = org . GetOrgUserMaxAuthorizeLevel ( ctx . Doer . ID )
if err != nil {
if err != nil {
errCb ( http . StatusInternalServerError , "GetOrgUserMaxAuthorizeLevel" , err )
return accessMode , err
return
}
}
// If access mode is less than write check every team for more permissions
// If access mode is less than write check every team for more permissions
if ctx . Package . AccessMode < perm . AccessModeWrite {
if a ccessMode < perm . AccessModeWrite {
teams , err := organization . GetUserOrgTeams ( ctx , org . ID , ctx . Doer . ID )
teams , err := organization . GetUserOrgTeams ( ctx , org . ID , ctx . Doer . ID )
if err != nil {
if err != nil {
errCb ( http . StatusInternalServerError , "GetUserOrgTeams" , err )
return accessMode , err
return
}
}
for _ , t := range teams {
for _ , t := range teams {
perm := t . UnitAccessModeCtx ( ctx , unit . TypePackages )
perm := t . UnitAccessModeCtx ( ctx , unit . TypePackages )
if ctx . Package . AccessMode < perm {
if a ccessMode < perm {
ctx . Package . AccessMode = perm
a ccessMode = perm
}
}
}
}
}
}
}
}
// 2. If authorize level is none, check if org is visible to user
// 2. If authorize level is none, check if org is visible to user
if ctx . Package . AccessMode == perm . AccessModeNone && organization . HasOrgOrUserVisible ( ctx , ctx . Package . Owner , ctx . Doer ) {
if a ccessMode == perm . AccessModeNone && organization . HasOrgOrUserVisible ( ctx , ctx . Package . Owner , ctx . Doer ) {
ctx . Package . AccessMode = perm . AccessModeRead
a ccessMode = perm . AccessModeRead
}
}
} else {
} else {
if ctx . Doer != nil && ! ctx . Doer . IsGhost ( ) {
if ctx . Doer != nil && ! ctx . Doer . IsGhost ( ) {
// 1. Check if user is package owner
// 1. Check if user is package owner
if ctx . Doer . ID == ctx . Package . Owner . ID {
if ctx . Doer . ID == ctx . Package . Owner . ID {
ctx . Package . AccessMode = perm . AccessModeOwner
a ccessMode = perm . AccessModeOwner
} else if ctx . Package . Owner . Visibility == structs . VisibleTypePublic || ctx . Package . Owner . Visibility == structs . VisibleTypeLimited { // 2. Check if package owner is public or limited
} else if ctx . Package . Owner . Visibility == structs . VisibleTypePublic || ctx . Package . Owner . Visibility == structs . VisibleTypeLimited { // 2. Check if package owner is public or limited
ctx . Package . A ccessMode = perm . AccessModeRead
a ccessMode = perm . AccessModeRead
}
}
} else if ctx . Package . Owner . Visibility == structs . VisibleTypePublic { // 3. Check if package owner is public
} else if ctx . Package . Owner . Visibility == structs . VisibleTypePublic { // 3. Check if package owner is public
ctx . Package . A ccessMode = perm . AccessModeRead
a ccessMode = perm . AccessModeRead
}
}
}
}
packageType := ctx . Params ( "type" )
return accessMode , nil
name := ctx . Params ( "name" )
version := ctx . Params ( "version" )
if packageType != "" && name != "" && version != "" {
pv , err := packages_model . GetVersionByNameAndVersion ( ctx , ctx . Package . Owner . ID , packages_model . Type ( packageType ) , name , version )
if err != nil {
if err == packages_model . ErrPackageNotExist {
errCb ( http . StatusNotFound , "GetVersionByNameAndVersion" , err )
} else {
errCb ( http . StatusInternalServerError , "GetVersionByNameAndVersion" , err )
}
return
}
ctx . Package . Descriptor , err = packages_model . GetPackageDescriptor ( ctx , pv )
if err != nil {
errCb ( http . StatusInternalServerError , "GetPackageDescriptor" , err )
return
}
}
}
}
// PackageContexter initializes a package context for a request.
// PackageContexter initializes a package context for a request.