@@ -16,16 +16,18 @@ import (
1616
1717	git_model "code.gitea.io/gitea/models/git" 
1818	repo_model "code.gitea.io/gitea/models/repo" 
19- 	"code.gitea.io/gitea/models/unit" 
2019	"code.gitea.io/gitea/modules/git" 
2120	"code.gitea.io/gitea/modules/gitrepo" 
2221	"code.gitea.io/gitea/modules/httpcache" 
22+ 	"code.gitea.io/gitea/modules/json" 
2323	"code.gitea.io/gitea/modules/lfs" 
2424	"code.gitea.io/gitea/modules/log" 
2525	"code.gitea.io/gitea/modules/setting" 
2626	"code.gitea.io/gitea/modules/storage" 
2727	api "code.gitea.io/gitea/modules/structs" 
28+ 	"code.gitea.io/gitea/modules/util" 
2829	"code.gitea.io/gitea/modules/web" 
30+ 	"code.gitea.io/gitea/routers/api/v1/utils" 
2931	"code.gitea.io/gitea/routers/common" 
3032	"code.gitea.io/gitea/services/context" 
3133	pull_service "code.gitea.io/gitea/services/pull" 
@@ -375,7 +377,7 @@ func GetEditorconfig(ctx *context.APIContext) {
375377	//   required: true 
376378	// - name: ref 
377379	//   in: query 
378- 	//   description: "The name of the commit/branch/tag. Default the repository’s default branch (usually master) " 
380+ 	//   description: "The name of the commit/branch/tag. Default to  the repository’s default branch. " 
379381	//   type: string 
380382	//   required: false 
381383	// responses: 
@@ -410,11 +412,6 @@ func canWriteFiles(ctx *context.APIContext, branch string) bool {
410412		! ctx .Repo .Repository .IsArchived 
411413}
412414
413- // canReadFiles returns true if repository is readable and user has proper access level. 
414- func  canReadFiles (r  * context.Repository ) bool  {
415- 	return  r .Permission .CanRead (unit .TypeCode )
416- }
417- 
418415func  base64Reader (s  string ) (io.ReadSeeker , error ) {
419416	b , err  :=  base64 .StdEncoding .DecodeString (s )
420417	if  err  !=  nil  {
@@ -894,6 +891,17 @@ func DeleteFile(ctx *context.APIContext) {
894891	}
895892}
896893
894+ func  resolveRefCommit (ctx  * context.APIContext , ref  string , minCommitIDLen  ... int ) * utils.RefCommit  {
895+ 	ref  =  util .IfZero (ref , ctx .Repo .Repository .DefaultBranch )
896+ 	refCommit , err  :=  utils .ResolveRefCommit (ctx , ctx .Repo .Repository , ref , minCommitIDLen ... )
897+ 	if  errors .Is (err , util .ErrNotExist ) {
898+ 		ctx .APIErrorNotFound (err )
899+ 	} else  if  err  !=  nil  {
900+ 		ctx .APIErrorInternal (err )
901+ 	}
902+ 	return  refCommit 
903+ }
904+ 
897905// GetContents Get the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir 
898906func  GetContents (ctx  * context.APIContext ) {
899907	// swagger:operation GET /repos/{owner}/{repo}/contents/{filepath} repository repoGetContents 
@@ -919,7 +927,7 @@ func GetContents(ctx *context.APIContext) {
919927	//   required: true 
920928	// - name: ref 
921929	//   in: query 
922- 	//   description: "The name of the commit/branch/tag. Default the repository’s default branch (usually master) " 
930+ 	//   description: "The name of the commit/branch/tag. Default to  the repository’s default branch. " 
923931	//   type: string 
924932	//   required: false 
925933	// responses: 
@@ -928,18 +936,13 @@ func GetContents(ctx *context.APIContext) {
928936	//   "404": 
929937	//     "$ref": "#/responses/notFound" 
930938
931- 	if  ! canReadFiles (ctx .Repo ) {
932- 		ctx .APIErrorInternal (repo_model.ErrUserDoesNotHaveAccessToRepo {
933- 			UserID :   ctx .Doer .ID ,
934- 			RepoName : ctx .Repo .Repository .LowerName ,
935- 		})
939+ 	treePath  :=  ctx .PathParam ("*" )
940+ 	refCommit  :=  resolveRefCommit (ctx , ctx .FormTrim ("ref" ))
941+ 	if  ctx .Written () {
936942		return 
937943	}
938944
939- 	treePath  :=  ctx .PathParam ("*" )
940- 	ref  :=  ctx .FormTrim ("ref" )
941- 
942- 	if  fileList , err  :=  files_service .GetContentsOrList (ctx , ctx .Repo .Repository , treePath , ref ); err  !=  nil  {
945+ 	if  fileList , err  :=  files_service .GetContentsOrList (ctx , ctx .Repo .Repository , refCommit , treePath ); err  !=  nil  {
943946		if  git .IsErrNotExist (err ) {
944947			ctx .APIErrorNotFound ("GetContentsOrList" , err )
945948			return 
@@ -970,7 +973,7 @@ func GetContentsList(ctx *context.APIContext) {
970973	//   required: true 
971974	// - name: ref 
972975	//   in: query 
973- 	//   description: "The name of the commit/branch/tag. Default the repository’s default branch (usually master) " 
976+ 	//   description: "The name of the commit/branch/tag. Default to  the repository’s default branch. " 
974977	//   type: string 
975978	//   required: false 
976979	// responses: 
@@ -982,3 +985,102 @@ func GetContentsList(ctx *context.APIContext) {
982985	// same as GetContents(), this function is here because swagger fails if path is empty in GetContents() interface 
983986	GetContents (ctx )
984987}
988+ 
989+ func  GetFileContentsGet (ctx  * context.APIContext ) {
990+ 	// swagger:operation GET /repos/{owner}/{repo}/file-contents repository repoGetFileContents 
991+ 	// --- 
992+ 	// summary: Get the metadata and contents of requested files 
993+ 	// description: See the POST method. This GET method supports to use JSON encoded request body in query parameter. 
994+ 	// produces: 
995+ 	// - application/json 
996+ 	// parameters: 
997+ 	// - name: owner 
998+ 	//   in: path 
999+ 	//   description: owner of the repo 
1000+ 	//   type: string 
1001+ 	//   required: true 
1002+ 	// - name: repo 
1003+ 	//   in: path 
1004+ 	//   description: name of the repo 
1005+ 	//   type: string 
1006+ 	//   required: true 
1007+ 	// - name: ref 
1008+ 	//   in: query 
1009+ 	//   description: "The name of the commit/branch/tag. Default to the repository’s default branch." 
1010+ 	//   type: string 
1011+ 	//   required: false 
1012+ 	// - name: body 
1013+ 	//   in: query 
1014+ 	//   description: "The JSON encoded body (see the POST request): {\"files\": [\"filename1\", \"filename2\"]}" 
1015+ 	//   type: string 
1016+ 	//   required: true 
1017+ 	// responses: 
1018+ 	//   "200": 
1019+ 	//     "$ref": "#/responses/ContentsListResponse" 
1020+ 	//   "404": 
1021+ 	//     "$ref": "#/responses/notFound" 
1022+ 
1023+ 	// POST method requires "write" permission, so we also support this "GET" method 
1024+ 	handleGetFileContents (ctx )
1025+ }
1026+ 
1027+ func  GetFileContentsPost (ctx  * context.APIContext ) {
1028+ 	// swagger:operation POST /repos/{owner}/{repo}/file-contents repository repoGetFileContentsPost 
1029+ 	// --- 
1030+ 	// summary: Get the metadata and contents of requested files 
1031+ 	// description: Uses automatic pagination based on default page size and 
1032+ 	// 							max response size and returns the maximum allowed number of files. 
1033+ 	//							Files which could not be retrieved are null. Files which are too large 
1034+ 	//							are being returned with `encoding == null`, `content == null` and `size > 0`, 
1035+ 	//							they can be requested separately by using the `download_url`. 
1036+ 	// produces: 
1037+ 	// - application/json 
1038+ 	// parameters: 
1039+ 	// - name: owner 
1040+ 	//   in: path 
1041+ 	//   description: owner of the repo 
1042+ 	//   type: string 
1043+ 	//   required: true 
1044+ 	// - name: repo 
1045+ 	//   in: path 
1046+ 	//   description: name of the repo 
1047+ 	//   type: string 
1048+ 	//   required: true 
1049+ 	// - name: ref 
1050+ 	//   in: query 
1051+ 	//   description: "The name of the commit/branch/tag. Default to the repository’s default branch." 
1052+ 	//   type: string 
1053+ 	//   required: false 
1054+ 	// - name: body 
1055+ 	//   in: body 
1056+ 	//   required: true 
1057+ 	//   schema: 
1058+ 	//     "$ref": "#/definitions/GetFilesOptions" 
1059+ 	// responses: 
1060+ 	//   "200": 
1061+ 	//     "$ref": "#/responses/ContentsListResponse" 
1062+ 	//   "404": 
1063+ 	//     "$ref": "#/responses/notFound" 
1064+ 
1065+ 	// This is actually a "read" request, but we need to accept a "files" list, then POST method seems easy to use. 
1066+ 	// But the permission system requires that the caller must have "write" permission to use POST method. 
1067+ 	// At the moment there is no other way to get around the permission check, so there is a "GET" workaround method above. 
1068+ 	handleGetFileContents (ctx )
1069+ }
1070+ 
1071+ func  handleGetFileContents (ctx  * context.APIContext ) {
1072+ 	opts , ok  :=  web .GetForm (ctx ).(* api.GetFilesOptions )
1073+ 	if  ! ok  {
1074+ 		err  :=  json .Unmarshal (util .UnsafeStringToBytes (ctx .FormString ("body" )), & opts )
1075+ 		if  err  !=  nil  {
1076+ 			ctx .APIError (http .StatusBadRequest , "invalid body parameter" )
1077+ 			return 
1078+ 		}
1079+ 	}
1080+ 	refCommit  :=  resolveRefCommit (ctx , ctx .FormTrim ("ref" ))
1081+ 	if  ctx .Written () {
1082+ 		return 
1083+ 	}
1084+ 	filesResponse  :=  files_service .GetContentsListFromTreePaths (ctx , ctx .Repo .Repository , refCommit , opts .Files )
1085+ 	ctx .JSON (http .StatusOK , util .SliceNilAsEmpty (filesResponse ))
1086+ }
0 commit comments