From d9c19899cd27c73dd1497c0da6bd00336d2182e6 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Thu, 7 Dec 2023 17:08:17 +0000 Subject: [PATCH 01/60] Make gogit Repository.GetBranchNames consistent (#28348) --- modules/git/repo_branch_gogit.go | 41 ++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/modules/git/repo_branch_gogit.go b/modules/git/repo_branch_gogit.go index f9896a7a09047..1c0d9a18aa9d9 100644 --- a/modules/git/repo_branch_gogit.go +++ b/modules/git/repo_branch_gogit.go @@ -8,6 +8,7 @@ package git import ( "context" + "sort" "strings" "github.com/go-git/go-git/v5/plumbing" @@ -52,32 +53,46 @@ func (repo *Repository) IsBranchExist(name string) bool { // GetBranches returns branches from the repository, skipping "skip" initial branches and // returning at most "limit" branches, or all branches if "limit" is 0. +// Branches are returned with sort of `-commiterdate` as the nogogit +// implementation. This requires full fetch, sort and then the +// skip/limit applies later as gogit returns in undefined order. func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) { - var branchNames []string + type BranchData struct { + name string + committerDate int64 + } + var branchData []BranchData - branches, err := repo.gogitRepo.Branches() + branchIter, err := repo.gogitRepo.Branches() if err != nil { return nil, 0, err } - i := 0 - count := 0 - _ = branches.ForEach(func(branch *plumbing.Reference) error { - count++ - if i < skip { - i++ - return nil - } else if limit != 0 && count > skip+limit { + _ = branchIter.ForEach(func(branch *plumbing.Reference) error { + obj, err := repo.gogitRepo.CommitObject(branch.Hash()) + if err != nil { + // skip branch if can't find commit return nil } - branchNames = append(branchNames, strings.TrimPrefix(branch.Name().String(), BranchPrefix)) + branchData = append(branchData, BranchData{strings.TrimPrefix(branch.Name().String(), BranchPrefix), obj.Committer.When.Unix()}) return nil }) - // TODO: Sort? + sort.Slice(branchData, func(i, j int) bool { + return !(branchData[i].committerDate < branchData[j].committerDate) + }) + + var branchNames []string + maxPos := len(branchData) + if limit > 0 { + maxPos = min(skip+limit, maxPos) + } + for i := skip; i < maxPos; i++ { + branchNames = append(branchNames, branchData[i].name) + } - return branchNames, count, nil + return branchNames, len(branchData), nil } // WalkReferences walks all the references from the repository From 4bf565358410c26a91447613dc0e930a6af87ff5 Mon Sep 17 00:00:00 2001 From: John Olheiser Date: Thu, 7 Dec 2023 11:42:58 -0600 Subject: [PATCH 02/60] Fix Docker meta action for releases (#28232) Should fix #28229 and #28230 for next release. Assuming I'm reading the docs correctly for the docker meta action: https://github.com/docker/metadata-action#flavor-input https://github.com/docker/metadata-action#latest-tag 1. We want `latest=false` for the RCs. 2. `latest` should happen already due to `auto` mode, however there's an extra option for the `suffix` flavor. This PR is ready, but leaving it as draft to make sure someone double-checks my sleuth-work. Signed-off-by: jolheiser --- .github/workflows/release-tag-rc.yml | 3 +++ .github/workflows/release-tag-version.yml | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-tag-rc.yml b/.github/workflows/release-tag-rc.yml index 02ec1a1b2dd0f..d73d67aede761 100644 --- a/.github/workflows/release-tag-rc.yml +++ b/.github/workflows/release-tag-rc.yml @@ -78,6 +78,8 @@ jobs: id: meta with: images: gitea/gitea + flavor: | + latest=false # 1.2.3-rc0 tags: | type=semver,pattern={{version}} @@ -109,6 +111,7 @@ jobs: images: gitea/gitea # each tag below will have the suffix of -rootless flavor: | + latest=false suffix=-rootless # 1.2.3-rc0 tags: | diff --git a/.github/workflows/release-tag-version.yml b/.github/workflows/release-tag-version.yml index 635507c48d087..0379350900a9e 100644 --- a/.github/workflows/release-tag-version.yml +++ b/.github/workflows/release-tag-version.yml @@ -86,7 +86,6 @@ jobs: # 1.2 # 1.2.3 tags: | - type=raw,value=latest type=semver,pattern={{major}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{version}} @@ -118,14 +117,13 @@ jobs: images: gitea/gitea # each tag below will have the suffix of -rootless flavor: | - suffix=-rootless + suffix=-rootless,onlatest=true # this will generate tags in the following format (with -rootless suffix added): # latest # 1 # 1.2 # 1.2.3 tags: | - type=raw,value=latest type=semver,pattern={{major}} type=semver,pattern={{major}}.{{minor}} type=semver,pattern={{version}} From 18ba1c6d004dedf11dff7fe4f5ae88b107d744e4 Mon Sep 17 00:00:00 2001 From: "Panagiotis \"Ivory\" Vasilopoulos" Date: Thu, 7 Dec 2023 22:38:55 +0000 Subject: [PATCH 03/60] Improve text in Security settings (#28393) - en-US: Rename "Scratch Tokens" to "single-use recovery keys". Longer, but clearer. - Improve titles - TOTP: Improve description - TOTP: Inform user about Scratch Tokens to encourage TOTP usage - WebAuthn: Add loss of access warning --- options/locale/locale_en-US.ini | 17 ++++++++++------- templates/user/settings/security/twofa.tmpl | 2 ++ templates/user/settings/security/webauthn.tmpl | 1 + 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 9c582a885013d..4f18606a45267 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -626,11 +626,11 @@ applications = Applications orgs = Manage Organizations repos = Repositories delete = Delete Account -twofa = Two-Factor Authentication +twofa = Two-Factor Authentication (TOTP) account_link = Linked Accounts organization = Organizations uid = UID -webauthn = Security Keys +webauthn = Two-Factor Authentication (Security Keys) public_profile = Public Profile biography_placeholder = Tell us a little bit about yourself! (You can use Markdown) @@ -864,22 +864,23 @@ revoke_oauth2_grant = Revoke Access revoke_oauth2_grant_description = Revoking access for this third party application will prevent this application from accessing your data. Are you sure? revoke_oauth2_grant_success = Access revoked successfully. -twofa_desc = Two-factor authentication enhances the security of your account. +twofa_desc = To protect your account against password theft, you can use a smartphone or another device for receiving time-based one-time passwords ("TOTP"). +twofa_recovery_tip = If you lose your device, you will be able to use a single-use recovery key to regain access to your account. twofa_is_enrolled = Your account is currently enrolled in two-factor authentication. twofa_not_enrolled = Your account is not currently enrolled in two-factor authentication. twofa_disable = Disable Two-Factor Authentication -twofa_scratch_token_regenerate = Regenerate Scratch Token -twofa_scratch_token_regenerated = Your scratch token is now %s. Store it in a safe place, it will never be shown again. +twofa_scratch_token_regenerate = Regenerate Single-Use Recovery Key +twofa_scratch_token_regenerated = Your single-use recovery key is now %s. Store it in a safe place, as it will not be shown again. twofa_enroll = Enroll into Two-Factor Authentication twofa_disable_note = You can disable two-factor authentication if needed. twofa_disable_desc = Disabling two-factor authentication will make your account less secure. Continue? -regenerate_scratch_token_desc = If you misplaced your scratch token or have already used it to sign in you can reset it here. +regenerate_scratch_token_desc = If you misplaced your recovery key or have already used it to sign in, you can reset it here. twofa_disabled = Two-factor authentication has been disabled. scan_this_image = Scan this image with your authentication application: or_enter_secret = Or enter the secret: %s then_enter_passcode = And enter the passcode shown in the application: passcode_invalid = The passcode is incorrect. Try again. -twofa_enrolled = Your account has been enrolled into two-factor authentication. Store your scratch token (%s) in a safe place as it is only shown once! +twofa_enrolled = Your account has been successfully enrolled. Store your single-use recovery key (%s) in a safe place, as it will not be shown again. twofa_failed_get_secret = Failed to get secret. webauthn_desc = Security keys are hardware devices containing cryptographic keys. They can be used for two-factor authentication. Security keys must support the WebAuthn Authenticator standard. @@ -887,6 +888,8 @@ webauthn_register_key = Add Security Key webauthn_nickname = Nickname webauthn_delete_key = Remove Security Key webauthn_delete_key_desc = If you remove a security key you can no longer sign in with it. Continue? +webauthn_key_loss_warning = If you lose your security keys, you will lose access to your account. +webauthn_alternative_tip = You may want to configure an additional authentication method. manage_account_links = Manage Linked Accounts manage_account_links_desc = These external accounts are linked to your Gitea account. diff --git a/templates/user/settings/security/twofa.tmpl b/templates/user/settings/security/twofa.tmpl index 9e58a647d2768..2f15fe13f1b5c 100644 --- a/templates/user/settings/security/twofa.tmpl +++ b/templates/user/settings/security/twofa.tmpl @@ -16,6 +16,8 @@ {{else}} + {{/* The recovery tip is there as a means of encouraging a user to enroll */}} +

{{ctx.Locale.Tr "settings.twofa_recovery_tip"}}

{{ctx.Locale.Tr "settings.twofa_not_enrolled"}}

{{ctx.Locale.Tr "settings.twofa_enroll"}} diff --git a/templates/user/settings/security/webauthn.tmpl b/templates/user/settings/security/webauthn.tmpl index 28d8511fb46c6..dd8b8a4e59cd8 100644 --- a/templates/user/settings/security/webauthn.tmpl +++ b/templates/user/settings/security/webauthn.tmpl @@ -1,6 +1,7 @@

{{ctx.Locale.Tr "settings.webauthn"}}

{{ctx.Locale.Tr "settings.webauthn_desc" | Str2html}}

+

{{ctx.Locale.Tr "settings.webauthn_key_loss_warning"}} {{ctx.Locale.Tr "settings.webauthn_alternative_tip"}}

{{template "user/auth/webauthn_error" .}}
{{range .WebAuthnCredentials}} From 80baac19f25b1527dda8c27e4db70bc3a377faf4 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sat, 9 Dec 2023 00:24:26 +0000 Subject: [PATCH 04/60] [skip ci] Updated translations via Crowdin --- options/locale/locale_fr-FR.ini | 12 +++--- options/locale/locale_lv-LV.ini | 67 ++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index 017444cbd091a..d2b90890dfa94 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -655,7 +655,7 @@ cancel=Annuler language=Langue ui=Thème hidden_comment_types=Catégories de commentaires masqués -hidden_comment_types_description=Les catégories cochées masquent les commentaires respectifs des tickets. Par exemple, « Label » cache les commentaires du genre « Cerise a attribué le label Bug il y a 2 heures. » +hidden_comment_types_description=Cochez les catégories suivantes pour masquer les commentaires correspondants des fils d'activité. Par exemple, « Label » cache les commentaires du genre « Cerise a attribué le label Bug il y a 2 heures. » hidden_comment_types.ref_tooltip=Commentaires où ce ticket a été référencé sur un autre ticket, révision, etc. hidden_comment_types.issue_ref_tooltip=Commentaires où l’utilisateur change la branche/étiquette associée au ticket comment_type_group_reference=Référence @@ -3227,7 +3227,7 @@ comment_pull=`a commenté la demande d’ajout %[3]s#%[2]s` merge_pull_request=`a fusionné la demande d’ajout %[3]s#%[2]s` auto_merge_pull_request=`a fusionné automatiquement la demande d’ajout %[3]s#%[2]s` transfer_repo=a transféré le dépôt %s vers %s -push_tag=a poussé l’étiquette %[3]s vers %[4]s +push_tag=a poussé l’étiquette %[3]s de %[4]s delete_tag=a supprimé l’étiquette %[2]s de %[3]s delete_branch=a supprimée la branche %[2]s de %[3]s compare_branch=Comparer @@ -3236,12 +3236,12 @@ compare_commits_general=Comparer les révisions mirror_sync_push=a synchronisé les révisions de %[3]s d’un miroir vers %[4]s. mirror_sync_create=a synchronisé la nouvelle référence %[3]s d’un miroir vers %[4]s. mirror_sync_delete=a synchronisé puis supprimé la nouvelle référence %[2]s vers %[3]s depuis le miroir -approve_pull_request=`a approuvé %[3]s#%[2]s.` +approve_pull_request=`a approuvé %[3]s#%[2]s` reject_pull_request=`a suggérés des changements pour %[3]s#%[2]s` -publish_release=`a publié "%[4]s" à %[3]s` -review_dismissed=`a révoqué l’évaluation de %[4]s sur %[3]s#%[2]s.` +publish_release=`a publié "%[4]s" dans %[3]s` +review_dismissed=`a révoqué l’évaluation de %[4]s dans %[3]s#%[2]s` review_dismissed_reason=Raison : -create_branch=a créé la branche %[3]s dans %[4]s. +create_branch=a créé la branche %[3]s dans %[4]s starred_repo=aime %[2]s watched_repo=observe %[2]s diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 1af1cc368564c..d0d4a39886011 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -3,7 +3,8 @@ dashboard=Infopanelis explore=Izpētīt help=Palīdzība logo=Logo -sign_in=Pierakstīties +sign_in=Pieteikties +sign_in_with_provider=Pieteikties ar %s sign_in_or=vai sign_out=Izrakstīties sign_up=Reģistrēties @@ -18,7 +19,7 @@ notifications=Paziņojumi active_stopwatch=Aktīvā laika uzskaite create_new=Izveidot… user_profile_and_more=Profils un iestatījumi… -signed_in_as=Pierakstījies kā +signed_in_as=Pieteicies kā enable_javascript=Šai lapas darbībai ir nepieciešams JavaScript. toc=Satura rādītājs licenses=Licences @@ -252,14 +253,14 @@ federated_avatar_lookup_popup=Iespējot apvienoto profila bilžu meklētāju, la disable_registration=Atspējot lietotāju reģistrāciju disable_registration_popup=Atspējot iespēju reģistrēties. Tikai administratori varēs izveidot jaunus kontus. allow_only_external_registration_popup=Atļaut reģistrēties tikai ar ārējiem servisiem -openid_signin=Iespējot OpenID autorizāciju -openid_signin_popup=Iespējot lietotāju autorizāciju ar OpenID. +openid_signin=Iespējot pieteikšanos ar OpenID +openid_signin_popup=Iespējot lietotāju pieteikšanos ar OpenID. openid_signup=Iespējot reģistrāciju, izmantojot OpenID openid_signup_popup=Iespējot lietotāju reģistrāciju pirms tam autorizējoties ar OpenID. enable_captcha=Pieprasīt drošības kodu lietotāju reģistrācijā enable_captcha_popup=Lietotājam reģistrējoties, pieprasīt ievadīt drošības kodu. -require_sign_in_view=Iespējot nepieciešamību autorizēties, lai aplūkotu lapas -require_sign_in_view_popup=Tikai autorizēti lietotāji var aplūkot lapas. Apmeklētāji redzēs tikai autorizācijas un reģistrācijas lapu. +require_sign_in_view=Pieprasīt pieteikšanos, lai aplūkotu lapas +require_sign_in_view_popup=Ierobežot piekļuvi lapām tikai lietotājiem, kuri ir pieteikušies. Apmeklētāji redzēs tikai pieteikšanās un reģistrēšanās lapu. admin_setting_desc=Nav nepieciešams izveidot administratora kontu uzreiz, pirmais reģistrētais lietotājs saņems administratora tiesības automātiski. admin_title=Administratora konta iestatījumi admin_name=Administratora lietotājvārds @@ -345,7 +346,7 @@ relevant_repositories=Tikai būtiskie repozitoriji tiek rādīti, p [auth] create_new_account=Reģistrēt kontu -register_helper_msg=Jau ir konts? Pieraksties tagad! +register_helper_msg=Jau ir konts? Piesakieties tagad! social_register_helper_msg=Jau ir konts? Piesaisti to! disable_register_prompt=Reģistrācija ir atspējota. Lūdzu, sazinieties ar vietnes administratoru. disable_register_mail=Reģistrācijas e-pasta apstiprināšana ir atspējota. @@ -360,7 +361,8 @@ allow_password_change=Pieprasīt lietotājam mainīt paroli (ieteicams) reset_password_mail_sent_prompt=Apstiprināšanas e-pasts tika nosūtīts uz %s. Pārbaudiet savu e-pasta kontu tuvāko %s laikā, lai pabeigtu paroles atjaunošanas procesu. active_your_account=Aktivizēt savu kontu account_activated=Konts ir aktivizēts -prohibit_login=Aizliegt pieteikšanos +prohibit_login=Pieteikšanās liegta +prohibit_login_desc=Jūsu konts ir bloķēts, sazinieties ar sistēmas administratoru. resent_limit_prompt=Jūs pieprasījāt aktivizācijas e-pastu pārāk bieži. Lūdzu, uzgaidiet 3 minūtes un mēģiniet vēlreiz. has_unconfirmed_mail=Sveiki %s, Jums ir neapstiprināta e-pasta adrese (%s). Ja neesat saņēmis apstiprināšanas e-pastu vai Jums ir nepieciešams nosūtīt jaunu, lūdzu, nospiediet pogu, kas atrodas zemāk. resend_mail=Nospiediet šeit, lai vēlreiz nosūtītu aktivizācijas e-pastu @@ -370,25 +372,26 @@ reset_password=Paroles atjaunošana invalid_code=Jūsu apstiprināšanas kodam ir beidzies derīguma termiņš vai arī tas ir nepareizs. invalid_password=Jūsu parole neatbilst parolei, kas tika ievadīta veidojot so kontu. reset_password_helper=Atjaunot paroli +reset_password_wrong_user=Jūs esat pieteicies kā %s, bet konta atkopšanas saite ir paredzēta lietotājam %s password_too_short=Paroles garums nedrīkst būt mazāks par %d simboliem. non_local_account=Ārējie konti nevar mainīt paroli, izmantojot, Gitea saskarni. verify=Pārbaudīt scratch_code=Vienreizējais kods use_scratch_code=Izmantot vienreizējo kodu twofa_scratch_used=Vienreizējais kods tika izmantots. Notika pārvirzīšana uz divfaktoru iestatījumu lapu, lai varētu pārsaistīt jaunu ierīci vai uzģenerēt jaunu vienreizējo kodu. -twofa_passcode_incorrect=Jūsu kods nav pareizs. Ja esat pazaudējis ierīci, izmantojiet vienreizējo kodu, lai autorizētos. +twofa_passcode_incorrect=Piekļuves kods nav pareizs. Ja esat pazaudējis ierīci, izmantojiet vienreizējo kodu, lai pieteiktos. twofa_scratch_token_incorrect=Ievadīts nepareizs vienreizējais kods. -login_userpass=Pierakstīties +login_userpass=Pieteikties login_openid=OpenID oauth_signup_tab=Reģistrēt jaunu kontu oauth_signup_title=Pabeigt konta veidošanu oauth_signup_submit=Pabeigt reģistrāciju -oauth_signin_tab=Savienot ar esošu kontu -oauth_signin_title=Pierakstīties, lai autorizētu saistīto kontu +oauth_signin_tab=Sasaistīt ar esošu kontu +oauth_signin_title=Pieteikties, lai autorizētu saistīto kontu oauth_signin_submit=Sasaistīt kontu -oauth.signin.error=Radās kļūda apstrādājot autorizācijas pieprasījumu. Ja šī kļūda atkārtojas, sazinieties ar lapas administratoru. +oauth.signin.error=Radās kļūda apstrādājot pieteikšanās pieprasījumu. Ja šī kļūda atkārtojas, sazinieties ar lapas administratoru. oauth.signin.error.access_denied=Autorizācijas pieprasījums tika noraidīts. -oauth.signin.error.temporarily_unavailable=Autorizācija neizdevās, jo autentifikācijas serveris ir īslaicīgi nepieejams. Mēģiniet autorizēties vēlāk. +oauth.signin.error.temporarily_unavailable=Pieteikšanās neizdevās, jo autentifikācijas serveris ir īslaicīgi nepieejams. Mēģiniet autorizēties vēlāk. openid_connect_submit=Pievienoties openid_connect_title=Pievienoties jau esošam kontam openid_connect_desc=Izvēlētais OpenID konts sistēmā netika atpazīts, bet Jūs to varat piesaistīt esošam kontam. @@ -662,7 +665,7 @@ change_password=Mainīt paroli old_password=Pašreizējā parole new_password=Jauna parole password_incorrect=Ievadīta nepareiza pašreizējā parole. -change_password_success=Parole tika veiksmīgi nomainīta. Tagad varat autorizēties ar jauno paroli. +change_password_success=Parole tika veiksmīgi nomainīta. Tagad varat pieteikties ar jauno paroli. password_change_disabled=Ārējie konti nevar mainīt paroli, izmantojot, Gitea saskarni. emails=E-pasta adreses @@ -683,7 +686,7 @@ email_deletion_success=E-pasta adrese ir veiksmīgi izdzēsta. theme_update_success=Jūsu motīvs tika nomainīts. theme_update_error=Izvēlētais motīvs neeksistē. openid_deletion=Dzēst OpenID adresi -openid_deletion_desc=Dzēšot šo OpenID adresi no Jūsu konta, ar to vairs nebūs iespējams autorizēties. Vai turpināt? +openid_deletion_desc=Dzēšot šo OpenID adresi no Jūsu konta, ar to vairs nebūs iespējams pieteikties. Vai turpināt? openid_deletion_success=OpenID adrese tika noņemta. add_new_email=Pievienot jaunu e-pasta adresi add_new_openid=Pievienot jaunu OpenID vietrādi @@ -772,6 +775,7 @@ ssh_disabled=SSH atspējots ssh_signonly=SSH ir atspējots, līdz ar to šīs atslēgas tiks izmantotas tikai revīziju parakstu pārbaudei. ssh_externally_managed=Šim lietotājam SSH atslēga tiek pāvaldīta attālināti manage_social=Pārvaldīt piesaistītos sociālos kontus +social_desc=Šie sociālo tīklu konti var tikt izmantoti, lai pieteiktos. Pārliecinieties, ka visi ir atpazīstami. unbind=Atsaistīt manage_access_token=Pārvaldīt piekļuves pilnvaras @@ -828,7 +832,7 @@ twofa_scratch_token_regenerate=Ģenerēt jaunu vienreizējo kodu twofa_enroll=Ieslēgt divfaktoru autentifikāciju twofa_disable_note=Nepieciešamības gadījumā divfaktoru autentifikāciju ir iespējams atslēgt. twofa_disable_desc=Atslēdzot divfaktoru autentifikāciju, konts vairs nebūs tik drošs. Vai turpināt? -regenerate_scratch_token_desc=Ja esat aizmirsis vienreizējo kodu vai jau esat to izmantojis, lai autorizētos, atjaunojiet to šeit. +regenerate_scratch_token_desc=Ja esat aizmirsis vienreizējo kodu vai esat to jau izmantojis, lai pieteiktos, atjaunojiet to šeit. twofa_disabled=Divfaktoru autentifikācija tika atslēgta. scan_this_image=Noskenējiet šo attēlu ar autentifikācijas lietojumprogrammu: or_enter_secret=Vai ievadiet šo noslēpumu: %s @@ -841,7 +845,7 @@ webauthn_desc=Drošības atslēgas ir fiziskas ierīces, kas satur kriptogrāfis webauthn_register_key=Pievienot drošības atslēgu webauthn_nickname=Segvārds webauthn_delete_key=Noņemt drošības atslēgu -webauthn_delete_key_desc=Noņemot drošības atslēgu ar to vairs nebūs iespējams autorizēties. Turpināt? +webauthn_delete_key_desc=Noņemot drošības atslēgu ar to vairs nebūs iespējams pieteikties. Vai turpināt? manage_account_links=Pārvaldīt saistītos kontus manage_account_links_desc=Šādi ārējie konti ir piesaistīti Jūsu Gitea kontam. @@ -1045,9 +1049,9 @@ mirror_from=spogulis no forked_from=atdalīts no generated_from=ģenerēts no fork_from_self=Nav iespējams atdalīt repozitoriju, kuram esat īpašnieks. -fork_guest_user=Autorizējieties, lai atdalītu repozitoriju. -watch_guest_user=Autorizejieties, lai sekotu šim repozitorijam. -star_guest_user=Autorizejieties, lai atzīmētu ar zvaigznīti šo repozitoriju. +fork_guest_user=Piesakieties, lai atdalītu repozitoriju. +watch_guest_user=Piesakieties, lai sekotu šim repozitorijam. +star_guest_user=Piesakieties, lai atzīmētu šo repozitoriju ar zvaigznīti. unwatch=Nevērot watch=Vērot unstar=Noņemt zvaigznīti @@ -1293,7 +1297,7 @@ issues.new.clear_assignees=Noņemt atbildīgo issues.new.no_assignees=Nav atbildīgo issues.new.no_reviewers=Nav recenzentu issues.choose.get_started=Sākt darbu -issues.choose.open_external_link=Aktīvie +issues.choose.open_external_link=Atvērt issues.choose.blank=Noklusējuma issues.choose.blank_about=Izveidot problēmu ar noklusējuma sagatavi. issues.choose.ignore_invalid_templates=Kļūdainās sagataves tika izlaistas @@ -1422,7 +1426,7 @@ issues.remove_request_review=Noņemt recenzijas pieprasījumu issues.remove_request_review_block=Nevar noņemt recenzījas pieprasījumu issues.dismiss_review=Atmest recenziju issues.dismiss_review_warning=Vai patiešām vēlaties atmest šo recenziju? -issues.sign_in_require_desc=Pierakstieties, lai pievienotos šai sarunai. +issues.sign_in_require_desc=Nepieciešams pieteikties, lai pievienotos šai sarunai. issues.edit=Labot issues.cancel=Atcelt issues.save=Saglabāt @@ -1735,6 +1739,8 @@ milestones.filter_sort.most_complete=Visvairāk pabeigtais milestones.filter_sort.most_issues=Visvairāk problēmu milestones.filter_sort.least_issues=Vismazāk problēmu +signing.wont_sign.error=Notika kļūda pārbaudot vai revīzija var tikt parakstīta. +signing.wont_sign.not_signed_in=Jūs neesat pieteicies. ext_wiki=Piekļuve ārējai vikivietnei ext_wiki.desc=Ārējā vikivietne norāda uz ārējo vikivietnes adresi. @@ -1865,6 +1871,7 @@ settings.mirror_settings.docs.no_new_mirrors=Šis repozitorijs spoguļo izmaiņa settings.mirror_settings.docs.can_still_use=Lai arī nav iespējams mainīt esošos vai izveidot jaunus spoguļa repozitorijus, esošie turpinās strādāt. settings.mirror_settings.docs.pull_mirror_instructions=Lai ietatītu atvilkšanas spoguli, sekojiet instrukcijām: settings.mirror_settings.docs.doc_link_title=Kā spoguļot repozitorijus? +settings.mirror_settings.docs.doc_link_pull_section=dokumentācijas nodaļā "Pulling from a remote repository". settings.mirror_settings.docs.pulling_remote_title=Atvilkt no attāla repozitorija settings.mirror_settings.mirrored_repository=Spoguļotais repozitorijs settings.mirror_settings.direction=Virziens @@ -2632,8 +2639,8 @@ users.restricted=Ierobežots users.2fa=2FA users.repos=Repozitoriji users.created=Izveidots -users.last_login=Pēdējā autorizācija -users.never_login=Nekad nav autorizējies +users.last_login=Pēdējā pieteikšanās +users.never_login=Pieteikšanās nekad nav veikta users.send_register_notify=Nosūtīt lietotājam reģistrācijas paziņojumu users.new_success=Lietotāja konts "%s" tika izveidots. users.edit=Labot @@ -2646,7 +2653,7 @@ users.edit_account=Labot lietotāja kontu users.max_repo_creation=Maksimālais repozitoriju skaits users.max_repo_creation_desc=(Ievadiet -1 lai izmantotu noklusēto globālo ierobežojumu) users.is_activated=Lietotāja konts ir aktivizēts -users.prohibit_login=Atspējota pieslēgšanās +users.prohibit_login=Atspējota pieteikšanās users.is_admin=Administratora tiesības users.is_restricted=Ir ierobežots users.allow_git_hook=Atļaut veidot git āķus @@ -2825,7 +2832,7 @@ auths.tip.github=Reģistrējiet jaunu aplikāciju adresē https://github.com/set auths.tip.gitlab=Reģistrējiet jaunu aplikāciju adresē https://gitlab.com/profile/applications auths.tip.google_plus=Iegūstiet OAuth2 klienta pilnvaru no Google API konsoles adresē https://console.developers.google.com/ auths.tip.openid_connect=Izmantojiet OpenID pieslēgšanās atklāšanas URL (/.well-known/openid-configuration), lai norādītu galapunktus -auths.tip.twitter=Dodieties uz adresi https://dev.twitter.com/apps, izveidojiet aplikāciju un pārliecinieties, ka ir atzīmēts “Allow this application to be used to Sign in with Twitter” +auths.tip.twitter=Dodieties uz adresi https://dev.twitter.com/apps, izveidojiet lietotni un pārliecinieties, ka ir atzīmēts “Allow this application to be used to Sign in with Twitter” auths.tip.discord=Reģistrējiet jaunu aplikāciju adresē https://discordapp.com/developers/applications/me auths.tip.yandex=`Izveidojiet jaunu lietotni adresē https://oauth.yandex.com/client/new. Izvēlieties sekojošas tiesības "Yandex.Passport API" sadaļā: "Access to email address", "Access to user avatar" un "Access to username, first name and surname, gender"` auths.tip.mastodon=Norādiet pielāgotu mastodon instances URL, ar kuru vēlaties autorizēties (vai izmantojiet noklusēto) @@ -2836,7 +2843,7 @@ auths.update_success=Autentifikācijas avots tika atjaunots. auths.update=Atjaunot autentifikācijas avotu auths.delete=Dzēst autentifikācijas avotu auths.delete_auth_title=Dzēst autentifikācijas avotu -auths.delete_auth_desc=Izdzēšot autentifikācijas avotu, tā lietotājiem nebūs iespējams autorizēties. Vai turpināt? +auths.delete_auth_desc=Izdzēšot autentifikācijas avotu, tā lietotājiem nebūs iespējams pieteikties. Vai turpināt? auths.still_in_used=Šo autentificēšanās avotu joprojām izmanto viens vai vairāki lietotāji, tos nepieciešams izdzēst vai pārvietot uz citu autentificēšanās avotu. auths.deletion_success=Autentifikācijas avots tika atjaunots. auths.login_source_exist=Autentifikācijas avots ar nosaukumu "%s" jau eksistē. @@ -2894,9 +2901,9 @@ config.disable_register=Atspējot lietotāju reģistrāciju config.allow_only_internal_registration=Atļaut reģistrāciju tikai no Gitea config.allow_only_external_registration=Atļaut reģistrēties tikai ar ārējiem servisiem config.enable_openid_signup=Iespējot reģistrāciju, izmantojot OpenID -config.enable_openid_signin=Iespējot OpenID autorizāciju +config.enable_openid_signin=Iespējot pieteikšanos ar OpenID config.show_registration_button=Rādīt reģistrēšanās pogu -config.require_sign_in_view=Iespējot nepieciešamību autorizēties, lai aplūkotu lapas +config.require_sign_in_view=Pieprasīt pieteikšanos, lai aplūkotu lapas config.mail_notify=Iespējot e-pasta paziņojumus config.disable_key_size_check=Atspējot atslēgas minimālā garuma pārbaudi config.enable_captcha=Iespējot drošības kodu From 27c05069a6a120d7a991d802548e8b74792af3e4 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 9 Dec 2023 19:38:46 +0800 Subject: [PATCH 05/60] Remove stale since giteabot has similiar feature (#28401) Replace #27447 --- .github/stale.yml | 54 ----------------------------------------------- 1 file changed, 54 deletions(-) delete mode 100644 .github/stale.yml diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index ebe95acf533a3..0000000000000 --- a/.github/stale.yml +++ /dev/null @@ -1,54 +0,0 @@ -# Configuration for probot-stale - https://github.com/probot/stale - -# Number of days of inactivity before an Issue or Pull Request becomes stale -daysUntilStale: 60 - -# Number of days of inactivity before an Issue or Pull Request with the stale label is closed. -# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. -daysUntilClose: 14 - -# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable -exemptLabels: - - status/blocked - - kind/security - - lgtm/done - - reviewed/confirmed - - priority/critical - - kind/proposal - -# Set to true to ignore issues in a project (defaults to false) -exemptProjects: false - -# Set to true to ignore issues in a milestone (defaults to false) -exemptMilestones: false - -# Label to use when marking as stale -staleLabel: stale - -# Comment to post when marking as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had recent activity. - I am here to help clear issues left open even if solved or waiting for more insight. - This issue will be closed if no further activity occurs during the next 2 weeks. - If the issue is still valid just add a comment to keep it alive. - Thank you for your contributions. - -# Comment to post when closing a stale Issue or Pull Request. -closeComment: > - This issue has been automatically closed because of inactivity. - You can re-open it if needed. - -# Limit the number of actions per hour, from 1-30. Default is 30 -limitPerRun: 1 - -# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': -pulls: - daysUntilStale: 60 - daysUntilClose: 60 - markComment: > - This pull request has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs during the next 2 months. Thank you - for your contributions. - closeComment: > - This pull request has been automatically closed because of inactivity. - You can re-open it if needed. From aeb383025f90abcda7a9562684376b1996dcf3a5 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sat, 9 Dec 2023 21:30:56 +0800 Subject: [PATCH 06/60] Also sync DB branches on push if necessary (#28361) Fix #28056 This PR will check whether the repo has zero branch when pushing a branch. If that, it means this repository hasn't been synced. The reason caused that is after user upgrade from v1.20 -> v1.21, he just push branches without visit the repository user interface. Because all repositories routers will check whether a branches sync is necessary but push has not such check. For every repository, it has two states, synced or not synced. If there is zero branch for a repository, then it will be assumed as non-sync state. Otherwise, it's synced state. So if we think it's synced, we just need to update branch/insert new branch. Otherwise do a full sync. So that, for every push, there will be almost no extra load added. It's high performance than yours. For the implementation, we in fact will try to update the branch first, if updated success with affect records > 0, then all are done. Because that means the branch has been in the database. If no record is affected, that means the branch does not exist in database. So there are two possibilities. One is this is a new branch, then we just need to insert the record. Another is the branches haven't been synced, then we need to sync all the branches into database. --- models/git/branch.go | 33 +++--- models/git/branch_list.go | 8 +- models/git/branch_test.go | 2 +- routers/api/v1/repo/branch.go | 5 +- routers/web/repo/branch.go | 4 +- services/repository/branch.go | 100 ++++++++++++------ services/repository/push.go | 2 +- .../api_repo_get_contents_list_test.go | 9 +- .../integration/api_repo_get_contents_test.go | 9 +- 9 files changed, 99 insertions(+), 73 deletions(-) diff --git a/models/git/branch.go b/models/git/branch.go index 6d50fb9fb6a18..ffd1d7ed164a0 100644 --- a/models/git/branch.go +++ b/models/git/branch.go @@ -205,10 +205,9 @@ func DeleteBranches(ctx context.Context, repoID, doerID int64, branchIDs []int64 }) } -// UpdateBranch updates the branch information in the database. If the branch exist, it will update latest commit of this branch information -// If it doest not exist, insert a new record into database -func UpdateBranch(ctx context.Context, repoID, pusherID int64, branchName string, commit *git.Commit) error { - cnt, err := db.GetEngine(ctx).Where("repo_id=? AND name=?", repoID, branchName). +// UpdateBranch updates the branch information in the database. +func UpdateBranch(ctx context.Context, repoID, pusherID int64, branchName string, commit *git.Commit) (int64, error) { + return db.GetEngine(ctx).Where("repo_id=? AND name=?", repoID, branchName). Cols("commit_id, commit_message, pusher_id, commit_time, is_deleted, updated_unix"). Update(&Branch{ CommitID: commit.ID.String(), @@ -217,21 +216,6 @@ func UpdateBranch(ctx context.Context, repoID, pusherID int64, branchName string CommitTime: timeutil.TimeStamp(commit.Committer.When.Unix()), IsDeleted: false, }) - if err != nil { - return err - } - if cnt > 0 { - return nil - } - - return db.Insert(ctx, &Branch{ - RepoID: repoID, - Name: branchName, - CommitID: commit.ID.String(), - CommitMessage: commit.Summary(), - PusherID: pusherID, - CommitTime: timeutil.TimeStamp(commit.Committer.When.Unix()), - }) } // AddDeletedBranch adds a deleted branch to the database @@ -308,6 +292,17 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, from, to str sess := db.GetEngine(ctx) + var branch Branch + exist, err := db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, from).Get(&branch) + if err != nil { + return err + } else if !exist || branch.IsDeleted { + return ErrBranchNotExist{ + RepoID: repo.ID, + BranchName: from, + } + } + // 1. update branch in database if n, err := sess.Where("repo_id=? AND name=?", repo.ID, from).Update(&Branch{ Name: to, diff --git a/models/git/branch_list.go b/models/git/branch_list.go index b5c1301a1dc00..2efe495264abe 100644 --- a/models/git/branch_list.go +++ b/models/git/branch_list.go @@ -73,7 +73,7 @@ type FindBranchOptions struct { Keyword string } -func (opts *FindBranchOptions) Cond() builder.Cond { +func (opts FindBranchOptions) ToConds() builder.Cond { cond := builder.NewCond() if opts.RepoID > 0 { cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) @@ -92,7 +92,7 @@ func (opts *FindBranchOptions) Cond() builder.Cond { } func CountBranches(ctx context.Context, opts FindBranchOptions) (int64, error) { - return db.GetEngine(ctx).Where(opts.Cond()).Count(&Branch{}) + return db.GetEngine(ctx).Where(opts.ToConds()).Count(&Branch{}) } func orderByBranches(sess *xorm.Session, opts FindBranchOptions) *xorm.Session { @@ -108,7 +108,7 @@ func orderByBranches(sess *xorm.Session, opts FindBranchOptions) *xorm.Session { } func FindBranches(ctx context.Context, opts FindBranchOptions) (BranchList, error) { - sess := db.GetEngine(ctx).Where(opts.Cond()) + sess := db.GetEngine(ctx).Where(opts.ToConds()) if opts.PageSize > 0 && !opts.IsListAll() { sess = db.SetSessionPagination(sess, &opts.ListOptions) } @@ -119,7 +119,7 @@ func FindBranches(ctx context.Context, opts FindBranchOptions) (BranchList, erro } func FindBranchNames(ctx context.Context, opts FindBranchOptions) ([]string, error) { - sess := db.GetEngine(ctx).Select("name").Where(opts.Cond()) + sess := db.GetEngine(ctx).Select("name").Where(opts.ToConds()) if opts.PageSize > 0 && !opts.IsListAll() { sess = db.SetSessionPagination(sess, &opts.ListOptions) } diff --git a/models/git/branch_test.go b/models/git/branch_test.go index ba6902692792e..07b243e5e6e92 100644 --- a/models/git/branch_test.go +++ b/models/git/branch_test.go @@ -37,7 +37,7 @@ func TestAddDeletedBranch(t *testing.T) { }, } - err := git_model.UpdateBranch(db.DefaultContext, repo.ID, secondBranch.PusherID, secondBranch.Name, commit) + _, err := git_model.UpdateBranch(db.DefaultContext, repo.ID, secondBranch.PusherID, secondBranch.Name, commit) assert.NoError(t, err) } diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index f2386a607e657..677105bdb506c 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -251,12 +251,11 @@ func CreateBranch(ctx *context.APIContext) { } } - err = repo_service.CreateNewBranchFromCommit(ctx, ctx.Doer, ctx.Repo.Repository, oldCommit.ID.String(), opt.BranchName) + err = repo_service.CreateNewBranchFromCommit(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, oldCommit.ID.String(), opt.BranchName) if err != nil { if git_model.IsErrBranchNotExist(err) { ctx.Error(http.StatusNotFound, "", "The old branch does not exist") - } - if models.IsErrTagAlreadyExists(err) { + } else if models.IsErrTagAlreadyExists(err) { ctx.Error(http.StatusConflict, "", "The branch with the same tag already exists.") } else if git_model.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) { ctx.Error(http.StatusConflict, "", "The branch already exists.") diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index bc72d5f2eca17..a0bc1dadade8b 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -191,9 +191,9 @@ func CreateBranch(ctx *context.Context) { } err = release_service.CreateNewTag(ctx, ctx.Doer, ctx.Repo.Repository, target, form.NewBranchName, "") } else if ctx.Repo.IsViewBranch { - err = repo_service.CreateNewBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.BranchName, form.NewBranchName) + err = repo_service.CreateNewBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.Repo.BranchName, form.NewBranchName) } else { - err = repo_service.CreateNewBranchFromCommit(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.CommitID, form.NewBranchName) + err = repo_service.CreateNewBranchFromCommit(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.Repo.CommitID, form.NewBranchName) } if err != nil { if models.IsErrProtectedTagName(err) { diff --git a/services/repository/branch.go b/services/repository/branch.go index 735fa1a756816..6dc286675f3d6 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -20,6 +20,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/queue" repo_module "code.gitea.io/gitea/modules/repository" + "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" notify_service "code.gitea.io/gitea/services/notify" files_service "code.gitea.io/gitea/services/repository/files" @@ -28,35 +29,13 @@ import ( ) // CreateNewBranch creates a new repository branch -func CreateNewBranch(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldBranchName, branchName string) (err error) { - err = repo.MustNotBeArchived() +func CreateNewBranch(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, gitRepo *git.Repository, oldBranchName, branchName string) (err error) { + branch, err := git_model.GetBranch(ctx, repo.ID, oldBranchName) if err != nil { return err } - // Check if branch name can be used - if err := checkBranchName(ctx, repo, branchName); err != nil { - return err - } - - if !git.IsBranchExist(ctx, repo.RepoPath(), oldBranchName) { - return git_model.ErrBranchNotExist{ - BranchName: oldBranchName, - } - } - - if err := git.Push(ctx, repo.RepoPath(), git.PushOptions{ - Remote: repo.RepoPath(), - Branch: fmt.Sprintf("%s%s:%s%s", git.BranchPrefix, oldBranchName, git.BranchPrefix, branchName), - Env: repo_module.PushingEnvironment(doer, repo), - }); err != nil { - if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) { - return err - } - return fmt.Errorf("push: %w", err) - } - - return nil + return CreateNewBranchFromCommit(ctx, doer, repo, gitRepo, branch.CommitID, branchName) } // Branch contains the branch information @@ -249,8 +228,49 @@ func checkBranchName(ctx context.Context, repo *repo_model.Repository, name stri return err } +// syncBranchToDB sync the branch information in the database. It will try to update the branch first, +// if updated success with affect records > 0, then all are done. Because that means the branch has been in the database. +// If no record is affected, that means the branch does not exist in database. So there are two possibilities. +// One is this is a new branch, then we just need to insert the record. Another is the branches haven't been synced, +// then we need to sync all the branches into database. +func syncBranchToDB(ctx context.Context, repoID, pusherID int64, branchName string, commit *git.Commit) error { + cnt, err := git_model.UpdateBranch(ctx, repoID, pusherID, branchName, commit) + if err != nil { + return fmt.Errorf("git_model.UpdateBranch %d:%s failed: %v", repoID, branchName, err) + } + if cnt > 0 { // This means branch does exist, so it's a normal update. It also means the branch has been synced. + return nil + } + + // if user haven't visit UI but directly push to a branch after upgrading from 1.20 -> 1.21, + // we cannot simply insert the branch but need to check we have branches or not + hasBranch, err := db.Exist[git_model.Branch](ctx, git_model.FindBranchOptions{ + RepoID: repoID, + IsDeletedBranch: util.OptionalBoolFalse, + }.ToConds()) + if err != nil { + return err + } + if !hasBranch { + if _, err = repo_module.SyncRepoBranches(ctx, repoID, pusherID); err != nil { + return fmt.Errorf("repo_module.SyncRepoBranches %d:%s failed: %v", repoID, branchName, err) + } + return nil + } + + // if database have branches but not this branch, it means this is a new branch + return db.Insert(ctx, &git_model.Branch{ + RepoID: repoID, + Name: branchName, + CommitID: commit.ID.String(), + CommitMessage: commit.Summary(), + PusherID: pusherID, + CommitTime: timeutil.TimeStamp(commit.Committer.When.Unix()), + }) +} + // CreateNewBranchFromCommit creates a new repository branch -func CreateNewBranchFromCommit(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, commit, branchName string) (err error) { +func CreateNewBranchFromCommit(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, gitRepo *git.Repository, commitID, branchName string) (err error) { err = repo.MustNotBeArchived() if err != nil { return err @@ -261,18 +281,28 @@ func CreateNewBranchFromCommit(ctx context.Context, doer *user_model.User, repo return err } - if err := git.Push(ctx, repo.RepoPath(), git.PushOptions{ - Remote: repo.RepoPath(), - Branch: fmt.Sprintf("%s:%s%s", commit, git.BranchPrefix, branchName), - Env: repo_module.PushingEnvironment(doer, repo), - }); err != nil { - if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) { + return db.WithTx(ctx, func(ctx context.Context) error { + commit, err := gitRepo.GetCommit(commitID) + if err != nil { + return err + } + // database operation should be done before git operation so that we can rollback if git operation failed + if err := syncBranchToDB(ctx, repo.ID, doer.ID, branchName, commit); err != nil { return err } - return fmt.Errorf("push: %w", err) - } - return nil + if err := git.Push(ctx, repo.RepoPath(), git.PushOptions{ + Remote: repo.RepoPath(), + Branch: fmt.Sprintf("%s:%s%s", commitID, git.BranchPrefix, branchName), + Env: repo_module.PushingEnvironment(doer, repo), + }); err != nil { + if git.IsErrPushOutOfDate(err) || git.IsErrPushRejected(err) { + return err + } + return fmt.Errorf("push: %w", err) + } + return nil + }) } // RenameBranch rename a branch diff --git a/services/repository/push.go b/services/repository/push.go index 391c8ad4ca7f1..b5388834c0bd1 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -259,7 +259,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { commits.Commits = commits.Commits[:setting.UI.FeedMaxCommitNum] } - if err = git_model.UpdateBranch(ctx, repo.ID, opts.PusherID, branch, newCommit); err != nil { + if err = syncBranchToDB(ctx, repo.ID, opts.PusherID, branch, newCommit); err != nil { return fmt.Errorf("git_model.UpdateBranch %s:%s failed: %v", repo.FullName(), branch, err) } diff --git a/tests/integration/api_repo_get_contents_list_test.go b/tests/integration/api_repo_get_contents_list_test.go index f3a5159115c18..7874eddfd4d19 100644 --- a/tests/integration/api_repo_get_contents_list_test.go +++ b/tests/integration/api_repo_get_contents_list_test.go @@ -70,15 +70,16 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { session = loginUser(t, user4.Name) token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) - // Make a new branch in repo1 - newBranch := "test_branch" - err := repo_service.CreateNewBranch(git.DefaultContext, user2, repo1, repo1.DefaultBranch, newBranch) - assert.NoError(t, err) // Get the commit ID of the default branch gitRepo, err := git.OpenRepository(git.DefaultContext, repo1.RepoPath()) assert.NoError(t, err) defer gitRepo.Close() + // Make a new branch in repo1 + newBranch := "test_branch" + err = repo_service.CreateNewBranch(git.DefaultContext, user2, repo1, gitRepo, repo1.DefaultBranch, newBranch) + assert.NoError(t, err) + commitID, _ := gitRepo.GetBranchCommitID(repo1.DefaultBranch) // Make a new tag in repo1 newTag := "test_tag" diff --git a/tests/integration/api_repo_get_contents_test.go b/tests/integration/api_repo_get_contents_test.go index 709bbe082a5a4..1d708a4cdb438 100644 --- a/tests/integration/api_repo_get_contents_test.go +++ b/tests/integration/api_repo_get_contents_test.go @@ -72,15 +72,16 @@ func testAPIGetContents(t *testing.T, u *url.URL) { session = loginUser(t, user4.Name) token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) - // Make a new branch in repo1 - newBranch := "test_branch" - err := repo_service.CreateNewBranch(git.DefaultContext, user2, repo1, repo1.DefaultBranch, newBranch) - assert.NoError(t, err) // Get the commit ID of the default branch gitRepo, err := git.OpenRepository(git.DefaultContext, repo1.RepoPath()) assert.NoError(t, err) defer gitRepo.Close() + // Make a new branch in repo1 + newBranch := "test_branch" + err = repo_service.CreateNewBranch(git.DefaultContext, user2, repo1, gitRepo, repo1.DefaultBranch, newBranch) + assert.NoError(t, err) + commitID, err := gitRepo.GetBranchCommitID(repo1.DefaultBranch) assert.NoError(t, err) // Make a new tag in repo1 From 9a99c17a1412fce29944bd9a87d7dc6d40423c77 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 11 Dec 2023 03:37:10 +0800 Subject: [PATCH 07/60] Fix missing check (#28406) --- routers/web/repo/issue_content_history.go | 22 ++++++++++++++++++---- routers/web/repo/issue_pin.go | 6 ++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go index 473ab260f3ea0..0f376db145063 100644 --- a/routers/web/repo/issue_content_history.go +++ b/routers/web/repo/issue_content_history.go @@ -193,15 +193,29 @@ func SoftDeleteContentHistory(ctx *context.Context) { var comment *issues_model.Comment var history *issues_model.ContentHistory var err error + + if history, err = issues_model.GetIssueContentHistoryByID(ctx, historyID); err != nil { + log.Error("can not get issue content history %v. err=%v", historyID, err) + return + } + if history.IssueID != issue.ID { + ctx.NotFound("CompareRepoID", issues_model.ErrCommentNotExist{}) + return + } if commentID != 0 { + if history.CommentID != commentID { + ctx.NotFound("CompareCommentID", issues_model.ErrCommentNotExist{}) + return + } + if comment, err = issues_model.GetCommentByID(ctx, commentID); err != nil { log.Error("can not get comment for issue content history %v. err=%v", historyID, err) return } - } - if history, err = issues_model.GetIssueContentHistoryByID(ctx, historyID); err != nil { - log.Error("can not get issue content history %v. err=%v", historyID, err) - return + if comment.IssueID != issue.ID { + ctx.NotFound("CompareIssueID", issues_model.ErrCommentNotExist{}) + return + } } canSoftDelete := canSoftDeleteContentHistory(ctx, issue, comment, history) diff --git a/routers/web/repo/issue_pin.go b/routers/web/repo/issue_pin.go index f853f72335e66..9f334129f943e 100644 --- a/routers/web/repo/issue_pin.go +++ b/routers/web/repo/issue_pin.go @@ -90,6 +90,12 @@ func IssuePinMove(ctx *context.Context) { return } + if issue.RepoID != ctx.Repo.Repository.ID { + ctx.Status(http.StatusNotFound) + log.Error("Issue does not belong to this repository") + return + } + err = issue.MovePin(ctx, form.Position) if err != nil { ctx.Status(http.StatusInternalServerError) From fab73e4a3a598aa9433522f27edf2d8efea3d0e0 Mon Sep 17 00:00:00 2001 From: Earl Warren <109468362+earl-warren@users.noreply.github.com> Date: Sun, 10 Dec 2023 21:15:06 +0100 Subject: [PATCH 08/60] Actually recover from a panic in cron task (#28409) - Currently there's code to recover gracefully from panics that happen within the execution of cron tasks. However this recover code wasn't being run, because `RunWithShutdownContext` also contains code to recover from any panic and then gracefully shutdown Forgejo. Because `RunWithShutdownContext` registers that code as last, that would get run first which in this case is not behavior that we want. - Move the recover code to inside the function, so that is run first before `RunWithShutdownContext`'s recover code (which is now a noop). Fixes: https://codeberg.org/forgejo/forgejo/issues/1910 Co-authored-by: Gusted --- services/cron/tasks.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/services/cron/tasks.go b/services/cron/tasks.go index d2c3d1d812c42..f0956a97d88c7 100644 --- a/services/cron/tasks.go +++ b/services/cron/tasks.go @@ -84,13 +84,15 @@ func (t *Task) RunWithUser(doer *user_model.User, config Config) { t.lock.Unlock() defer func() { taskStatusTable.Stop(t.Name) - if err := recover(); err != nil { - // Recover a panic within the - combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2)) - log.Error("PANIC whilst running task: %s Value: %v", t.Name, combinedErr) - } }() graceful.GetManager().RunWithShutdownContext(func(baseCtx context.Context) { + defer func() { + if err := recover(); err != nil { + // Recover a panic within the execution of the task. + combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2)) + log.Error("PANIC whilst running task: %s Value: %v", t.Name, combinedErr) + } + }() // Store the time of this run, before the function is executed, so it // matches the behavior of what the cron library does. t.lock.Lock() From 5b2bbf1a1f2527b75d8a64bc36ea735cd19c0efa Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Mon, 11 Dec 2023 00:25:45 +0000 Subject: [PATCH 09/60] [skip ci] Updated licenses and gitignores --- options/license/xkeyboard-config-Zinoviev | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 options/license/xkeyboard-config-Zinoviev diff --git a/options/license/xkeyboard-config-Zinoviev b/options/license/xkeyboard-config-Zinoviev new file mode 100644 index 0000000000000..509fc255e27f2 --- /dev/null +++ b/options/license/xkeyboard-config-Zinoviev @@ -0,0 +1,15 @@ +Copyright (C) 1999, 2000 by Anton Zinoviev + +This software may be used, modified, copied, distributed, and sold, +in both source and binary form provided that the above copyright +and these terms are retained. Under no circumstances is the author +responsible for the proper functioning of this software, nor does +the author assume any responsibility for damages incurred with its +use. + +Permission is granted to anyone to use, distribute and modify +this file in any way, provided that the above copyright notice +is left intact and the author of the modification summarizes +the changes in this header. + +This file is distributed without any expressed or implied warranty. From 0abb5633e34fd14c2d49de0b4c98f7ba7d98a37e Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Mon, 11 Dec 2023 15:19:57 +0900 Subject: [PATCH 10/60] Fix commit status in repo list (#28412) Before: ![image](https://github.com/go-gitea/gitea/assets/18380374/00edf23a-aee1-4177-a12c-bd03ae14e65e) ![image](https://github.com/go-gitea/gitea/assets/18380374/0663e443-682c-4a68-b14e-a0fa0e4c3716) `TestOrg/testactions` does have commit status, but won't display in `All` After: ![image](https://github.com/go-gitea/gitea/assets/18380374/7231db29-9c4e-484f-afa2-87db19be19b8) Same to #26179. --- models/git/commit_status.go | 4 +++- routers/web/repo/repo.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index acb011020056e..097ce01c1442a 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -323,7 +323,9 @@ func GetLatestCommitStatusForPairs(ctx context.Context, repoIDsToLatestCommitSHA Select("max( id ) as id, repo_id"). GroupBy("context_hash, repo_id").OrderBy("max( id ) desc") - sess = db.SetSessionPagination(sess, &listOptions) + if !listOptions.IsListAll() { + sess = db.SetSessionPagination(sess, &listOptions) + } err := sess.Find(&results) if err != nil { diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index b3b6b48871a08..482fbaac2bc57 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -606,7 +606,7 @@ func SearchRepo(ctx *context.Context) { } // call the database O(1) times to get the commit statuses for all repos - repoToItsLatestCommitStatuses, err := git_model.GetLatestCommitStatusForPairs(ctx, repoIDsToLatestCommitSHAs, db.ListOptions{}) + repoToItsLatestCommitStatuses, err := git_model.GetLatestCommitStatusForPairs(ctx, repoIDsToLatestCommitSHAs, db.ListOptionsAll) if err != nil { log.Error("GetLatestCommitStatusForPairs: %v", err) return From 537fa6996214ef42348cfe89bab6f2e04380aeac Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 11 Dec 2023 16:56:48 +0800 Subject: [PATCH 11/60] Second part of refactor `db.Find` (#28194) Continue of #27798 and move more functions to `db.Find` and `db.Count`. --- models/git/branch_list.go | 34 ++--- models/git/branch_test.go | 6 +- models/issues/milestone.go | 9 +- models/issues/milestone_list.go | 143 ++++----------------- models/issues/milestone_test.go | 76 +++++++---- modules/context/repo.go | 6 +- modules/repository/branch.go | 8 +- routers/api/v1/repo/branch.go | 7 +- routers/api/v1/repo/milestone.go | 15 ++- routers/web/repo/issue.go | 15 +-- routers/web/repo/milestone.go | 12 +- routers/web/user/home.go | 17 ++- services/migrations/gitea_uploader_test.go | 12 +- services/repository/branch.go | 11 +- 14 files changed, 149 insertions(+), 222 deletions(-) diff --git a/models/git/branch_list.go b/models/git/branch_list.go index 2efe495264abe..0e8d28038a566 100644 --- a/models/git/branch_list.go +++ b/models/git/branch_list.go @@ -12,7 +12,6 @@ import ( "code.gitea.io/gitea/modules/util" "xorm.io/builder" - "xorm.io/xorm" ) type BranchList []*Branch @@ -91,31 +90,20 @@ func (opts FindBranchOptions) ToConds() builder.Cond { return cond } -func CountBranches(ctx context.Context, opts FindBranchOptions) (int64, error) { - return db.GetEngine(ctx).Where(opts.ToConds()).Count(&Branch{}) -} - -func orderByBranches(sess *xorm.Session, opts FindBranchOptions) *xorm.Session { +func (opts FindBranchOptions) ToOrders() string { + orderBy := opts.OrderBy if !opts.IsDeletedBranch.IsFalse() { // if deleted branch included, put them at the end - sess = sess.OrderBy("is_deleted ASC") + if orderBy != "" { + orderBy += ", " + } + orderBy += "is_deleted ASC" } - - if opts.OrderBy == "" { + if orderBy == "" { // the commit_time might be the same, so add the "name" to make sure the order is stable - opts.OrderBy = "commit_time DESC, name ASC" + return "commit_time DESC, name ASC" } - return sess.OrderBy(opts.OrderBy) -} -func FindBranches(ctx context.Context, opts FindBranchOptions) (BranchList, error) { - sess := db.GetEngine(ctx).Where(opts.ToConds()) - if opts.PageSize > 0 && !opts.IsListAll() { - sess = db.SetSessionPagination(sess, &opts.ListOptions) - } - sess = orderByBranches(sess, opts) - - var branches []*Branch - return branches, sess.Find(&branches) + return orderBy } func FindBranchNames(ctx context.Context, opts FindBranchOptions) ([]string, error) { @@ -123,9 +111,9 @@ func FindBranchNames(ctx context.Context, opts FindBranchOptions) ([]string, err if opts.PageSize > 0 && !opts.IsListAll() { sess = db.SetSessionPagination(sess, &opts.ListOptions) } - sess = orderByBranches(sess, opts) + var branches []string - if err := sess.Table("branch").Find(&branches); err != nil { + if err := sess.Table("branch").OrderBy(opts.ToOrders()).Find(&branches); err != nil { return nil, err } return branches, nil diff --git a/models/git/branch_test.go b/models/git/branch_test.go index 07b243e5e6e92..ce4cbd56a123d 100644 --- a/models/git/branch_test.go +++ b/models/git/branch_test.go @@ -45,10 +45,8 @@ func TestGetDeletedBranches(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - branches, err := git_model.FindBranches(db.DefaultContext, git_model.FindBranchOptions{ - ListOptions: db.ListOptions{ - ListAll: true, - }, + branches, err := db.Find[git_model.Branch](db.DefaultContext, git_model.FindBranchOptions{ + ListOptions: db.ListOptionsAll, RepoID: repo.ID, IsDeletedBranch: util.OptionalBoolTrue, }) diff --git a/models/issues/milestone.go b/models/issues/milestone.go index ad1d5d0453282..9db7cb2b15ee0 100644 --- a/models/issues/milestone.go +++ b/models/issues/milestone.go @@ -295,16 +295,15 @@ func DeleteMilestoneByRepoID(ctx context.Context, repoID, id int64) error { return err } - numMilestones, err := CountMilestones(ctx, GetMilestonesOption{ + numMilestones, err := db.Count[Milestone](ctx, FindMilestoneOptions{ RepoID: repo.ID, - State: api.StateAll, }) if err != nil { return err } - numClosedMilestones, err := CountMilestones(ctx, GetMilestonesOption{ - RepoID: repo.ID, - State: api.StateClosed, + numClosedMilestones, err := db.Count[Milestone](ctx, FindMilestoneOptions{ + RepoID: repo.ID, + IsClosed: util.OptionalBoolTrue, }) if err != nil { return err diff --git a/models/issues/milestone_list.go b/models/issues/milestone_list.go index d55c18a9954f6..f331b2590faa4 100644 --- a/models/issues/milestone_list.go +++ b/models/issues/milestone_list.go @@ -8,8 +8,7 @@ import ( "strings" "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/setting" - api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/util" "xorm.io/builder" ) @@ -25,31 +24,31 @@ func (milestones MilestoneList) getMilestoneIDs() []int64 { return ids } -// GetMilestonesOption contain options to get milestones -type GetMilestonesOption struct { +// FindMilestoneOptions contain options to get milestones +type FindMilestoneOptions struct { db.ListOptions RepoID int64 - State api.StateType + IsClosed util.OptionalBool Name string SortType string + RepoCond builder.Cond + RepoIDs []int64 } -func (opts GetMilestonesOption) toCond() builder.Cond { +func (opts FindMilestoneOptions) ToConds() builder.Cond { cond := builder.NewCond() if opts.RepoID != 0 { cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) } - - switch opts.State { - case api.StateClosed: - cond = cond.And(builder.Eq{"is_closed": true}) - case api.StateAll: - break - // api.StateOpen: - default: - cond = cond.And(builder.Eq{"is_closed": false}) + if opts.IsClosed != util.OptionalBoolNone { + cond = cond.And(builder.Eq{"is_closed": opts.IsClosed.IsTrue()}) + } + if opts.RepoCond != nil && opts.RepoCond.IsValid() { + cond = cond.And(builder.In("repo_id", builder.Select("id").From("repository").Where(opts.RepoCond))) + } + if len(opts.RepoIDs) > 0 { + cond = cond.And(builder.In("repo_id", opts.RepoIDs)) } - if len(opts.Name) != 0 { cond = cond.And(db.BuildCaseInsensitiveLike("name", opts.Name)) } @@ -57,34 +56,23 @@ func (opts GetMilestonesOption) toCond() builder.Cond { return cond } -// GetMilestones returns milestones filtered by GetMilestonesOption's -func GetMilestones(ctx context.Context, opts GetMilestonesOption) (MilestoneList, int64, error) { - sess := db.GetEngine(ctx).Where(opts.toCond()) - - if opts.Page != 0 { - sess = db.SetSessionPagination(sess, &opts) - } - +func (opts FindMilestoneOptions) ToOrders() string { switch opts.SortType { case "furthestduedate": - sess.Desc("deadline_unix") + return "deadline_unix DESC" case "leastcomplete": - sess.Asc("completeness") + return "completeness ASC" case "mostcomplete": - sess.Desc("completeness") + return "completeness DESC" case "leastissues": - sess.Asc("num_issues") + return "num_issues ASC" case "mostissues": - sess.Desc("num_issues") + return "num_issues DESC" case "id": - sess.Asc("id") + return "id ASC" default: - sess.Asc("deadline_unix").Asc("id") + return "deadline_unix ASC, id ASC" } - - miles := make([]*Milestone, 0, opts.PageSize) - total, err := sess.FindAndCount(&miles) - return miles, total, err } // GetMilestoneIDsByNames returns a list of milestone ids by given names. @@ -99,49 +87,6 @@ func GetMilestoneIDsByNames(ctx context.Context, names []string) ([]int64, error Find(&ids) } -// SearchMilestones search milestones -func SearchMilestones(ctx context.Context, repoCond builder.Cond, page int, isClosed bool, sortType, keyword string) (MilestoneList, error) { - miles := make([]*Milestone, 0, setting.UI.IssuePagingNum) - sess := db.GetEngine(ctx).Where("is_closed = ?", isClosed) - if len(keyword) > 0 { - sess = sess.And(builder.Like{"UPPER(name)", strings.ToUpper(keyword)}) - } - if repoCond.IsValid() { - sess.In("repo_id", builder.Select("id").From("repository").Where(repoCond)) - } - if page > 0 { - sess = sess.Limit(setting.UI.IssuePagingNum, (page-1)*setting.UI.IssuePagingNum) - } - - switch sortType { - case "furthestduedate": - sess.Desc("deadline_unix") - case "leastcomplete": - sess.Asc("completeness") - case "mostcomplete": - sess.Desc("completeness") - case "leastissues": - sess.Asc("num_issues") - case "mostissues": - sess.Desc("num_issues") - default: - sess.Asc("deadline_unix") - } - return miles, sess.Find(&miles) -} - -// GetMilestonesByRepoIDs returns a list of milestones of given repositories and status. -func GetMilestonesByRepoIDs(ctx context.Context, repoIDs []int64, page int, isClosed bool, sortType string) (MilestoneList, error) { - return SearchMilestones( - ctx, - builder.In("repo_id", repoIDs), - page, - isClosed, - sortType, - "", - ) -} - // LoadTotalTrackedTimes loads for every milestone in the list the TotalTrackedTime by a batch request func (milestones MilestoneList) LoadTotalTrackedTimes(ctx context.Context) error { type totalTimesByMilestone struct { @@ -183,47 +128,9 @@ func (milestones MilestoneList) LoadTotalTrackedTimes(ctx context.Context) error return nil } -// CountMilestones returns number of milestones in given repository with other options -func CountMilestones(ctx context.Context, opts GetMilestonesOption) (int64, error) { - return db.GetEngine(ctx). - Where(opts.toCond()). - Count(new(Milestone)) -} - -// CountMilestonesByRepoCond map from repo conditions to number of milestones matching the options` -func CountMilestonesByRepoCond(ctx context.Context, repoCond builder.Cond, isClosed bool) (map[int64]int64, error) { - sess := db.GetEngine(ctx).Where("is_closed = ?", isClosed) - if repoCond.IsValid() { - sess.In("repo_id", builder.Select("id").From("repository").Where(repoCond)) - } - - countsSlice := make([]*struct { - RepoID int64 - Count int64 - }, 0, 10) - if err := sess.GroupBy("repo_id"). - Select("repo_id AS repo_id, COUNT(*) AS count"). - Table("milestone"). - Find(&countsSlice); err != nil { - return nil, err - } - - countMap := make(map[int64]int64, len(countsSlice)) - for _, c := range countsSlice { - countMap[c.RepoID] = c.Count - } - return countMap, nil -} - // CountMilestonesByRepoCondAndKw map from repo conditions and the keyword of milestones' name to number of milestones matching the options` -func CountMilestonesByRepoCondAndKw(ctx context.Context, repoCond builder.Cond, keyword string, isClosed bool) (map[int64]int64, error) { - sess := db.GetEngine(ctx).Where("is_closed = ?", isClosed) - if len(keyword) > 0 { - sess = sess.And(builder.Like{"UPPER(name)", strings.ToUpper(keyword)}) - } - if repoCond.IsValid() { - sess.In("repo_id", builder.Select("id").From("repository").Where(repoCond)) - } +func CountMilestonesMap(ctx context.Context, opts FindMilestoneOptions) (map[int64]int64, error) { + sess := db.GetEngine(ctx).Where(opts.ToConds()) countsSlice := make([]*struct { RepoID int64 diff --git a/models/issues/milestone_test.go b/models/issues/milestone_test.go index ecfccf6ddbe97..0581d3d14881f 100644 --- a/models/issues/milestone_test.go +++ b/models/issues/milestone_test.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" "xorm.io/builder" @@ -39,10 +40,15 @@ func TestGetMilestoneByRepoID(t *testing.T) { func TestGetMilestonesByRepoID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64, state api.StateType) { + var isClosed util.OptionalBool + switch state { + case api.StateClosed, api.StateOpen: + isClosed = util.OptionalBoolOf(state == api.StateClosed) + } repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - milestones, _, err := issues_model.GetMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ - RepoID: repo.ID, - State: state, + milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + RepoID: repo.ID, + IsClosed: isClosed, }) assert.NoError(t, err) @@ -77,9 +83,9 @@ func TestGetMilestonesByRepoID(t *testing.T) { test(3, api.StateClosed) test(3, api.StateAll) - milestones, _, err := issues_model.GetMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ - RepoID: unittest.NonexistentID, - State: api.StateOpen, + milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + RepoID: unittest.NonexistentID, + IsClosed: util.OptionalBoolFalse, }) assert.NoError(t, err) assert.Len(t, milestones, 0) @@ -90,13 +96,13 @@ func TestGetMilestones(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) test := func(sortType string, sortCond func(*issues_model.Milestone) int) { for _, page := range []int{0, 1} { - milestones, _, err := issues_model.GetMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, }, RepoID: repo.ID, - State: api.StateOpen, + IsClosed: util.OptionalBoolFalse, SortType: sortType, }) assert.NoError(t, err) @@ -107,13 +113,13 @@ func TestGetMilestones(t *testing.T) { } assert.True(t, sort.IntsAreSorted(values)) - milestones, _, err = issues_model.GetMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + milestones, err = db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, }, RepoID: repo.ID, - State: api.StateClosed, + IsClosed: util.OptionalBoolTrue, Name: "", SortType: sortType, }) @@ -150,9 +156,8 @@ func TestCountRepoMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ RepoID: repoID, - State: api.StateAll, }) assert.NoError(t, err) assert.EqualValues(t, repo.NumMilestones, count) @@ -161,9 +166,8 @@ func TestCountRepoMilestones(t *testing.T) { test(2) test(3) - count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ + count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ RepoID: unittest.NonexistentID, - State: api.StateAll, }) assert.NoError(t, err) assert.EqualValues(t, 0, count) @@ -173,9 +177,9 @@ func TestCountRepoClosedMilestones(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) test := func(repoID int64) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ - RepoID: repoID, - State: api.StateClosed, + count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + RepoID: repoID, + IsClosed: util.OptionalBoolTrue, }) assert.NoError(t, err) assert.EqualValues(t, repo.NumClosedMilestones, count) @@ -184,9 +188,9 @@ func TestCountRepoClosedMilestones(t *testing.T) { test(2) test(3) - count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ - RepoID: unittest.NonexistentID, - State: api.StateClosed, + count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + RepoID: unittest.NonexistentID, + IsClosed: util.OptionalBoolTrue, }) assert.NoError(t, err) assert.EqualValues(t, 0, count) @@ -201,12 +205,19 @@ func TestCountMilestonesByRepoIDs(t *testing.T) { repo1OpenCount, repo1ClosedCount := milestonesCount(1) repo2OpenCount, repo2ClosedCount := milestonesCount(2) - openCounts, err := issues_model.CountMilestonesByRepoCond(db.DefaultContext, builder.In("repo_id", []int64{1, 2}), false) + openCounts, err := issues_model.CountMilestonesMap(db.DefaultContext, issues_model.FindMilestoneOptions{ + RepoIDs: []int64{1, 2}, + IsClosed: util.OptionalBoolFalse, + }) assert.NoError(t, err) assert.EqualValues(t, repo1OpenCount, openCounts[1]) assert.EqualValues(t, repo2OpenCount, openCounts[2]) - closedCounts, err := issues_model.CountMilestonesByRepoCond(db.DefaultContext, builder.In("repo_id", []int64{1, 2}), true) + closedCounts, err := issues_model.CountMilestonesMap(db.DefaultContext, + issues_model.FindMilestoneOptions{ + RepoIDs: []int64{1, 2}, + IsClosed: util.OptionalBoolTrue, + }) assert.NoError(t, err) assert.EqualValues(t, repo1ClosedCount, closedCounts[1]) assert.EqualValues(t, repo2ClosedCount, closedCounts[2]) @@ -218,7 +229,15 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) test := func(sortType string, sortCond func(*issues_model.Milestone) int) { for _, page := range []int{0, 1} { - openMilestones, err := issues_model.GetMilestonesByRepoIDs(db.DefaultContext, []int64{repo1.ID, repo2.ID}, page, false, sortType) + openMilestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + ListOptions: db.ListOptions{ + Page: page, + PageSize: setting.UI.IssuePagingNum, + }, + RepoIDs: []int64{repo1.ID, repo2.ID}, + IsClosed: util.OptionalBoolFalse, + SortType: sortType, + }) assert.NoError(t, err) assert.Len(t, openMilestones, repo1.NumOpenMilestones+repo2.NumOpenMilestones) values := make([]int, len(openMilestones)) @@ -227,7 +246,16 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { } assert.True(t, sort.IntsAreSorted(values)) - closedMilestones, err := issues_model.GetMilestonesByRepoIDs(db.DefaultContext, []int64{repo1.ID, repo2.ID}, page, true, sortType) + closedMilestones, err := db.Find[issues_model.Milestone](db.DefaultContext, + issues_model.FindMilestoneOptions{ + ListOptions: db.ListOptions{ + Page: page, + PageSize: setting.UI.IssuePagingNum, + }, + RepoIDs: []int64{repo1.ID, repo2.ID}, + IsClosed: util.OptionalBoolTrue, + SortType: sortType, + }) assert.NoError(t, err) assert.Len(t, closedMilestones, repo1.NumClosedMilestones+repo2.NumClosedMilestones) values = make([]int, len(closedMilestones)) diff --git a/modules/context/repo.go b/modules/context/repo.go index f91dd6aa9a83e..a18dc873b6444 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -668,11 +668,9 @@ func RepoAssignment(ctx *Context) context.CancelFunc { branchOpts := git_model.FindBranchOptions{ RepoID: ctx.Repo.Repository.ID, IsDeletedBranch: util.OptionalBoolFalse, - ListOptions: db.ListOptions{ - ListAll: true, - }, + ListOptions: db.ListOptionsAll, } - branchesTotal, err := git_model.CountBranches(ctx, branchOpts) + branchesTotal, err := db.Count[git_model.Branch](ctx, branchOpts) if err != nil { ctx.ServerError("CountBranches", err) return cancel diff --git a/modules/repository/branch.go b/modules/repository/branch.go index 8daceecb44ffa..cd45f162276f3 100644 --- a/modules/repository/branch.go +++ b/modules/repository/branch.go @@ -49,11 +49,9 @@ func SyncRepoBranchesWithRepo(ctx context.Context, repo *repo_model.Repository, dbBranches := make(map[string]*git_model.Branch) { - branches, err := git_model.FindBranches(ctx, git_model.FindBranchOptions{ - ListOptions: db.ListOptions{ - ListAll: true, - }, - RepoID: repo.ID, + branches, err := db.Find[git_model.Branch](ctx, git_model.FindBranchOptions{ + ListOptions: db.ListOptionsAll, + RepoID: repo.ID, }) if err != nil { return 0, err diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 677105bdb506c..36c85c8a57034 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -10,6 +10,7 @@ import ( "net/http" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/models/organization" user_model "code.gitea.io/gitea/models/user" @@ -137,7 +138,7 @@ func DeleteBranch(ctx *context.APIContext) { } // check whether branches of this repository has been synced - totalNumOfBranches, err := git_model.CountBranches(ctx, git_model.FindBranchOptions{ + totalNumOfBranches, err := db.Count[git_model.Branch](ctx, git_model.FindBranchOptions{ RepoID: ctx.Repo.Repository.ID, IsDeletedBranch: util.OptionalBoolFalse, }) @@ -341,7 +342,7 @@ func ListBranches(ctx *context.APIContext) { IsDeletedBranch: util.OptionalBoolFalse, } var err error - totalNumOfBranches, err = git_model.CountBranches(ctx, branchOpts) + totalNumOfBranches, err = db.Count[git_model.Branch](ctx, branchOpts) if err != nil { ctx.Error(http.StatusInternalServerError, "CountBranches", err) return @@ -360,7 +361,7 @@ func ListBranches(ctx *context.APIContext) { return } - branches, err := git_model.FindBranches(ctx, branchOpts) + branches, err := db.Find[git_model.Branch](ctx, branchOpts) if err != nil { ctx.Error(http.StatusInternalServerError, "GetBranches", err) return diff --git a/routers/api/v1/repo/milestone.go b/routers/api/v1/repo/milestone.go index da470dfa74c5b..9c2ed16d930c1 100644 --- a/routers/api/v1/repo/milestone.go +++ b/routers/api/v1/repo/milestone.go @@ -9,10 +9,12 @@ import ( "strconv" "time" + "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" "code.gitea.io/gitea/services/convert" @@ -58,14 +60,21 @@ func ListMilestones(ctx *context.APIContext) { // "404": // "$ref": "#/responses/notFound" - milestones, total, err := issues_model.GetMilestones(ctx, issues_model.GetMilestonesOption{ + state := api.StateType(ctx.FormString("state")) + var isClosed util.OptionalBool + switch state { + case api.StateClosed, api.StateOpen: + isClosed = util.OptionalBoolOf(state == api.StateClosed) + } + + milestones, total, err := db.FindAndCount[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ ListOptions: utils.GetListOptions(ctx), RepoID: ctx.Repo.Repository.ID, - State: api.StateType(ctx.FormString("state")), + IsClosed: isClosed, Name: ctx.FormString("name"), }) if err != nil { - ctx.Error(http.StatusInternalServerError, "GetMilestones", err) + ctx.Error(http.StatusInternalServerError, "db.FindAndCount[issues_model.Milestone]", err) return } diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index ba8b49774b977..14781be822da0 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -510,9 +510,8 @@ func Issues(ctx *context.Context) { func renderMilestones(ctx *context.Context) { // Get milestones - milestones, _, err := issues_model.GetMilestones(ctx, issues_model.GetMilestonesOption{ + milestones, err := db.Find[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ RepoID: ctx.Repo.Repository.ID, - State: api.StateAll, }) if err != nil { ctx.ServerError("GetAllRepoMilestones", err) @@ -534,17 +533,17 @@ func renderMilestones(ctx *context.Context) { // RetrieveRepoMilestonesAndAssignees find all the milestones and assignees of a repository func RetrieveRepoMilestonesAndAssignees(ctx *context.Context, repo *repo_model.Repository) { var err error - ctx.Data["OpenMilestones"], _, err = issues_model.GetMilestones(ctx, issues_model.GetMilestonesOption{ - RepoID: repo.ID, - State: api.StateOpen, + ctx.Data["OpenMilestones"], err = db.Find[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ + RepoID: repo.ID, + IsClosed: util.OptionalBoolFalse, }) if err != nil { ctx.ServerError("GetMilestones", err) return } - ctx.Data["ClosedMilestones"], _, err = issues_model.GetMilestones(ctx, issues_model.GetMilestonesOption{ - RepoID: repo.ID, - State: api.StateClosed, + ctx.Data["ClosedMilestones"], err = db.Find[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ + RepoID: repo.ID, + IsClosed: util.OptionalBoolTrue, }) if err != nil { ctx.ServerError("GetMilestones", err) diff --git a/routers/web/repo/milestone.go b/routers/web/repo/milestone.go index 0e6f63074749f..fbecabb2b1f0f 100644 --- a/routers/web/repo/milestone.go +++ b/routers/web/repo/milestone.go @@ -16,7 +16,6 @@ import ( "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/markdown" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" @@ -46,18 +45,13 @@ func Milestones(ctx *context.Context) { page = 1 } - state := structs.StateOpen - if isShowClosed { - state = structs.StateClosed - } - - miles, total, err := issues_model.GetMilestones(ctx, issues_model.GetMilestonesOption{ + miles, total, err := db.FindAndCount[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ ListOptions: db.ListOptions{ Page: page, PageSize: setting.UI.IssuePagingNum, }, RepoID: ctx.Repo.Repository.ID, - State: state, + IsClosed: util.OptionalBoolOf(isShowClosed), SortType: sortType, Name: keyword, }) @@ -80,7 +74,7 @@ func Milestones(ctx *context.Context) { url.QueryEscape(keyword), url.QueryEscape(sortType)) if ctx.Repo.Repository.IsTimetrackerEnabled(ctx) { - if err := miles.LoadTotalTrackedTimes(ctx); err != nil { + if err := issues_model.MilestoneList(miles).LoadTotalTrackedTimes(ctx); err != nil { ctx.ServerError("LoadTotalTrackedTimes", err) return } diff --git a/routers/web/user/home.go b/routers/web/user/home.go index d54e762429069..204d4adbd4900 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -212,13 +212,26 @@ func Milestones(ctx *context.Context) { } } - counts, err := issues_model.CountMilestonesByRepoCondAndKw(ctx, userRepoCond, keyword, isShowClosed) + counts, err := issues_model.CountMilestonesMap(ctx, issues_model.FindMilestoneOptions{ + RepoCond: userRepoCond, + Name: keyword, + IsClosed: util.OptionalBoolOf(isShowClosed), + }) if err != nil { ctx.ServerError("CountMilestonesByRepoIDs", err) return } - milestones, err := issues_model.SearchMilestones(ctx, repoCond, page, isShowClosed, sortType, keyword) + milestones, err := db.Find[issues_model.Milestone](ctx, issues_model.FindMilestoneOptions{ + ListOptions: db.ListOptions{ + Page: page, + PageSize: setting.UI.IssuePagingNum, + }, + RepoCond: repoCond, + IsClosed: util.OptionalBoolOf(isShowClosed), + SortType: sortType, + Name: keyword, + }) if err != nil { ctx.ServerError("SearchMilestones", err) return diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index 84db83bc67080..7c291eabafa62 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -65,16 +65,16 @@ func TestGiteaUploadRepo(t *testing.T) { assert.True(t, repo.HasWiki()) assert.EqualValues(t, repo_model.RepositoryReady, repo.Status) - milestones, _, err := issues_model.GetMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ - RepoID: repo.ID, - State: structs.StateOpen, + milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + RepoID: repo.ID, + IsClosed: util.OptionalBoolFalse, }) assert.NoError(t, err) assert.Len(t, milestones, 1) - milestones, _, err = issues_model.GetMilestones(db.DefaultContext, issues_model.GetMilestonesOption{ - RepoID: repo.ID, - State: structs.StateClosed, + milestones, err = db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ + RepoID: repo.ID, + IsClosed: util.OptionalBoolTrue, }) assert.NoError(t, err) assert.Empty(t, milestones) diff --git a/services/repository/branch.go b/services/repository/branch.go index 6dc286675f3d6..b3dbb252ca34e 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -66,22 +66,17 @@ func LoadBranches(ctx context.Context, repo *repo_model.Repository, gitRepo *git Keyword: keyword, } - totalNumOfBranches, err := git_model.CountBranches(ctx, branchOpts) + dbBranches, totalNumOfBranches, err := db.FindAndCount[git_model.Branch](ctx, branchOpts) if err != nil { return nil, nil, 0, err } branchOpts.ExcludeBranchNames = []string{repo.DefaultBranch} - dbBranches, err := git_model.FindBranches(ctx, branchOpts) - if err != nil { - return nil, nil, 0, err - } - - if err := dbBranches.LoadDeletedBy(ctx); err != nil { + if err := git_model.BranchList(dbBranches).LoadDeletedBy(ctx); err != nil { return nil, nil, 0, err } - if err := dbBranches.LoadPusher(ctx); err != nil { + if err := git_model.BranchList(dbBranches).LoadPusher(ctx); err != nil { return nil, nil, 0, err } From f2a309e6c81f9ce0de5346e49efbc98fbd20e54b Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 11 Dec 2023 23:55:10 +0800 Subject: [PATCH 12/60] Improve doctor cli behavior (#28422) 1. Do not sort the "checks" slice again and again when "Register", it just wastes CPU when the Gitea instance runs 2. If a check doesn't exist, tell the end user 3. Add some tests --- cmd/doctor.go | 51 ++++++++++++++++++---------------------- cmd/doctor_test.go | 33 ++++++++++++++++++++++++++ modules/doctor/doctor.go | 16 ++++++++----- 3 files changed, 66 insertions(+), 34 deletions(-) create mode 100644 cmd/doctor_test.go diff --git a/cmd/doctor.go b/cmd/doctor.go index d040a3af1c815..4085d37332478 100644 --- a/cmd/doctor.go +++ b/cmd/doctor.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/migrations" migrate_base "code.gitea.io/gitea/models/migrations/base" + "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/doctor" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -22,6 +23,19 @@ import ( "xorm.io/xorm" ) +// CmdDoctor represents the available doctor sub-command. +var CmdDoctor = &cli.Command{ + Name: "doctor", + Usage: "Diagnose and optionally fix problems", + Description: "A command to diagnose problems with the current Gitea instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.", + + Subcommands: []*cli.Command{ + cmdDoctorCheck, + cmdRecreateTable, + cmdDoctorConvert, + }, +} + var cmdDoctorCheck = &cli.Command{ Name: "check", Usage: "Diagnose and optionally fix problems", @@ -60,19 +74,6 @@ var cmdDoctorCheck = &cli.Command{ }, } -// CmdDoctor represents the available doctor sub-command. -var CmdDoctor = &cli.Command{ - Name: "doctor", - Usage: "Diagnose and optionally fix problems", - Description: "A command to diagnose problems with the current Gitea instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.", - - Subcommands: []*cli.Command{ - cmdDoctorCheck, - cmdRecreateTable, - cmdDoctorConvert, - }, -} - var cmdRecreateTable = &cli.Command{ Name: "recreate-table", Usage: "Recreate tables from XORM definitions and copy the data.", @@ -177,6 +178,7 @@ func runDoctorCheck(ctx *cli.Context) error { if ctx.IsSet("list") { w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0) _, _ = w.Write([]byte("Default\tName\tTitle\n")) + doctor.SortChecks(doctor.Checks) for _, check := range doctor.Checks { if check.IsDefault { _, _ = w.Write([]byte{'*'}) @@ -192,26 +194,20 @@ func runDoctorCheck(ctx *cli.Context) error { var checks []*doctor.Check if ctx.Bool("all") { - checks = doctor.Checks + checks = make([]*doctor.Check, len(doctor.Checks)) + copy(checks, doctor.Checks) } else if ctx.IsSet("run") { addDefault := ctx.Bool("default") - names := ctx.StringSlice("run") - for i, name := range names { - names[i] = strings.ToLower(strings.TrimSpace(name)) - } - + runNamesSet := container.SetOf(ctx.StringSlice("run")...) for _, check := range doctor.Checks { - if addDefault && check.IsDefault { + if (addDefault && check.IsDefault) || runNamesSet.Contains(check.Name) { checks = append(checks, check) - continue - } - for _, name := range names { - if name == check.Name { - checks = append(checks, check) - break - } + runNamesSet.Remove(check.Name) } } + if len(runNamesSet) > 0 { + return fmt.Errorf("unknown checks: %q", strings.Join(runNamesSet.Values(), ",")) + } } else { for _, check := range doctor.Checks { if check.IsDefault { @@ -219,6 +215,5 @@ func runDoctorCheck(ctx *cli.Context) error { } } } - return doctor.RunChecks(stdCtx, colorize, ctx.Bool("fix"), checks) } diff --git a/cmd/doctor_test.go b/cmd/doctor_test.go new file mode 100644 index 0000000000000..75376a567ee02 --- /dev/null +++ b/cmd/doctor_test.go @@ -0,0 +1,33 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package cmd + +import ( + "context" + "testing" + + "code.gitea.io/gitea/modules/doctor" + "code.gitea.io/gitea/modules/log" + + "github.com/stretchr/testify/assert" + "github.com/urfave/cli/v2" +) + +func TestDoctorRun(t *testing.T) { + doctor.Register(&doctor.Check{ + Title: "Test Check", + Name: "test-check", + Run: func(ctx context.Context, logger log.Logger, autofix bool) error { return nil }, + + SkipDatabaseInitialization: true, + }) + app := cli.NewApp() + app.Commands = []*cli.Command{cmdDoctorCheck} + err := app.Run([]string{"./gitea", "check", "--run", "test-check"}) + assert.NoError(t, err) + err = app.Run([]string{"./gitea", "check", "--run", "no-such"}) + assert.ErrorContains(t, err, `unknown checks: "no-such"`) + err = app.Run([]string{"./gitea", "check", "--run", "test-check,no-such"}) + assert.ErrorContains(t, err, `unknown checks: "no-such"`) +} diff --git a/modules/doctor/doctor.go b/modules/doctor/doctor.go index ceee32285218b..559f8e06da342 100644 --- a/modules/doctor/doctor.go +++ b/modules/doctor/doctor.go @@ -79,6 +79,7 @@ var Checks []*Check // RunChecks runs the doctor checks for the provided list func RunChecks(ctx context.Context, colorize, autofix bool, checks []*Check) error { + SortChecks(checks) // the checks output logs by a special logger, they do not use the default logger logger := log.BaseLoggerToGeneralLogger(&doctorCheckLogger{colorize: colorize}) loggerStep := log.BaseLoggerToGeneralLogger(&doctorCheckStepLogger{colorize: colorize}) @@ -104,20 +105,23 @@ func RunChecks(ctx context.Context, colorize, autofix bool, checks []*Check) err logger.Info("OK") } } - logger.Info("\nAll done.") + logger.Info("\nAll done (checks: %d).", len(checks)) return nil } // Register registers a command with the list func Register(command *Check) { Checks = append(Checks, command) - sort.SliceStable(Checks, func(i, j int) bool { - if Checks[i].Priority == Checks[j].Priority { - return Checks[i].Name < Checks[j].Name +} + +func SortChecks(checks []*Check) { + sort.SliceStable(checks, func(i, j int) bool { + if checks[i].Priority == checks[j].Priority { + return checks[i].Name < checks[j].Name } - if Checks[i].Priority == 0 { + if checks[i].Priority == 0 { return false } - return Checks[i].Priority < Checks[j].Priority + return checks[i].Priority < checks[j].Priority }) } From 4b0940cb9ff3287038a1f8aeab74b68b82179c4c Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Tue, 12 Dec 2023 00:19:30 +0100 Subject: [PATCH 13/60] Let `curl` write the content to file (#28427) --- templates/package/content/generic.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/package/content/generic.tmpl b/templates/package/content/generic.tmpl index ba4df0a57d2d2..05aa4aecad9f0 100644 --- a/templates/package/content/generic.tmpl +++ b/templates/package/content/generic.tmpl @@ -6,7 +6,7 @@

 {{- range .PackageDescriptor.Files -}}
-curl 
+curl -OJ 
 {{end -}}
 				
From baea205675e6bdd058ada1e7ff148582cabeb6dc Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Tue, 12 Dec 2023 00:25:05 +0000 Subject: [PATCH 14/60] [skip ci] Updated translations via Crowdin --- options/locale/locale_cs-CZ.ini | 17 ++------------- options/locale/locale_de-DE.ini | 21 +++--------------- options/locale/locale_el-GR.ini | 17 ++------------- options/locale/locale_es-ES.ini | 21 +++--------------- options/locale/locale_fa-IR.ini | 13 ++--------- options/locale/locale_fi-FI.ini | 8 ++----- options/locale/locale_fr-FR.ini | 29 +++++++++---------------- options/locale/locale_hu-HU.ini | 8 ++----- options/locale/locale_id-ID.ini | 5 ++--- options/locale/locale_is-IS.ini | 9 ++------ options/locale/locale_it-IT.ini | 13 ++--------- options/locale/locale_ja-JP.ini | 21 +++--------------- options/locale/locale_ko-KR.ini | 5 ++--- options/locale/locale_lv-LV.ini | 17 ++------------- options/locale/locale_nl-NL.ini | 13 ++--------- options/locale/locale_pl-PL.ini | 13 ++--------- options/locale/locale_pt-BR.ini | 18 ++-------------- options/locale/locale_pt-PT.ini | 38 +++++++++++++++++++-------------- options/locale/locale_ru-RU.ini | 17 ++------------- options/locale/locale_si-LK.ini | 11 ++-------- options/locale/locale_sk-SK.ini | 9 ++------ options/locale/locale_sv-SE.ini | 7 ++---- options/locale/locale_tr-TR.ini | 20 +++-------------- options/locale/locale_uk-UA.ini | 13 ++--------- options/locale/locale_zh-CN.ini | 21 +++--------------- options/locale/locale_zh-HK.ini | 5 ++--- options/locale/locale_zh-TW.ini | 17 ++------------- 27 files changed, 87 insertions(+), 319 deletions(-) diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 602fe0bce83f7..5a48624e07fed 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -104,9 +104,6 @@ write=Zapsat preview=Náhled loading=Načítá se… -step1=Krok 1: -step2=Krok 2: - error=Chyba error404=Stránka, kterou se snažíte zobrazit, buď neexistuje, nebo nemáte oprávnění ji zobrazit. @@ -342,7 +339,6 @@ code_last_indexed_at=Naposledy indexováno %s relevant_repositories_tooltip=Repozitáře, které jsou rozštěpení nebo nemají žádné téma, ikonu a žádný popis jsou skryty. relevant_repositories=Zobrazují se pouze relevantní repositáře, zobrazit nefiltrované výsledky. - [auth] create_new_account=Registrovat účet register_helper_msg=Již máte účet? Přihlaste se! @@ -951,10 +947,8 @@ transfer.reject_desc=Zrušit převod do „%s“ desc.private=Soukromý desc.public=Veřejný -desc.private_template=Soukromá šablona -desc.public_template=Šablona +desc.template=Šablona desc.internal=Interní -desc.internal_template=Interní šablona desc.archived=Archivováno template.items=Položky šablony @@ -1650,9 +1644,6 @@ pulls.update_not_allowed=Nemáte oprávnění aktualizovat větev pulls.outdated_with_base_branch=Tato větev je zastaralá oproti základní větvi pulls.closed_at=`uzavřel/a tento požadavek na natažení %[2]s` pulls.reopened_at=`znovuotevřel/a tento požadavek na natažení %[2]s` -pulls.merge_instruction_hint=`Můžete také zobrazit instrukce příkazové řádky.` -pulls.merge_instruction_step1_desc=Z vašeho repositáře projektu se podívejte na novou větev a vyzkoušejte změny. -pulls.merge_instruction_step2_desc=Slučte změny a aktualizujte je na Gitea. pulls.auto_merge_button_when_succeed=(Když kontroly uspějí) pulls.auto_merge_when_succeed=Automaticky sloučit, když všechny kontroly uspějí @@ -2571,7 +2562,6 @@ emails.updated=E-mail aktualizován emails.not_updated=Aktualizace požadované e-mailové adresy se nezdařila: %v emails.duplicate_active=Tato e-mailová adresa je již aktivní pro jiného uživatele. emails.change_email_header=Aktualizovat vlastnosti e-mailu -emails.change_email_text=Opravdu chcete aktualizovat tuto e-mailovou adresu? orgs.org_manage_panel=Správa organizací orgs.name=Název @@ -3031,8 +3021,6 @@ alpine.repository.repositories=Repozitáře alpine.repository.architectures=Architektury cargo.registry=Nastavte tento registr v konfiguračním souboru Cargo (například ~/.cargo/config.toml): cargo.install=Chcete-li nainstalovat balíček pomocí Cargo, spusťte následující příkaz: -cargo.details.repository_site=Stránka repositáře -cargo.details.documentation_site=Stránka dokumentace chef.registry=Nastavit tento registr v souboru ~/.chef/config.rb: chef.install=Pro instalaci balíčku spusťte následující příkaz: composer.registry=Nastavit tento registr v souboru ~/.composer/config.json: @@ -3044,8 +3032,6 @@ conan.registry=Nastavte tento registr z příkazového řádku: conan.install=Pro instalaci balíčku pomocí Conan spusťte následující příkaz: conda.registry=Nastavte tento registr jako Conda repozitář ve vašem .condarc: conda.install=Pro instalaci balíčku pomocí Conda spusťte následující příkaz: -conda.details.repository_site=Stránka repositáře -conda.details.documentation_site=Stránka dokumentace container.details.type=Typ obrazu container.details.platform=Platforma container.pull=Stáhněte obraz z příkazové řádky: @@ -3205,5 +3191,6 @@ runs.status=Status type-3.display_name=Projekt organizace [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=Symbolický odkaz diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 8a93e493f166a..c15e1de71a6b1 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -108,9 +108,6 @@ write=Verfassen preview=Vorschau loading=Laden… -step1=Schritt 1: -step2=Schritt 2: - error=Fehler error404=Die Seite, die Du versuchst aufzurufen, existiert nicht oder Du bist nicht berechtigt, diese anzusehen. go_back=Zurück @@ -354,7 +351,6 @@ code_last_indexed_at=Zuletzt indexiert %s relevant_repositories_tooltip=Repositories, die Forks sind oder die kein Thema, kein Symbol und keine Beschreibung haben, werden ausgeblendet. relevant_repositories=Es werden nur relevante Repositories angezeigt, ungefilterte Ergebnisse anzeigen. - [auth] create_new_account=Konto anlegen register_helper_msg=Hast du bereits ein Konto? Jetzt anmelden! @@ -924,7 +920,6 @@ visibility.private=Privat visibility.private_tooltip=Sichtbar nur für Mitglieder von Organisationen, denen du beigetreten bist [repo] -new_repo_helper=Ein Repository enthält alle Projektdateien, einschließlich des Änderungsverlaufs. Schon woanders vorhanden? Migriere das Repository. owner=Besitzer owner_helper=Einige Organisationen könnten in der Dropdown-Liste nicht angezeigt werden, da die Anzahl an Repositories begrenzt ist. repo_name=Repository-Name @@ -1029,10 +1024,8 @@ transfer.no_permission_to_reject=Du hast keine Berechtigung, diesen Transfer abz desc.private=Privat desc.public=Öffentlich -desc.private_template=Private Vorlage -desc.public_template=Vorlage +desc.template=Template desc.internal=Intern -desc.internal_template=Interne Vorlage desc.archived=Archiviert template.items=Template-Elemente @@ -1797,9 +1790,6 @@ pulls.outdated_with_base_branch=Dieser Branch enthält nicht die neusten Commits pulls.close=Pull-Request schließen pulls.closed_at=`hat diesen Pull-Request %[2]s geschlossen` pulls.reopened_at=`hat diesen Pull-Request %[2]s wieder geöffnet` -pulls.merge_instruction_hint=`Siehe auch die Anleitung für die Kommandozeile.` -pulls.merge_instruction_step1_desc=Wechsle auf einen neuen Branch in deinem lokalen Repository und teste die Änderungen. -pulls.merge_instruction_step2_desc=Führe die Änderungen zusammen und aktualisiere den Stand online auf Gitea. pulls.clear_merge_message=Merge-Nachricht löschen pulls.clear_merge_message_hint=Das Löschen der Merge-Nachricht wird nur den Inhalt der Commit-Nachricht entfernen und generierte Git-Trailer wie "Co-Authored-By …" erhalten. @@ -2311,7 +2301,6 @@ settings.dismiss_stale_approvals_desc=Wenn neue Commits gepusht werden, die den settings.require_signed_commits=Signierte Commits erforderlich settings.require_signed_commits_desc=Pushes auf diesen Branch ablehnen, wenn Commits nicht signiert oder nicht überprüfbar sind. settings.protect_branch_name_pattern=Muster für geschützte Branchnamen -settings.protect_branch_name_pattern_desc=Geschützte Branch-Namensmuster. Lies die Dokumentation für die Muster-Syntax. Beispiele: main, release/** settings.protect_patterns=Muster settings.protect_protected_file_patterns=Geschützte Dateimuster (durch Semikolon ';' getrennt): settings.protect_protected_file_patterns_desc=Geschützte Dateien dürfen nicht direkt geändert werden, auch wenn der Benutzer Rechte hat, Dateien in diesem Branch hinzuzufügen, zu bearbeiten oder zu löschen. Mehrere Muster können mit Semikolon (';') getrennt werden. Siehe github.com/gobwas/glob Dokumentation zur Mustersyntax. Beispiele: .drone.yml, /docs/**/*.txt. @@ -2507,7 +2496,6 @@ release.releases_for=Releases für %s release.tags_for=Tags für %s branch.name=Branchname -branch.search=Branch suchen branch.already_exists=Ein Branch mit dem Namen "%s" existiert bereits. branch.delete_head=Löschen branch.delete=Branch "%s" löschen @@ -2530,6 +2518,7 @@ branch.default_deletion_failed=Branch "%s" kann nicht gelöscht werden, da diese branch.restore=Branch "%s" wiederherstellen branch.download=Branch "%s" herunterladen branch.rename=Branch "%s" umbenennen +branch.search=Branch suchen branch.included_desc=Dieser Branch ist im Standard-Branch enthalten branch.included=Enthalten branch.create_new_branch=Branch aus Branch erstellen: @@ -2857,7 +2846,6 @@ emails.updated=E-Mail aktualisiert emails.not_updated=Fehler beim Aktualisieren der angeforderten E-Mail-Adresse: %v emails.duplicate_active=Diese E-Mail-Adresse wird bereits von einem Nutzer verwendet. emails.change_email_header=E-Mail-Eigenschaften aktualisieren -emails.change_email_text=Bist du dir sicher, diese E-Mail-Adresse zu aktualisieren? orgs.org_manage_panel=Organisationsverwaltung orgs.name=Name @@ -3341,8 +3329,6 @@ alpine.repository.repositories=Repositories alpine.repository.architectures=Architekturen cargo.registry=Richte diese Registry in der Cargo-Konfigurationsdatei ein (z.B. ~/.cargo/config.toml): cargo.install=Um das Paket mit Cargo zu installieren, führe den folgenden Befehl aus: -cargo.details.repository_site=Repository-Seite -cargo.details.documentation_site=Dokumentationsseite chef.registry=Richte diese Registry in deiner ~/.chef/config.rb Datei ein: chef.install=Nutze folgenden Befehl, um das Paket zu installieren: composer.registry=Setze diese Paketverwaltung in deiner ~/.composer/config.json Datei auf: @@ -3354,8 +3340,6 @@ conan.registry=Diese Registry über die Kommandozeile einrichten: conan.install=Um das Paket mit Conan zu installieren, führe den folgenden Befehl aus: conda.registry=Richte diese Registry als Conda-Repository in deiner .condarc Datei ein: conda.install=Um das Paket mit Conda zu installieren, führe den folgenden Befehl aus: -conda.details.repository_site=Repository-Seite -conda.details.documentation_site=Dokumentationsseite container.details.type=Container-Image Typ container.details.platform=Plattform container.pull=Downloade das Container-Image aus der Kommandozeile: @@ -3564,6 +3548,7 @@ type-3.display_name=Organisationsprojekt [git.filemode] changed_filemode=%[1]s → %[2]s +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … directory=Verzeichnis normal_file=Normale Datei executable_file=Ausführbare Datei diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index 2dc615a1b336f..b540fe2e5dc92 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -104,9 +104,6 @@ write=Σύνταξη preview=Προεπισκόπηση loading=Φόρτωση… -step1=Βήμα 1: -step2=Βήμα 2: - error=Σφάλμα error404=Η σελίδα που προσπαθείτε να φτάσετε είτε δεν υπάρχει είτε δεν είστε εξουσιοδοτημένοι για να την δείτε. @@ -343,7 +340,6 @@ code_last_indexed_at=Τελευταίο δημιουργία ευρετηρίο relevant_repositories_tooltip=Τα αποθετήρια που είναι forks ή που δεν έχουν θέμα, εικονίδιο και περιγραφή είναι κρυμμένα. relevant_repositories=Εμφανίζονται μόνο τα σχετικά αποθετήρια, εμφάνιση χωρίς φίλτρο. - [auth] create_new_account=Εγγραφή Λογαριασμού register_helper_msg=Έχετε ήδη λογαριασμό; Συνδεθείτε τώρα! @@ -965,10 +961,8 @@ transfer.reject_desc=`Ακύρωση μεταφοράς σε "%s"` desc.private=Ιδιωτικό desc.public=Δημόσιο -desc.private_template=Ιδιωτικό πρότυπο -desc.public_template=Πρότυπο +desc.template=Πρότυπο desc.internal=Εσωτερικό -desc.internal_template=Εσωτερικό πρότυπο desc.archived=Αρχειοθετημένο template.items=Αντικείμενα Προτύπου @@ -1686,9 +1680,6 @@ pulls.outdated_with_base_branch=Αυτός ο κλάδος δεν είναι ε pulls.close=Κλείσιμο Pull Request pulls.closed_at=`έκλεισε αυτό το pull request %[2]s` pulls.reopened_at=`άνοιξε ξανά αυτό το pull request %[2]s` -pulls.merge_instruction_hint=`Μπορείτε επίσης να δείτε τις οδηγίες της γραμμής εντολών.` -pulls.merge_instruction_step1_desc=Από το αποθετήριο του έργου σας, ελέγξτε έναν νέο κλάδο και τεστάρετε τις αλλαγές. -pulls.merge_instruction_step2_desc=Συγχώνευσε τις αλλαγές και ενημέρωσε στο Gitea. pulls.clear_merge_message=Εκκαθάριση μηνύματος συγχώνευσης pulls.clear_merge_message_hint=Η εκκαθάριση του μηνύματος συγχώνευσης θα αφαιρέσει μόνο το περιεχόμενο του μηνύματος υποβολής και θα διατηρήσει τα παραγόμενα git trailers όπως "Co-Authored-By …". @@ -2688,7 +2679,6 @@ emails.updated=Το email ενημερώθηκε emails.not_updated=Αποτυχία ενημέρωσης της ζητούμενης διεύθυνσης email: %v emails.duplicate_active=Αυτή η διεύθυνση email είναι ήδη ενεργή σε διαφορετικό χρήστη. emails.change_email_header=Ενημέρωση Ιδιοτήτων Email -emails.change_email_text=Είστε βέβαιοι ότι θέλετε να ενημερώσετε αυτή τη διεύθυνση email; orgs.org_manage_panel=Διαχείριση Οργανισμού orgs.name=Όνομα @@ -3162,8 +3152,6 @@ alpine.repository.repositories=Αποθετήρια alpine.repository.architectures=Αρχιτεκτονικές cargo.registry=Ρυθμίστε αυτό το μητρώο στις ρυθμίσεις του Cargo (για παράδειγμα ~/.cargo/config.toml): cargo.install=Για να εγκαταστήσετε το πακέτο χρησιμοποιώντας το Cargo, εκτελέστε την ακόλουθη εντολή: -cargo.details.repository_site=Ιστοσελίδα Αποθετηρίου -cargo.details.documentation_site=Ιστοσελίδα Τεκμηρίωσης chef.registry=Ρυθμίστε αυτό το μητρώο στο αρχείο ~/.chef/config.rb: chef.install=Για να εγκαταστήσετε το πακέτο, εκτελέστε την ακόλουθη εντολή: composer.registry=Ρυθμίστε αυτό το μητρώο στο αρχείο ~/.composer/config.json: @@ -3175,8 +3163,6 @@ conan.registry=Ρυθμίστε αυτό το μητρώο από τη γραμ conan.install=Για να εγκαταστήσετε το πακέτο χρησιμοποιώντας το Conan, εκτελέστε την ακόλουθη εντολή: conda.registry=Ρυθμίστε αυτό το μητρώο ως αποθετήριο Conda στο αρχείο .condarc: conda.install=Για να εγκαταστήσετε το πακέτο χρησιμοποιώντας το Conda, εκτελέστε την ακόλουθη εντολή: -conda.details.repository_site=Ιστοσελίδα Αποθετηρίου -conda.details.documentation_site=Ιστοσελίδα Τεκμηρίωσης container.details.type=Τύπος Εικόνας container.details.platform=Πλατφόρμα container.pull=Κατεβάστε την εικόνα από τη γραμμή εντολών: @@ -3348,5 +3334,6 @@ type-2.display_name=Έργο Αποθετηρίου type-3.display_name=Έργο Οργανισμού [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=Symbolic link diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index 9eb9e856cef14..2aab7fc71baac 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -108,9 +108,6 @@ write=Escribir preview=Vista previa loading=Cargando… -step1=Paso 1: -step2=Paso 2: - error=Error error404=La página a la que está intentando acceder o no existe o no está autorizado para verla. go_back=Volver @@ -354,7 +351,6 @@ code_last_indexed_at=Indexado por última vez %s relevant_repositories_tooltip=Repositorios que son bifurcaciones o que no tienen ningún tema, ningún icono, y ninguna descripción están ocultos. relevant_repositories=Solo se muestran repositorios relevantes, mostrar resultados sin filtrar. - [auth] create_new_account=Registrar una cuenta register_helper_msg=¿Ya tienes una cuenta? ¡Inicia sesión! @@ -924,7 +920,6 @@ visibility.private=Privado visibility.private_tooltip=Visible sólo para los miembros de organizaciones a las que te has unido [repo] -new_repo_helper=Un repositorio contiene todos los archivos del proyecto, incluyendo el historial de revisiones. ¿Ya está alojando uno en otro lugar? Migrar repositorio. owner=Propietario owner_helper=Algunas organizaciones pueden no aparecer en el menú desplegable debido a un límite máximo de recuento de repositorios. repo_name=Nombre del repositorio @@ -1029,10 +1024,8 @@ transfer.no_permission_to_reject=No tienes permiso para rechazar esta transferen desc.private=Privado desc.public=Público -desc.private_template=Plantilla privada -desc.public_template=Plantilla +desc.template=Plantilla desc.internal=Interno -desc.internal_template=Plantilla interna desc.archived=Archivado template.items=Elementos de plantilla @@ -1797,9 +1790,6 @@ pulls.outdated_with_base_branch=Esta rama está desactualizada con la rama base pulls.close=Cerrar Pull Request pulls.closed_at=`cerró este pull request %[2]s` pulls.reopened_at=`reabrió este pull request %[2]s` -pulls.merge_instruction_hint=`También puede ver instrucciones de línea de comandos.` -pulls.merge_instruction_step1_desc=Desde el repositorio de su proyecto, revisa una nueva rama y prueba los cambios. -pulls.merge_instruction_step2_desc=Combine los cambios y actualice en Gitea. pulls.clear_merge_message=Borrar mensaje de fusión pulls.clear_merge_message_hint=Limpiar el mensaje de fusión solo eliminará el contenido del mensaje de commit y mantendrá frases generadas como "Co-Autorizado por …". @@ -2311,7 +2301,6 @@ settings.dismiss_stale_approvals_desc=Cuando los nuevos commits que cambien el c settings.require_signed_commits=Requiere commits firmados settings.require_signed_commits_desc=Rechazar push en esta rama si los commits no están firmados o no son verificables. settings.protect_branch_name_pattern=Patrón de nombre de la rama protegida -settings.protect_branch_name_pattern_desc=Patrones de nombre de rama protegidos. Consulte la documentación para la sintaxis de patrones. Ejemplos: principal, lanzamiento/** settings.protect_patterns=Patrones settings.protect_protected_file_patterns=Patrones de archivos protegidos (separados con punto y coma ';'): settings.protect_protected_file_patterns_desc=No está permitido cambiar archivos directamente incluso si el usuario tiene permiso para agregar, editar o borrar archivos en esta rama. Múltiples patrones pueden separarse usando punto y coma (';'). Refvisa la documentación de github.com/gobwas/glob para la sintaxis de patrones. Ejemplos: .drone.yml, /docs/**/*.txt. @@ -2507,7 +2496,6 @@ release.releases_for=Lanzamientos para %s release.tags_for=Etiquetas para %s branch.name=Nombre de la rama -branch.search=Buscar rama branch.already_exists=Una rama llamada "%s" ya existe. branch.delete_head=Eliminar branch.delete=`Eliminar rama "%s "` @@ -2530,6 +2518,7 @@ branch.default_deletion_failed=La rama "%s" es la rama por defecto. No se puede branch.restore=`Restaurar rama "%s"` branch.download=`Descargar rama "%s"` branch.rename=`Renombrar rama "%s"` +branch.search=Buscar rama branch.included_desc=Esta rama forma parte de la predeterminada branch.included=Incluida branch.create_new_branch=Crear rama desde la rama: @@ -2857,7 +2846,6 @@ emails.updated=Email actualizado emails.not_updated=Error al actualizar la dirección de correo electrónico solicitada: %v emails.duplicate_active=Esta dirección de correo está asignada a un usuario diferente. emails.change_email_header=Actualizar Propiedades de Correo -emails.change_email_text=¿Realmente quiere actualizar esta dirección de correo electrónico? orgs.org_manage_panel=Gestión de organizaciones orgs.name=Nombre @@ -3341,8 +3329,6 @@ alpine.repository.repositories=Repositorios alpine.repository.architectures=Arquitecturas cargo.registry=Configurar este registro en el archivo de configuración de Cargo (por ejemplo ~/.cargo/config.toml): cargo.install=Para instalar el paquete usando Cargo, ejecute el siguiente comando: -cargo.details.repository_site=Sitio del repositorio -cargo.details.documentation_site=Sitio de documentación chef.registry=Configura este registro en tu archivo ~/.chef/config.rb: chef.install=Para instalar el paquete, ejecute el siguiente comando: composer.registry=Configura este registro en el archivo ~/.composer/config.json: @@ -3354,8 +3340,6 @@ conan.registry=Configurar este registro desde la línea de comandos: conan.install=Para instalar el paquete usando Conan, ejecuta el siguiente comando: conda.registry=Configura este registro como un repositorio Conda en tu archivo .condarc: conda.install=Para instalar el paquete usando Conda, ejecute el siguiente comando: -conda.details.repository_site=Sitio del repositorio -conda.details.documentation_site=Sitio de documentación container.details.type=Tipo de imagen container.details.platform=Plataforma container.pull=Arrastra la imagen desde la línea de comandos: @@ -3564,6 +3548,7 @@ type-3.display_name=Proyecto de organización [git.filemode] changed_filemode=%[1]s → %[2]s +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … directory=Directorio normal_file=Archivo normal executable_file=Archivo ejecutable diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index b9194c48a55a8..9a3d6a98cfb60 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -83,9 +83,6 @@ write=نوشتن preview=پیش نمایش loading=بارگذاری… -step1=مرحله ۱: -step2=مرحله ۲: - error=خطا error404=صفحه موردنظر شما یا وجود ندارد یا شما دسترسی کافی برای مشاهده آن را ندارید. @@ -267,7 +264,6 @@ org_no_results=سازمانی مطابق با این مورد یافت نشد. code_no_results=کد منبعی مطابق با جستجوی شما یافت نشد. code_last_indexed_at=آخرین به روزرسانی در %s - [auth] create_new_account=نام‌نویسی حساب کاربری register_helper_msg=قبلا ثبت نام کردید؟ از اینجا وارد شوید! @@ -799,10 +795,8 @@ transfer.reject_desc=رد انتقال به %s desc.private=خصوصی desc.public=عمومی -desc.private_template=قالب خصوصی -desc.public_template=قالب +desc.template=قالب desc.internal=داخلی -desc.internal_template=قالب داخلی desc.archived=بایگانی شده template.items=موارد الگو @@ -1382,9 +1376,6 @@ pulls.update_not_allowed=شما اجازه بروزرسانی شاخه را ند pulls.outdated_with_base_branch=این شاخه با شاخه پایه منسوخ شده است pulls.closed_at=`این درخواست pull بسته شده %[2]s` pulls.reopened_at=`این درخواست pull را بازگشایی کرد %[2]s` -pulls.merge_instruction_hint=`همچنین می‌توانید دستورالعمل‌های خط فرمان را مشاهده کنید.` -pulls.merge_instruction_step1_desc=از انبار پروژه خود، یک شاخه جدید را بگیرید و تغییرات را آزمایش کنید. -pulls.merge_instruction_step2_desc=تغییرات را ادغام کنید و در Gitea به روز کنید. @@ -2211,7 +2202,6 @@ emails.updated=ایمیل به روز شد emails.not_updated=آدرس ایمیل درخواستی به‌روزرسانی نشد: %v emails.duplicate_active=این آدرس ایمیل از قبل برای کاربر دیگری فعال است. emails.change_email_header=به روز رسانی ویژگی های ایمیل -emails.change_email_text=آیا مطمئن هستید که می خواهید این آدرس ایمیل را به روز کنید؟ orgs.org_manage_panel=مدیریت سازمان orgs.name=نام @@ -2625,5 +2615,6 @@ runs.commit=کامیت [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=پیوند نمادین diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini index 640739d5e73fc..b6cf0d842ad91 100644 --- a/options/locale/locale_fi-FI.ini +++ b/options/locale/locale_fi-FI.ini @@ -96,9 +96,6 @@ write=Kirjoita preview=Esikatselu loading=Ladataan… -step1=Vaihe 1: -step2=Vaihe 2: - error=Virhe error404=Sivu, jota yrität nähdä, joko ei löydy tai et ole oikeutettu katsomaan sitä. @@ -276,7 +273,6 @@ org_no_results=Ei löytynyt vastaavia organisaatioita. code_no_results=Hakuehtoasi vastaavaa lähdekoodia ei löytynyt. code_last_indexed_at=Viimeksi indeksoitu %s - [auth] create_new_account=Rekisteröi tili register_helper_msg=On jo tili? Kirjaudu sisään nyt! @@ -684,8 +680,7 @@ delete_preexisting_label=Poista desc.private=Yksityinen desc.public=Julkinen -desc.private_template=Yksityinen malli -desc.public_template=Malli +desc.template=Malli desc.internal=Sisäinen desc.archived=Arkistoidut @@ -1750,4 +1745,5 @@ runs.commit=Commit [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index d2b90890dfa94..c09dad7e5f8b9 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -90,6 +90,7 @@ remove=Retirer remove_all=Tout Retirer remove_label_str=Supprimer l’élément « %s » edit=Éditer +view=Voir enabled=Activé disabled=Désactivé @@ -108,9 +109,6 @@ write=Écrire preview=Aperçu loading=Chargement… -step1=Étape 1: -step2=Étape 2: - error=Erreur error404=La page que vous essayez d'atteindre n'existe pas ou vous n'êtes pas autorisé à la voir. go_back=Retour @@ -354,7 +352,6 @@ code_last_indexed_at=Dernière indexation %s relevant_repositories_tooltip=Les dépôts qui sont des forks ou qui n'ont aucun sujet, aucune icône et aucune description sont cachés. relevant_repositories=Seuls les dépôts pertinents sont affichés, afficher les résultats non filtrés. - [auth] create_new_account=Créer un compte register_helper_msg=Déjà enregistré ? Connectez-vous ! @@ -866,6 +863,7 @@ revoke_oauth2_grant_description=La révocation de l'accès à cette application revoke_oauth2_grant_success=Accès révoqué avec succès. twofa_desc=L'authentification à deux facteurs améliore la sécurité de votre compte. +twofa_recovery_tip=Si vous perdez votre appareil, vous pourrez utiliser une clé de récupération à usage unique pour obtenir l’accès à votre compte. twofa_is_enrolled=Votre compte est inscrit à l'authentification à deux facteurs. twofa_not_enrolled=Votre compte n'est pas inscrit à l'authentification à deux facteurs. twofa_disable=Désactiver l'authentification à deux facteurs @@ -888,6 +886,7 @@ webauthn_register_key=Ajouter une clé de sécurité webauthn_nickname=Pseudonyme webauthn_delete_key=Retirer la clé de sécurité webauthn_delete_key_desc=Si vous retirez une clé de sécurité, vous ne pourrez plus l'utiliser pour vous connecter. Continuer ? +webauthn_key_loss_warning=Si vous perdez vos clés de sécurité, vous perdrez l’accès à votre compte. manage_account_links=Gérer les comptes liés manage_account_links_desc=Ces comptes externes sont liés à votre compte Gitea. @@ -924,7 +923,6 @@ visibility.private=Privé visibility.private_tooltip=Visible uniquement aux membres des organisations que vous avez rejointes [repo] -new_repo_helper=Un dépôt contient tous les fichiers d'un projet, ainsi que l'historique de leurs modifications. Vous avez déjà ça ailleurs ? Migrez-le ici. owner=Propriétaire owner_helper=Certaines organisations peuvent ne pas apparaître dans la liste déroulante en raison d'une limite maximale du nombre de dépôts. repo_name=Nom du dépôt @@ -1029,10 +1027,8 @@ transfer.no_permission_to_reject=Vous n’êtes pas autorisé à rejeter ce tran desc.private=Privé desc.public=Publique -desc.private_template=Modèle privé -desc.public_template=Modèle +desc.template=Modèle desc.internal=Interne -desc.internal_template=Modèle interne desc.archived=Archivé template.items=Élément du modèle @@ -1789,6 +1785,8 @@ pulls.status_checks_failure=Certaines vérifications ont échoué pulls.status_checks_error=Quelques vérifications ont signalé des erreurs pulls.status_checks_requested=Requis pulls.status_checks_details=Détails +pulls.status_checks_hide_all=Masquer toutes les vérifications +pulls.status_checks_show_all=Afficher toutes les vérifications pulls.update_branch=Actualiser la branche par fusion pulls.update_branch_rebase=Actualiser la branche par rebasage pulls.update_branch_success=La mise à jour de la branche a réussi @@ -1797,9 +1795,7 @@ pulls.outdated_with_base_branch=Cette branche est désynchronisée avec la branc pulls.close=Fermer la demande d’ajout pulls.closed_at=`a fermé cette demande d'ajout %[2]s.` pulls.reopened_at=`a rouvert cette demande d'ajout %[2]s.` -pulls.merge_instruction_hint=`Vous pouvez également voir les instructions en ligne de commande.` -pulls.merge_instruction_step1_desc=Depuis le dépôt de votre projet, sélectionnez une nouvelle branche et testez les modifications. -pulls.merge_instruction_step2_desc=Fusionner les modifications et mettre à jour sur Gitea. +pulls.cmd_instruction_hint=`Voir les instructions en ligne de commande.` pulls.clear_merge_message=Effacer le message de fusion pulls.clear_merge_message_hint=Effacer le message de fusion ne supprimera que le message de la révision, mais pas les pieds de révision générés tels que "Co-Authored-By:". @@ -1824,7 +1820,7 @@ pull.deleted_branch=(supprimé) : %s milestones.new=Nouveau jalon milestones.closed=%s fermé -milestones.update_ago=Actualisé il y a %s +milestones.update_ago=Actualisé %s milestones.no_due_date=Aucune date d'échéance milestones.open=Ouvrir milestones.close=Fermer @@ -2311,7 +2307,6 @@ settings.dismiss_stale_approvals_desc=Lorsque des nouvelles révisions changent settings.require_signed_commits=Exiger des révisions signées settings.require_signed_commits_desc=Rejeter les soumissions sur cette branche lorsqu'ils ne sont pas signés ou vérifiables. settings.protect_branch_name_pattern=Motif de nom de branche protégé -settings.protect_branch_name_pattern_desc=Motifs de nom de branche protégé. Consultez la documentation pour la syntaxe du motif. Exemples : main, release/** settings.protect_patterns=Motifs settings.protect_protected_file_patterns=Liste des fichiers et motifs protégés settings.protect_protected_file_patterns_desc=Liste de fichiers et de motifs, séparés par un point-virgule « ; », qui ne pourront pas être modifiés même si les utilisateurs disposent des droits sur la branche. Voir la syntaxe glob. Exemples : .drone.yml ; /docs/**/*.txt. @@ -2507,7 +2502,6 @@ release.releases_for=Publications pour %s release.tags_for=Étiquettes pour %s branch.name=Nom de la branche -branch.search=Rechercher une branche branch.already_exists=Une branche nommée "%s" existe déjà. branch.delete_head=Supprimer branch.delete=`Supprimer la branche "%s"` @@ -2530,6 +2524,7 @@ branch.default_deletion_failed=La branche "%s" est la branche par défaut. Elle branch.restore=`Restaurer la branche "%s"` branch.download=`Télécharger la branche "%s"` branch.rename=`Renommer la branche "%s"` +branch.search=Rechercher une branche branch.included_desc=Cette branche fait partie de la branche par défaut branch.included=Incluses branch.create_new_branch=Créer une branche à partir de la branche : @@ -2857,7 +2852,6 @@ emails.updated=Courriel mis à jour emails.not_updated=Impossible de mettre à jour l’adresse courriel demandée : %v emails.duplicate_active=Cette adresse courriel est déjà active pour un autre utilisateur. emails.change_email_header=Mettre à jour les propriétés du courriel -emails.change_email_text=Êtes-vous sûr de vouloir mettre à jour cette adresse courriel ? orgs.org_manage_panel=Gestion des organisations orgs.name=Nom @@ -3341,8 +3335,6 @@ alpine.repository.repositories=Dépôts alpine.repository.architectures=Architectures cargo.registry=Configurez ce registre dans le fichier de configuration Cargo (par exemple ~/.cargo/config.toml) : cargo.install=Pour installer le paquet en utilisant Cargo, exécutez la commande suivante : -cargo.details.repository_site=Site du dépôt -cargo.details.documentation_site=Site de documentation chef.registry=Configurer ce registre dans votre fichier ~/.chef/config.rb: chef.install=Pour installer le paquet, exécutez la commande suivante : composer.registry=Configurez ce registre dans votre fichier ~/.composer/config.json : @@ -3354,8 +3346,6 @@ conan.registry=Configurez ce registre à partir d'un terminal : conan.install=Pour installer le paquet en utilisant Conan, exécutez la commande suivante : conda.registry=Configurez ce registre en tant que dépôt Conda dans le fichier .condarc : conda.install=Pour installer le paquet en utilisant Conda, exécutez la commande suivante : -conda.details.repository_site=Site du dépôt -conda.details.documentation_site=Site de documentation container.details.type=Type d'image container.details.platform=Plateforme container.pull=Tirez l'image depuis un terminal : @@ -3564,6 +3554,7 @@ type-3.display_name=Projet d’organisation [git.filemode] changed_filemode=%[1]s → %[2]s +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … directory=Dossier normal_file=Fichier normal executable_file=Fichier exécutable diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini index c22a049817671..4e0d1e0471bdb 100644 --- a/options/locale/locale_hu-HU.ini +++ b/options/locale/locale_hu-HU.ini @@ -75,9 +75,6 @@ write=Írás preview=Előnézet loading=Betöltés… -step1=1. lépés: -step2=2. lépés: - error404=Az elérni kívánt oldal vagy nem létezik, vagy nincs jogosultsága a megtekintéséhez. @@ -233,7 +230,6 @@ org_no_results=Nincs ilyen szervezet. code_no_results=Nincs találat a keresési kifejezésedre. code_last_indexed_at=Utoljára indexelve: %s - [auth] create_new_account=Regisztráció register_helper_msg=Van már felhasználói fiókja? Jelentkezzen be! @@ -613,8 +609,7 @@ delete_preexisting_label=Törlés desc.private=Privát desc.public=Nyilvános -desc.private_template=Privát sablon -desc.public_template=Sablon +desc.template=Sablon desc.internal=Belső desc.archived=Archivált @@ -1660,5 +1655,6 @@ runs.commit=Commit [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=Szimbolikus hivatkozás diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini index a5efde6d07b82..679b31269e147 100644 --- a/options/locale/locale_id-ID.ini +++ b/options/locale/locale_id-ID.ini @@ -77,7 +77,6 @@ loading=Memuat… - concept_code_repository=Repositori @@ -153,7 +152,6 @@ user_no_results=Tidak ditemukan pengguna yang cocok. org_no_results=Tidak ada organisasi yang cocok ditemukan. code_no_results=Tidak ada kode sumber yang cocok dengan istilah yang anda cari. - [auth] create_new_account=Daftar Akun register_helper_msg=Sudah memiliki akun? Masuk sekarang! @@ -534,7 +532,7 @@ delete_preexisting_label=Hapus desc.private=Pribadi -desc.public_template=Contoh +desc.template=Contoh template.webhooks=Webhooks template.topics=Topik @@ -1346,4 +1344,5 @@ runs.commit=Memperbuat [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini index 28ce5ae7f7ac7..2ba623dc1278e 100644 --- a/options/locale/locale_is-IS.ini +++ b/options/locale/locale_is-IS.ini @@ -94,9 +94,6 @@ write=Skrifa preview=Forskoða loading=Hleður… -step1=Skref 1: -step2=Skref 2: - error=Villa error404=Síðan sem þú ert að reyna að fá annað hvort er ekki til eða þú hefur ekki heimild til að skoða hana. @@ -251,7 +248,6 @@ user_no_results=Engir samsvarandi notendur fundust. org_no_results=Engar samsvarandi stofnanir fundust. code_no_results=Enginn samsvarandi frumkóði fannst eftur þínum leitarorðum. - [auth] create_new_account=Skrá Notanda register_helper_msg=Ertu nú þegar með notanda? Skráðu þig inn núna! @@ -612,10 +608,8 @@ delete_preexisting_content=Eyða skrám í %s desc.private=Einka desc.public=Opinbert -desc.private_template=Einka sniðmát -desc.public_template=Sniðmát +desc.template=Sniðmát desc.internal=Innra -desc.internal_template=Innra sniðmát desc.archived=Safnvistað template.git_content=Git Innihald (Sjálfgefin Grein) @@ -1371,4 +1365,5 @@ runs.commit=Framlag [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index e73d063613707..13edd4af03fc0 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -97,9 +97,6 @@ write=Scrivi preview=Anteprima loading=Caricamento… -step1=Passo 1: -step2=Passo 2: - error=Errore error404=La pagina che stai cercando di raggiungere non esiste oppure non sei autorizzato a visualizzarla. @@ -289,7 +286,6 @@ org_no_results=Nessun'organizzazione corrispondente trovata. code_no_results=Nessun codice sorgente corrispondente ai termini di ricerca. code_last_indexed_at=Ultimo indicizzato %s - [auth] create_new_account=Registra un account register_helper_msg=Hai già un account? Accedi ora! @@ -858,10 +854,8 @@ transfer.reject_desc=`Annulla il trasferimento a "%s"` desc.private=Privato desc.public=Pubblico -desc.private_template=Modello privato -desc.public_template=Modello +desc.template=Template desc.internal=Interno -desc.internal_template=Template interno desc.archived=Archiviato template.items=Elementi del modello @@ -1495,9 +1489,6 @@ pulls.update_not_allowed=Non sei abilitato ad aggiornare il branch pulls.outdated_with_base_branch=Questo brench non è aggiornato con il branch di base pulls.closed_at=`chiusa questa pull request %[2]s` pulls.reopened_at=`riaperta questa pull request %[2]s` -pulls.merge_instruction_hint=`Puoi anche visualizzare le istruzioni da riga di comando.` -pulls.merge_instruction_step1_desc=Dal repository del tuo progetto, fai il check out di un nuovo branch e verifica le modifiche. -pulls.merge_instruction_step2_desc=Fai il merge delle modifiche e aggiorna su Gitea. pulls.auto_merge_button_when_succeed=(Quando i controlli sono superati) pulls.auto_merge_when_succeed=Unione automatica quando tutti i controlli sono superati @@ -2388,7 +2379,6 @@ emails.updated=Email aggiornata emails.not_updated=Impossibile aggiornare l'indirizzo email richiesto: %v emails.duplicate_active=Questo indirizzo email risulta già attivo per un altro utente. emails.change_email_header=Aggiorna proprietà email -emails.change_email_text=Sei sicuro di voler aggiornare questo indirizzo email? orgs.org_manage_panel=Gestione Organizzazione orgs.name=Nome @@ -2914,5 +2904,6 @@ runs.commit=Commit [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=Link Simbolico diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index df1cd0a540e75..bd2a2ea4794d7 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -108,9 +108,6 @@ write=書き込み preview=プレビュー loading=読み込み中… -step1=ステップ 1: -step2=ステップ 2: - error=エラー error404=アクセスしようとしたページは存在しないか、閲覧が許可されていません。 go_back=戻る @@ -354,7 +351,6 @@ code_last_indexed_at=最終取得 %s relevant_repositories_tooltip=フォークリポジトリや、トピック、アイコン、説明のいずれも無いリポジトリは表示されません。 relevant_repositories=妥当と思われるリポジトリのみを表示しています。 フィルタリングしない結果を表示。 - [auth] create_new_account=アカウントを登録 register_helper_msg=既にアカウントをお持ちですか? 今すぐサインインしましょう! @@ -924,7 +920,6 @@ visibility.private=プライベート visibility.private_tooltip=あなたが参加した組織のメンバーのみに表示されます [repo] -new_repo_helper=リポジトリには、プロジェクトのすべてのファイルとリビジョン履歴が入ります。 すでにほかの場所でホストしていますか? リポジトリを移行 もどうぞ。 owner=オーナー owner_helper=リポジトリ数の上限により、一部の組織はドロップダウンに表示されない場合があります。 repo_name=リポジトリ名 @@ -1029,10 +1024,8 @@ transfer.no_permission_to_reject=この移転を拒否する権限がありま desc.private=プライベート desc.public=公開 -desc.private_template=プライベートテンプレート -desc.public_template=テンプレート +desc.template=テンプレート desc.internal=組織内 -desc.internal_template=組織内テンプレート desc.archived=アーカイブ template.items=テンプレート項目 @@ -1797,9 +1790,6 @@ pulls.outdated_with_base_branch=このブランチはベースブランチに対 pulls.close=プルリクエストをクローズ pulls.closed_at=`がプルリクエストをクローズ %[2]s` pulls.reopened_at=`がプルリクエストを再オープン %[2]s` -pulls.merge_instruction_hint=`コマンドラインの手順も確認できます。` -pulls.merge_instruction_step1_desc=あなたのプロジェクトリポジトリで新しいブランチをチェックアウトし、変更内容をテストします。 -pulls.merge_instruction_step2_desc=変更内容をマージして、Giteaに反映します。 pulls.clear_merge_message=マージメッセージをクリア pulls.clear_merge_message_hint=マージメッセージのクリアは、コミットメッセージの除去だけを行います。 生成されたGitトレーラー("Co-Authored-By …" 等)はそのまま残ります。 @@ -2311,7 +2301,6 @@ settings.dismiss_stale_approvals_desc=プルリクエストの内容を変える settings.require_signed_commits=コミット署名必須 settings.require_signed_commits_desc=署名されていない場合、または署名が検証できなかった場合は、このブランチへのプッシュを拒否します。 settings.protect_branch_name_pattern=保護ブランチ名のパターン -settings.protect_branch_name_pattern_desc=保護ブランチ名のパターン。書き方についてはドキュメント を参照してください。例: main, release/** settings.protect_patterns=パターン settings.protect_protected_file_patterns=保護されるファイルのパターン (セミコロン';'で区切る): settings.protect_protected_file_patterns_desc=保護されたファイルは、このブランチにファイルを追加・編集・削除する権限を持つユーザーであっても、直接変更することができなくなります。 セミコロン(';')で区切って複数のパターンを指定できます。 パターンの文法については github.com/gobwas/glob を参照してください。 例: .drone.yml, /docs/**/*.txt @@ -2507,7 +2496,6 @@ release.releases_for=%s のリリース release.tags_for=%s のタグ branch.name=ブランチ名 -branch.search=ブランチを検索 branch.already_exists=ブランチ "%s" は既に存在します。 branch.delete_head=削除 branch.delete=ブランチ "%s" の削除 @@ -2530,6 +2518,7 @@ branch.default_deletion_failed=ブランチ "%s" はデフォルトブランチ branch.restore=ブランチ "%s" の復元 branch.download=ブランチ "%s" をダウンロード branch.rename=ブランチ名 "%s" を変更 +branch.search=ブランチを検索 branch.included_desc=このブランチはデフォルトブランチに含まれています branch.included=埋没 branch.create_new_branch=このブランチをもとに作成します: @@ -2857,7 +2846,6 @@ emails.updated=メール設定を更新しました emails.not_updated=メール設定の更新に失敗しました: %v emails.duplicate_active=メールアドレスは別のユーザーが既に使用中です。 emails.change_email_header=メール設定の更新 -emails.change_email_text=このメールアドレスを設定してよろしいですか? orgs.org_manage_panel=組織の管理 orgs.name=名称 @@ -3341,8 +3329,6 @@ alpine.repository.repositories=Repositories alpine.repository.architectures=Architectures cargo.registry=Cargo 設定ファイルでこのレジストリをセットアップします。(例 ~/.cargo/config.toml): cargo.install=Cargo を使用してパッケージをインストールするには、次のコマンドを実行します: -cargo.details.repository_site=リポジトリサイト -cargo.details.documentation_site=ドキュメンテーションサイト chef.registry=あなたの ~/.chef/config.rb ファイルに、このレジストリをセットアップします: chef.install=パッケージをインストールするには、次のコマンドを実行します: composer.registry=あなたの ~/.composer/config.json ファイルに、このレジストリをセットアップします: @@ -3354,8 +3340,6 @@ conan.registry=このレジストリをコマンドラインからセットア conan.install=Conan を使用してパッケージをインストールするには、次のコマンドを実行します: conda.registry=あなたの .condarc ファイルに、このレジストリを Conda リポジトリとしてセットアップします: conda.install=Conda を使用してパッケージをインストールするには、次のコマンドを実行します: -conda.details.repository_site=リポジトリサイト -conda.details.documentation_site=ドキュメンテーションサイト container.details.type=イメージタイプ container.details.platform=プラットフォーム container.pull=コマンドラインでイメージを取得します: @@ -3564,6 +3548,7 @@ type-3.display_name=組織プロジェクト [git.filemode] changed_filemode=%[1]s → %[2]s +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … directory=ディレクトリ normal_file=ノーマルファイル executable_file=実行可能ファイル diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index d33bf0f850bc3..54e8e79aef82a 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -77,7 +77,6 @@ loading=불러오는 중... - concept_code_repository=저장소 concept_user_organization=조직 @@ -218,7 +217,6 @@ user_no_results=일치하는 사용자가 없습니다. org_no_results=일치하는 조직이 없습니다. code_no_results=검색어와 일치하는 소스코드가 없습니다. - [auth] create_new_account=계정 등록 register_helper_msg=이미 계정을 가지고 계신가요? 로그인하세요! @@ -578,7 +576,7 @@ delete_preexisting_label=삭제 desc.private=비공개 -desc.public_template=템플릿 +desc.template=템플릿 template.topics=토론 주제 template.avatar=아바타 @@ -1604,4 +1602,5 @@ runs.commit=커밋 [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index d0d4a39886011..6d24435012177 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -105,9 +105,6 @@ write=Rakstīt preview=Priekšskatītījums loading=Notiek ielāde… -step1=Solis 1: -step2=Solis 2: - error=Kļūda error404=Lapa, ko vēlaties atvērt, neeksistē vai arī Jums nav tiesības to aplūkot. @@ -343,7 +340,6 @@ code_last_indexed_at=Pēdējo reizi indeksēts %s relevant_repositories_tooltip=Repozitoriju, kas ir atdalīti vai kuriem nav tēmas, ikonas un apraksta ir paslēpti. relevant_repositories=Tikai būtiskie repozitoriji tiek rādīti, pārādīt nefiltrētus rezultātus. - [auth] create_new_account=Reģistrēt kontu register_helper_msg=Jau ir konts? Piesakieties tagad! @@ -968,10 +964,8 @@ transfer.reject_desc=`Atcelt īpašnieka maiņu uz "%s"` desc.private=Privāts desc.public=Publisks -desc.private_template=Privāta sagatave -desc.public_template=Sagatave +desc.template=Sagatave desc.internal=Iekšējs -desc.internal_template=Iekšēja sagatave desc.archived=Arhivēts template.items=Sagataves ieraksti @@ -1689,9 +1683,6 @@ pulls.outdated_with_base_branch=Atzars ir novecojis salīdzinot ar bāzes atzaru pulls.close=Aizvērt izmaiņu pieprasījumu pulls.closed_at=`aizvēra šo izmaiņu pieprasījumu %[2]s` pulls.reopened_at=`atkārtoti atvēra šo izmaiņu pieprasījumu %[2]s` -pulls.merge_instruction_hint=`Varat aplūkot arī komandrindas instrukcijas.` -pulls.merge_instruction_step1_desc=Projekta repozitorijā izveidojiet jaunu jaunu atzaru un pārbaudiet savas izmaiņas. -pulls.merge_instruction_step2_desc=Sapludināt izmaiņas un atjaunot tās Gitea. pulls.clear_merge_message=Notīrīt sapludināšanas ziņojumu pulls.clear_merge_message_hint=Notīrot sapludināšanas ziņojumu tiks noņemts tikai pats ziņojums, bet tiks paturēti ģenerētie git ziņojumu, kā "Co-Authored-By …". @@ -2694,7 +2685,6 @@ emails.updated=E-pasts atjaunots emails.not_updated=Neizdevās atjaunot pieprasīto e-pasta adresi: %v emails.duplicate_active=E-pasta adrese jau ir aktīva citam lietotājam. emails.change_email_header=Atjaunot e-pasta rekvizītus -emails.change_email_text=Vai patiešām vēlaties atjaunot šo e-pasta adresi? orgs.org_manage_panel=Organizāciju pārvaldība orgs.name=Nosaukums @@ -3168,8 +3158,6 @@ alpine.repository.repositories=Repozitoriji alpine.repository.architectures=Arhitektūras cargo.registry=Uzstādiet šo reģistru Cargo konfigurācijas failā, piemēram, ~/.cargo/config.toml: cargo.install=Lai instalētu Cargo pakotni, izpildiet sekojošu komandu: -cargo.details.repository_site=Repozitorija vietne -cargo.details.documentation_site=Dokumentācijas lapa chef.registry=Uzstādiet šo reģistru failā ~/.chef/config.rb: chef.install=Lai uzstādītu pakotni, ir jāizpilda šī komanda: composer.registry=Pievienojiet šo reģistru savā ~/.composer/config.json failā: @@ -3181,8 +3169,6 @@ conan.registry=Konfigurējiet šo reģistru no komandrindas: conan.install=Lai instalētu Conan pakotni, izpildiet sekojošu komandu: conda.registry=Uzstādiet šo reģistru kā Conda repozitoriju failā .condarc: conda.install=Lai instalētu Conda pakotni, izpildiet sekojošu komandu: -conda.details.repository_site=Repozitorija vietne -conda.details.documentation_site=Dokumentācijas lapa container.details.type=Attēla formāts container.details.platform=Platforma container.pull=Atgādājiet šo attēlu no komandrindas: @@ -3354,5 +3340,6 @@ type-2.display_name=Repozitorija projekts type-3.display_name=Organizācijas projekts [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=Simboliska saite diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index 2440002241354..ba4c28dd3bff7 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -97,9 +97,6 @@ write=Schrijf preview=Voorbeeld loading=Laden… -step1=Stap 1: -step2=Stap 2: - error=Fout error404=De pagina die u probeert te bereiken bestaat niet of u bent niet gemachtigd om het te bekijken. @@ -288,7 +285,6 @@ org_no_results=Er zijn geen overeenkomende organisaties gevonden. code_no_results=Geen broncode gevonden in overeenstemming met uw zoekterm. code_last_indexed_at=Laatst geïndexeerd %s - [auth] create_new_account=Account registreren register_helper_msg=Heeft u al een account? Klik hier om in te loggen @@ -856,10 +852,8 @@ transfer.reject_desc=`Annuleer overdracht naar "%s"` desc.private=Privé desc.public=Openbaar -desc.private_template=Privé sjabloon -desc.public_template=Sjabloon +desc.template=Sjabloon desc.internal=Interne -desc.internal_template=Intern sjabloon desc.archived=Gearchiveerd template.items=Sjabloon items @@ -1492,9 +1486,6 @@ pulls.update_not_allowed=Je hebt geen toestemming om branch bij te werken pulls.outdated_with_base_branch=Deze branch is verouderd met de basis branch pulls.closed_at=`heeft deze pull request gesloten %[2]s` pulls.reopened_at=`heropende deze pull request %[2]s` -pulls.merge_instruction_hint=`Je kunt ook command line instructies bekijken.` -pulls.merge_instruction_step1_desc=Vanuit het project, check een branch uit en test de veranderingen. -pulls.merge_instruction_step2_desc=Voeg de wijzigingen samen en update ze op Gitea. pulls.auto_merge_button_when_succeed=(Bij geslaagde controles) pulls.auto_merge_when_succeed=Automatisch samenvoegen wanneer alle controles gelukt zijn @@ -2273,7 +2264,6 @@ emails.updated=E-mailadres bijgewerkt emails.not_updated=Bijwerken van het gevraagde e-mailadres is mislukt: %v emails.duplicate_active=Dit e-mailadres is al actief voor een andere gebruiker. emails.change_email_header=Update E-mail Eigenschappen -emails.change_email_text=Weet je zeker dat je dit e-mailadres wilt bijwerken? orgs.org_manage_panel=Organisaties beheren orgs.name=Naam @@ -2641,5 +2631,6 @@ runs.commit=Commit [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=Symbolic link diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index 8811b218927a6..52c6d716cf3c1 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -96,9 +96,6 @@ write=Napisz preview=Podgląd loading=Ładowanie… -step1=Krok 1: -step2=Krok 2: - error=Błąd error404=Strona, do której próbujesz dotrzeć nie istnieje lub nie jesteś autoryzowany aby go zobaczyć. @@ -285,7 +282,6 @@ org_no_results=Nie znaleziono pasujących organizacji. code_no_results=Nie znaleziono kodu źródłowego odpowiadającego Twojej frazie wyszukiwania. code_last_indexed_at=Ostatnio indeksowane %s - [auth] create_new_account=Zarejestruj konto register_helper_msg=Masz już konto? Zaloguj się teraz! @@ -802,10 +798,8 @@ transfer.reject_desc=`Anuluj transfer do "%s"` desc.private=Prywatne desc.public=Publiczne -desc.private_template=Szablon prywatny -desc.public_template=Szablon +desc.template=Szablon desc.internal=Wewnętrzny -desc.internal_template=Wewnętrzny szablon desc.archived=Zarchiwizowane template.items=Elementy szablonu @@ -1353,9 +1347,6 @@ pulls.update_not_allowed=Nie masz uprawnień do aktualizacji gałęzi pulls.outdated_with_base_branch=Ta gałąź jest przestarzała w stosunku do gałęzi bazowej pulls.closed_at=`zamknął(-ęła) ten pull request %[2]s` pulls.reopened_at=`otworzył(-a) ponownie ten Pull Request %[2]s` -pulls.merge_instruction_hint=`Możesz także zobaczyć instrukcje wiersza poleceń.` -pulls.merge_instruction_step1_desc=Z repozytorium twojego projektu, sprawdź nową gałąź i przetestuj zmiany. -pulls.merge_instruction_step2_desc=Połącz zmiany i zaktualizuj na Gitea. @@ -2148,7 +2139,6 @@ emails.updated=E-mail zaktualizowany emails.not_updated=Nie udało się zaktualizować żądanego adresu e-mail: %v emails.duplicate_active=Ten e-mail jest już aktywny dla innego użytkownika. emails.change_email_header=Aktualizuj właściwości adresu e-mail -emails.change_email_text=Czy na pewno chcesz zaktualizować ten adres? orgs.org_manage_panel=Zarządzanie organizacją orgs.name=Nazwa @@ -2529,5 +2519,6 @@ runs.commit=Commit [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=Dowiązanie symboliczne diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini index 302ff934667f4..f77374e753f19 100644 --- a/options/locale/locale_pt-BR.ini +++ b/options/locale/locale_pt-BR.ini @@ -107,9 +107,6 @@ write=Escrever preview=Pré-visualização loading=Carregando… -step1=Passo 1: -step2=Passo 2: - error=Erro error404=A página que você está tentando acessar não existe ou você não está autorizado a visualizá-la. @@ -351,7 +348,6 @@ code_last_indexed_at=Última indexação %s relevant_repositories_tooltip=Repositórios que são forks ou que não possuem tópico, nem ícone e nem descrição estão ocultos. relevant_repositories=Apenas repositórios relevantes estão sendo mostrados, mostrar resultados não filtrados. - [auth] create_new_account=Cadastrar conta register_helper_msg=Já tem uma conta? Acesse agora! @@ -920,7 +916,6 @@ visibility.private=Privada visibility.private_tooltip=Visível apenas para membros das organizações às quais você se associou [repo] -new_repo_helper=Um repositório contém todos os arquivos do projeto, inclusive o histórico de revisões. Já está hospedando um em outro lugar? Migre o repositório. owner=Proprietário owner_helper=Algumas organizações podem não aparecer no menu devido a um limite de contagem dos repositórios. repo_name=Nome do repositório @@ -1018,10 +1013,8 @@ transfer.no_permission_to_reject=Você não tem permissão para rejeitar essa tr desc.private=Privado desc.public=Público -desc.private_template=Modelo privado -desc.public_template=Modelo +desc.template=Template desc.internal=Interno -desc.internal_template=Modelo interno desc.archived=Arquivado template.items=Itens do modelo @@ -1773,9 +1766,6 @@ pulls.outdated_with_base_branch=Este branch está desatualizado com o branch bas pulls.close=Fechar pull request pulls.closed_at=`fechou este pull request %[2]s` pulls.reopened_at=`reabriu este pull request %[2]s` -pulls.merge_instruction_hint=`Você também pode ver as instruções para a linha de comandos.` -pulls.merge_instruction_step1_desc=No repositório do seu projeto, crie um novo branch e teste as alterações. -pulls.merge_instruction_step2_desc=Faça merge das alterações e atualize no Gitea. pulls.clear_merge_message=Limpar mensagem do merge pulls.clear_merge_message_hint=Limpar a mensagem de merge só irá remover o conteúdo da mensagem de commit e manter trailers git gerados, como "Co-Authored-By …". @@ -2774,7 +2764,6 @@ emails.updated=E-mail atualizado emails.not_updated=Falha ao atualizar o endereço de e-mail solicitado: %v emails.duplicate_active=Este endereço de e-mail já está ativo para um usuário diferente. emails.change_email_header=Atualizar Propriedades do E-mail -emails.change_email_text=Você tem certeza que deseja atualizar este endereço de e-mail? orgs.org_manage_panel=Gerenciamento da organização orgs.name=Nome @@ -3250,8 +3239,6 @@ alpine.repository.repositories=Repositórios alpine.repository.architectures=Arquiteturas cargo.registry=Configurar este registro no arquivo de configuração de Cargo (por exemplo ~/.cargo/config.toml): cargo.install=Para instalar o pacote usando Cargo, execute o seguinte comando: -cargo.details.repository_site=Site do Repositório -cargo.details.documentation_site=Site da Documentação chef.registry=Configure este registro em seu arquivo ~/.chef/config.rb: chef.install=Para instalar o pacote, execute o seguinte comando: composer.registry=Configure este registro em seu arquivo ~/.composer/config.json: @@ -3263,8 +3250,6 @@ conan.registry=Configure este registro pela linha de comando: conan.install=Para instalar o pacote usando o Conan, execute o seguinte comando: conda.registry=Configure este registro como um repositório Conda no arquivo .condarc: conda.install=Para instalar o pacote usando o Conda, execute o seguinte comando: -conda.details.repository_site=Site do Repositório -conda.details.documentation_site=Site da Documentação container.details.type=Tipo de Imagem container.details.platform=Plataforma container.pull=Puxe a imagem pela linha de comando: @@ -3441,5 +3426,6 @@ type-2.display_name=Projeto do repositório type-3.display_name=Projeto da organização [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=Link simbólico diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index b3c60333698ad..54f83c5735964 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -17,6 +17,7 @@ template=Modelo language=Idioma notifications=Notificações active_stopwatch=Cronómetro em andamento +tracked_time_summary=Resumo do tempo rastreado com base em filtros da lista de questões create_new=Criar… user_profile_and_more=Perfil e configurações… signed_in_as=Sessão iniciada como @@ -90,6 +91,7 @@ remove=Remover remove_all=Remover tudo remove_label_str=`Remover item "%s"` edit=Editar +view=Ver enabled=Habilitado disabled=Desabilitado @@ -108,9 +110,6 @@ write=Escrever preview=Pré-visualizar loading=Carregando… -step1=Passo 1: -step2=Passo 2: - error=Erro error404=A página que pretende aceder não existe ou não tem autorização para a ver. go_back=Voltar @@ -354,7 +353,6 @@ code_last_indexed_at=Última indexação %s relevant_repositories_tooltip=Repositórios que são derivações ou que não têm tópico, nem ícone, nem descrição, estão escondidos. relevant_repositories=Apenas estão a ser mostrados os repositórios relevantes. Mostrar resultados não filtrados. - [auth] create_new_account=Fazer inscrição register_helper_msg=Já tem uma conta? Inicie a sessão agora! @@ -363,6 +361,7 @@ disable_register_prompt=As inscrições estão desabilitadas. Entre em contacto disable_register_mail=A confirmação por email da inscrição está desabilitada. manual_activation_only=Contacte o administrador para completar a habilitação. remember_me=Memorizar este dispositivo +remember_me.compromised=O identificador da sessão já não é válido, o que pode indicar uma conta comprometida. Verifique se a sua conta apresenta operações pouco habituais. forgot_password_title=Esqueci-me da senha forgot_password=Esqueceu a sua senha? sign_up_now=Precisa de uma conta? Inscreva-se agora. @@ -866,6 +865,7 @@ revoke_oauth2_grant_description=Revogar o acesso desta aplicação de terceiros revoke_oauth2_grant_success=Acesso revogado com sucesso. twofa_desc=Autenticação em dois passos melhora a segurança da sua conta. +twofa_recovery_tip=Se perder o seu dispositivo, poderá usar uma chave de recuperação de utilização única para voltar a ter acesso à sua conta. twofa_is_enrolled=A autenticação em dois passos está neste momento habilitada na sua conta. twofa_not_enrolled=A autenticação em dois passos não está neste momento habilitada na sua conta. twofa_disable=Desabilitar autenticação em dois passos @@ -888,6 +888,8 @@ webauthn_register_key=Adicionar chave de segurança webauthn_nickname=Apelido webauthn_delete_key=Remover chave de segurança webauthn_delete_key_desc=Se remover uma chave de segurança, deixará de poder usá-la para iniciar a sessão. Quer continuar? +webauthn_key_loss_warning=Se perder as suas chaves de segurança, perderá acesso à sua conta. +webauthn_alternative_tip=Poderá querer configurar um método de autenticação adicional. manage_account_links=Gerir contas vinculadas manage_account_links_desc=Estas contas externas estão vinculadas à sua conta do Gitea. @@ -1029,10 +1031,8 @@ transfer.no_permission_to_reject=Você não tem permissão para rejeitar esta tr desc.private=Privado desc.public=Público -desc.private_template=Modelo privado -desc.public_template=Modelo +desc.template=Modelo desc.internal=Interno -desc.internal_template=Modelo interno desc.archived=Arquivado template.items=Itens do modelo @@ -1789,6 +1789,8 @@ pulls.status_checks_failure=Algumas verificações falharam pulls.status_checks_error=Algumas verificações reportaram erros pulls.status_checks_requested=Obrigatório pulls.status_checks_details=Detalhes +pulls.status_checks_hide_all=Ocultar todas as verificações +pulls.status_checks_show_all=Mostrar todas as verificações pulls.update_branch=Modificar ramo executando a integração pulls.update_branch_rebase=Modificar ramo mudando a base pulls.update_branch_success=A sincronização do ramo foi bem sucedida @@ -1797,9 +1799,11 @@ pulls.outdated_with_base_branch=Este ramo é obsoleto em relação ao ramo base pulls.close=Encerrar pedido de integração pulls.closed_at=`fechou este pedido de integração %[2]s` pulls.reopened_at=`reabriu este pedido de integração %[2]s` -pulls.merge_instruction_hint=`Também pode ver as instruções para a linha de comandos.` -pulls.merge_instruction_step1_desc=No seu repositório, crie um novo ramo e teste as modificações. -pulls.merge_instruction_step2_desc=Integre as modificações e envie para o Gitea. +pulls.cmd_instruction_hint=`Ver instruções para a linha de comandos.` +pulls.cmd_instruction_checkout_title=Conferir +pulls.cmd_instruction_checkout_desc=No seu repositório, irá criar um novo ramo para que possa testar as modificações. +pulls.cmd_instruction_merge_title=Integrar +pulls.cmd_instruction_merge_desc=Integrar as modificações e enviar para o Gitea. pulls.clear_merge_message=Apagar mensagem de integração pulls.clear_merge_message_hint=Apagar a mensagem de integração apenas remove o conteúdo da mensagem de cometimento e mantém os rodapés do git, tais como "Co-Autorado-Por …". @@ -2311,7 +2315,7 @@ settings.dismiss_stale_approvals_desc=Quando novos cometimentos que mudam o cont settings.require_signed_commits=Exigir cometimentos assinados settings.require_signed_commits_desc=Rejeitar envios para este ramo que não estejam assinados ou que não sejam validáveis. settings.protect_branch_name_pattern=Padrão do nome do ramo protegido -settings.protect_branch_name_pattern_desc=Padrões de nomes de ramos protegidos. Consulte a documentação para ver a sintaxe dos padrões. Exemplos: main, release/** +settings.protect_branch_name_pattern_desc=Padrões de nomes de ramos protegidos. Consulte a documentação para ver a sintaxe dos padrões. Exemplos: main, release/** settings.protect_patterns=Padrões settings.protect_protected_file_patterns=Padrões de ficheiros protegidos (separados com ponto e vírgula ';'): settings.protect_protected_file_patterns_desc=Ficheiros protegidos não podem ser modificados imediatamente, mesmo que o utilizador tenha direitos para adicionar, editar ou eliminar ficheiros neste ramo. Múltiplos padrões podem ser separados com ponto e vírgula (';'). Veja a documentação em github.com/gobwas/glob para ver a sintaxe. Exemplos: .drone.yml, /docs/**/*.txt. @@ -2507,7 +2511,6 @@ release.releases_for=Lançamentos para %s release.tags_for=Etiquetas para %s branch.name=Nome do ramo -branch.search=Pesquisar ramo branch.already_exists=Já existe um ramo com o nome "%s". branch.delete_head=Eliminar branch.delete=`Eliminar o ramo "%s"` @@ -2530,6 +2533,7 @@ branch.default_deletion_failed=O ramo "%s" é o ramo principal, não pode ser el branch.restore=`Restaurar o ramo "%s"` branch.download=`Descarregar o ramo "%s"` branch.rename=`Renomear ramo "%s"` +branch.search=Pesquisar ramo branch.included_desc=Este ramo faz parte do ramo principal branch.included=Incluído branch.create_new_branch=Criar ramo a partir do ramo: @@ -2882,6 +2886,7 @@ packages.package_manage_panel=Gestão de pacotes packages.total_size=Tamanho total: %s packages.unreferenced_size=Tamanho não referenciado: %s packages.cleanup=Limpar dados expirados +packages.cleanup.success=Limpou os dados expirados com sucesso packages.owner=Proprietário packages.creator=Criador packages.name=Nome @@ -3341,8 +3346,6 @@ alpine.repository.repositories=Repositórios alpine.repository.architectures=Arquitecturas cargo.registry=Configurar este registo no ficheiro de configuração do Cargo (por exemplo: ~/.cargo/config.toml): cargo.install=Para instalar o pacote usando o Cargo, execute o seguinte comando: -cargo.details.repository_site=Página web do repositório -cargo.details.documentation_site=Página web da documentação chef.registry=Configure este registo no seu ficheiro ~/.chef/config.rb: chef.install=Para instalar o pacote, execute o seguinte comando: composer.registry=Configure este registo no seu ficheiro ~/.composer/config.json: @@ -3354,8 +3357,6 @@ conan.registry=Configurar este registo usando a linha de comandos: conan.install=Para instalar o pacote usando o Conan, execute o seguinte comando: conda.registry=Configure este registo como um repositório Conda no seu ficheiro .condarc: conda.install=Para instalar o pacote usando o Conda, execute o seguinte comando: -conda.details.repository_site=Página web do repositório -conda.details.documentation_site=Página web da documentação container.details.type=Tipo de imagem container.details.platform=Plataforma container.pull=Puxar a imagem usando a linha de comandos: @@ -3531,7 +3532,11 @@ runs.status=Estado runs.actors_no_select=Todos os intervenientes runs.status_no_select=Todos os estados runs.no_results=Nenhum resultado obtido. +runs.no_workflows=Ainda não há sequências de trabalho. +runs.no_workflows.quick_start=Não sabe como começar com o Gitea Action? Veja o guia de iniciação rápida. +runs.no_workflows.documentation=Para mais informação sobre o Gitea Action, veja a documentação. runs.no_runs=A sequência de trabalho ainda não foi executada. +runs.empty_commit_message=(mensagem de cometimento vazia) workflow.disable=Desabilitar sequência de trabalho workflow.disable_success=A sequência de trabalho '%s' foi desabilitada com sucesso. @@ -3564,6 +3569,7 @@ type-3.display_name=Planeamento da organização [git.filemode] changed_filemode=%[1]s → %[2]s +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … directory=Pasta normal_file=Ficheiro normal executable_file=Ficheiro executável diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index aad2d86b8325b..417f70303eb32 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -108,9 +108,6 @@ write=Редактирование preview=Предпросмотр loading=Загрузка… -step1=Шаг 1: -step2=Шаг 2: - error=Ошибка error404=Либо страница, которую вы пытаетесь открыть, не существует, либо у вас недостаточно прав для ее просмотра. go_back=Назад @@ -354,7 +351,6 @@ code_last_indexed_at=Последний проиндексированный %s relevant_repositories_tooltip=Репозитории, являющиеся ответвлениями или не имеющие ни темы, ни значка, ни описания, скрыты. relevant_repositories=Показаны только релевантные репозитории, показать результаты без фильтрации. - [auth] create_new_account=Регистрация аккаунта register_helper_msg=Уже есть аккаунт? Авторизуйтесь! @@ -1011,10 +1007,8 @@ transfer.reject_desc=Отменить перемещение в «%s» desc.private=Приватный desc.public=Публичный -desc.private_template=Приватный шаблон -desc.public_template=Шаблон +desc.template=Шаблон desc.internal=Внутренний -desc.internal_template=Внутренний шаблон desc.archived=Архивировано template.items=Элементы шаблона @@ -1750,9 +1744,6 @@ pulls.outdated_with_base_branch=Эта ветка отстает от базов pulls.close=Закрыть запрос на слияние pulls.closed_at=`закрыл этот запрос на слияние %[2]s` pulls.reopened_at=`переоткрыл этот запрос на слияние %[2]s` -pulls.merge_instruction_hint=`Вы также можете просмотреть инструкции командной строки.` -pulls.merge_instruction_step1_desc=В репозитории вашего проекта посмотрите новую ветку и протестируйте изменения. -pulls.merge_instruction_step2_desc=Объединить изменения и обновить на Gitea. pulls.clear_merge_message=Очистить сообщение о слиянии pulls.clear_merge_message_hint=Очистка сообщения о слиянии удалит только содержимое сообщения коммита, но сохранит сгенерированные git добавки, такие как "Co-Authored-By …". @@ -2775,7 +2766,6 @@ emails.updated=Email обновлён emails.not_updated=Не удалось обновить запрошенный адрес электронной почты: %v emails.duplicate_active=Этот адрес электронной почты уже активирован для другого пользователя. emails.change_email_header=Обновить свойства электронной почты -emails.change_email_text=Вы уверены, что хотите обновить этот адрес электронной почты? orgs.org_manage_panel=Управление организациями orgs.name=Название @@ -3253,8 +3243,6 @@ alpine.repository.repositories=Репозитории alpine.repository.architectures=Архитектуры cargo.registry=Настройте этот реестр в файле конфигурации Cargo (например, ~/.cargo/config.toml): cargo.install=Чтобы установить пакет с помощью Cargo, выполните следующую команду: -cargo.details.repository_site=Сайт репозитория -cargo.details.documentation_site=Сайт документации chef.registry=Настройте этот реестр в своём файле ~/.chef/config.rb: chef.install=Чтобы установить пакет, выполните следующую команду: composer.registry=Настройте этот реестр в файле ~/.composer/config.json: @@ -3266,8 +3254,6 @@ conan.registry=Настроить реестр из командной стро conan.install=Чтобы установить пакет с помощью Conan, выполните следующую команду: conda.registry=Пропишите этот реестр в качестве репозитория Conda в своём файле .condarc: conda.install=Чтобы установить пакет с помощью Conda, выполните следующую команду: -conda.details.repository_site=Сайт репозитория -conda.details.documentation_site=Сайт документации container.details.type=Тип образа container.details.platform=Платформа container.pull=Загрузите образ из командной строки: @@ -3469,6 +3455,7 @@ type-3.display_name=Проект организации [git.filemode] changed_filemode=%[1]s → %[2]s +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … directory=Каталог normal_file=Обычный файл executable_file=Исполняемый файл diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 6fdcb3422856b..5824c49974e37 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -83,9 +83,6 @@ write=ලියන්න preview=පෙරදසුන loading=පූරණය වෙමින්... -step1=පියවර 1: -step2=පියවර 2: - error=දෝෂයකි error404=ඔබ ළඟා වීමට උත්සාහ කරන පිටුව නොපවතී හෝ ඔබට අවසර නැත එය බැලීමට. @@ -255,7 +252,6 @@ org_no_results=ගැලපෙන සංවිධාන හමු නොවී code_no_results=ඔබගේ සෙවුම් පදය ගැලපෙන ප්රභව කේතයක් නොමැත. code_last_indexed_at=අවසන් සුචිගත %s - [auth] create_new_account=ගිණුමක් ලියාපදිංචි කරන්න register_helper_msg=දැනටමත් ගිණුමක් තිබේද? දැන්ම පුරනය වන්න! @@ -784,7 +780,7 @@ transfer.accept_desc=`"%s" වෙත මාරු කරන්න` desc.private=පෞද්ගලික desc.public=ප්‍රසිද්ධ -desc.public_template=සැකිලි +desc.template=සැකිලි desc.internal=අභ්‍යන්තර desc.archived=සංරක්ෂිත @@ -1342,9 +1338,6 @@ pulls.update_not_allowed=ශාඛාව යාවත්කාලීන කි pulls.outdated_with_base_branch=මෙම ශාඛාව මූලික ශාඛාව සමඟ දිවයයි pulls.closed_at=`මෙම අදින්න ඉල්ලීම වසා %[2]s` pulls.reopened_at=`මෙම අදින්න ඉල්ලීම නැවත විවෘත කරන ලදි %[2]s` -pulls.merge_instruction_hint=`ඔබට විධාන රේඛා උපදෙස්ද නැරඹිය හැකිය. ` -pulls.merge_instruction_step1_desc=ඔබගේ ව්යාපෘති ගබඩාවෙන්, නව ශාඛාවක් පරීක්ෂා කර වෙනස්කම් පරීක්ෂා කරන්න. -pulls.merge_instruction_step2_desc=Gitea හි වෙනස්කම් සහ යාවත්කාලීන කිරීම ඒකාබද්ධ කරන්න. @@ -2167,7 +2160,6 @@ emails.updated=වි-තැපෑල යාවත්කාල කෙරිණ emails.not_updated=ඉල්ලූ විද්යුත් තැපැල් ලිපිනය යාවත්කාලීන කිරීමට අපොහොසත් විය: %v emails.duplicate_active=මෙම විද්යුත් තැපැල් ලිපිනය වෙනත් පරිශීලකයෙකු සඳහා දැනටමත් ක්රියාකාරී වේ. emails.change_email_header=විද්යුත් ගුණාංග යාවත්කාලීන කරන්න -emails.change_email_text=මෙම ඊ-තැපැල් ලිපිනය යාවත්කාලීන කිරීමට ඔබට අවශ්යද? orgs.org_manage_panel=සංවිධාන කළමනාකරණය orgs.name=නම @@ -2559,5 +2551,6 @@ runs.commit=කැප [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=සංකේතාත්මක සබැඳිය diff --git a/options/locale/locale_sk-SK.ini b/options/locale/locale_sk-SK.ini index d137a6d2beda6..aa02c701dd2ec 100644 --- a/options/locale/locale_sk-SK.ini +++ b/options/locale/locale_sk-SK.ini @@ -100,9 +100,6 @@ write=Zapísať preview=Náhľad loading=Načítava sa… -step1=Krok 1: -step2=Krok 2: - error=Chyba error404=Stránka, na ktorú sa pokúšate dostať, buď neexistuje, alebo nemáte oprávnenie na jej zobrazenie. @@ -290,7 +287,6 @@ code_last_indexed_at=Naposledy indexované %s relevant_repositories_tooltip=Repozitáre, ktoré sú forkami alebo ktoré nemajú tému, žiadnu ikonu ani popis, sú skryté. relevant_repositories=Zobrazujú sa iba relevantné repozitáre, zobraziť nefiltrované výsledky. - [auth] create_new_account=Zaregistrovať účet register_helper_msg=Máte už účet? Prihláste sa teraz! @@ -839,10 +835,8 @@ transfer.reject_desc=`Zrušiť prevod do "%s"` desc.private=Súkromný desc.public=Verejný -desc.private_template=Súkromná šablóna -desc.public_template=Šablóna +desc.template=Šablóna desc.internal=Interný -desc.internal_template=Interná šablóna desc.archived=Archivovaný template.items=Položky šablóny @@ -1297,5 +1291,6 @@ runs.commit=Commit [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=Symbolický odkaz diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index ce3f7d5d9bec4..e24f2f9df6464 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -76,7 +76,6 @@ write=Skriv preview=Förhandsgranska loading=Laddar… - error404=Sidan du försöker nå finns inte eller så har du inte behörighet att se den. @@ -240,7 +239,6 @@ org_no_results=Inga matchande organisationer hittades. code_no_results=Ingen källkod hittades som matchar din sökterm. code_last_indexed_at=Indexerades senast %s - [auth] create_new_account=Registrera Konto register_helper_msg=Har du redan ett konto? Logga in nu! @@ -661,10 +659,8 @@ delete_preexisting_content=Ta bort filer i %s desc.private=Privat desc.public=Publik -desc.private_template=Privat mall -desc.public_template=Mall +desc.template=Mall desc.internal=Intern -desc.internal_template=Intern mall desc.archived=Arkiverade template.items=Mallobjekt @@ -2068,5 +2064,6 @@ runs.commit=Commit [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=Symbolisk länk diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index 4c0fc95c0a26b..ed4c3182033c3 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -107,9 +107,6 @@ write=Yaz preview=Önizleme loading=Yükleniyor… -step1=1. Adım: -step2=2. Adım: - error=Hata error404=Ulaşmaya çalıştığınız sayfa mevcut değil veya görüntüleme yetkiniz yok. @@ -351,7 +348,6 @@ code_last_indexed_at=Son dizinlenen %s relevant_repositories_tooltip=Çatal olan veya konusu, simgesi veya açıklaması olmayan depolar gizlenmiştir. relevant_repositories=Sadece ilişkili depolar gösteriliyor, süzülmemiş sonuçları göster. - [auth] create_new_account=Hesap Oluştur register_helper_msg=Bir hesabınız var mı? Şimdi giriş yapın! @@ -919,7 +915,6 @@ visibility.private=Özel visibility.private_tooltip=Sadece katıldığınız organizasyonların üyeleri tarafından görünür [repo] -new_repo_helper=Bir depo, sürüm geçmişi dahil tüm proje dosyalarını içerir. Zaten başka bir yerde mi barındırıyorsunuz? Depoyu taşıyın. owner=Sahibi owner_helper=Bazı organizasyonlar, en çok depo sayısı sınırı nedeniyle açılır menüde görünmeyebilir. repo_name=Depo İsmi @@ -1016,10 +1011,8 @@ transfer.no_permission_to_reject=Bu aktarımı reddetme izniniz yok. desc.private=Özel desc.public=Genel -desc.private_template=Özel şablon -desc.public_template=Şablon +desc.template=Şablon desc.internal=Dahili -desc.internal_template=Dahili şablon desc.archived=Arşivlenmiş template.items=Şablon Öğeleri @@ -1771,9 +1764,6 @@ pulls.outdated_with_base_branch=Bu dal, temel dal ile güncel değil pulls.close=Değişiklik İsteğini Kapat pulls.closed_at=`%[2]s değişiklik isteğini kapattı` pulls.reopened_at=`%[2]s değişiklik isteğini yeniden açtı` -pulls.merge_instruction_hint=`komut satırı talimatlarını da görüntüleyebilirsiniz.` -pulls.merge_instruction_step1_desc=Proje deponuzdan yeni bir dala göz atın ve değişiklikleri test edin. -pulls.merge_instruction_step2_desc=Gitea'daki değişiklikleri ve güncellemeleri birleştirin. pulls.clear_merge_message=Birleştirme iletilerini temizle pulls.clear_merge_message_hint=Birleştirme iletisini temizlemek sadece işleme ileti içeriğini kaldırır ama üretilmiş "Co-Authored-By …" gibi git fragmanlarını korur. @@ -2342,7 +2332,7 @@ settings.lfs_findcommits=İşleme bul settings.lfs_lfs_file_no_commits=Bu LFS dosyası için hiçbir işleme bulunamadı settings.lfs_noattribute=Bu yol, varsayılan dalda kilitlenebilir özelliğe sahip değil settings.lfs_delete=OID %s ile LFS dosyasını sil -settings.lfs_delete_warning=Bir LFS dosyasını silmek, ödeme sırasında 'nesne yok' hatalarına neden olabilir. Emin misiniz? +settings.lfs_delete_warning=Bir LFS dosyasını silmek, çekme sırasında 'nesne yok' hatalarına neden olabilir. Emin misiniz? settings.lfs_findpointerfiles=İşaretçi dosyalarını bul settings.lfs_locks=Kilitler settings.lfs_invalid_locking_path=Geçersiz yol: %s @@ -2815,7 +2805,6 @@ emails.updated=E-posta güncellendi emails.not_updated=İstenen e-posta adresi güncellenemedi: %v emails.duplicate_active=Bu e-posta adresi farklı bir kullanıcı için zaten aktif. emails.change_email_header=E-posta Özelliklerini Güncelle -emails.change_email_text=Bu e-posta adresini güncellemek istediğinizden emin misiniz? orgs.org_manage_panel=Organizasyon Yönetimi orgs.name=İsim @@ -3294,8 +3283,6 @@ alpine.repository.repositories=Depolar alpine.repository.architectures=Mimariler cargo.registry=Bu kütüğü Cargo yapılandırma dosyasına (örneğin ~/.cargo/config.toml) ayarlayın: cargo.install=Paketi Cargo kullanarak kurmak için, şu komutu çalıştırın: -cargo.details.repository_site=Depo Sitesi -cargo.details.documentation_site=Belge Sitesi chef.registry=Bu kütüğü ~/.chef/config.rb dosyasında ayarlayın: chef.install=Paketi kurmak için, aşağıdaki komutu çalıştırın: composer.registry=Bu kütüğü ~/.composer/config.json dosyasında ayarlayın: @@ -3307,8 +3294,6 @@ conan.registry=Bu kütüğü komut satırını kullanarak kurun: conan.install=Conan ile paket kurmak için aşağıdaki komutu çalıştırın: conda.registry=Bu kütüğü .condarc dosyasında bir Conda deposu olarak ayarlayın: conda.install=Conda ile paket kurmak için aşağıdaki komutu çalıştırın: -conda.details.repository_site=Depo Sitesi -conda.details.documentation_site=Belge Sitesi container.details.type=Görüntü Türü container.details.platform=Platform container.pull=Görüntüyü komut satırını kullanarak çekin: @@ -3514,6 +3499,7 @@ type-3.display_name=Organizasyon Projesi [git.filemode] changed_filemode=%[1]s → %[2]s +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … directory=Dizin normal_file=Normal dosya executable_file=Çalıştırılabilir dosya diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 85adc61d33911..0d787c772fb75 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -84,9 +84,6 @@ write=Писати preview=Попередній перегляд loading=Завантаження… -step1=Крок 1: -step2=Крок 2: - error=Помилка error404=Сторінка, до якої ви намагаєтеся звернутися або до , не існує або Ви не маєте права на її перегляд. @@ -270,7 +267,6 @@ org_no_results=Відповідних організацій не знайден code_no_results=Відповідний пошуковому запитанню код не знайдено. code_last_indexed_at=Останні індексовані %s - [auth] create_new_account=Реєстрація облікового запису register_helper_msg=Вже зареєстровані? Увійдіть зараз! @@ -807,10 +803,8 @@ transfer.reject_desc=`Скасувати переміщення до "%s"` desc.private=Приватний desc.public=Публічний -desc.private_template=Приватний шаблон -desc.public_template=Шаблон +desc.template=Шаблон desc.internal=Внутрішній -desc.internal_template=Внутрішній шаблон desc.archived=Архівний template.items=Елементи шаблону @@ -1392,9 +1386,6 @@ pulls.update_not_allowed=Ви не можете оновити гілку pulls.outdated_with_base_branch=Ця гілка застаріла відносно базової гілки pulls.closed_at=`закрив цей запит на злиття %[2]s` pulls.reopened_at=`повторно відкрив цей запит на злиття %[2]s` -pulls.merge_instruction_hint=`Також можна переглянути інструкції для командного рядка.` -pulls.merge_instruction_step1_desc=У репозиторії вашого проєкту перевірте нову гілку і протестуйте зміни. -pulls.merge_instruction_step2_desc=Об'єднати зміни і оновити на Gitea. @@ -2221,7 +2212,6 @@ emails.updated=Електронну пошту оновлено emails.not_updated=Не вдалось оновити адресу електронної пошти: %v emails.duplicate_active=Ця електронна адреса вже активна для іншого користувача. emails.change_email_header=Редагувати властивості електронної пошти -emails.change_email_text=Ви впевнені, що хочете оновити цю адресу електронної пошти? orgs.org_manage_panel=Керування організаціями orgs.name=Назва @@ -2634,5 +2624,6 @@ runs.commit=Коміт [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=Символічне посилання diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 8ebf6c509c3f9..b56e797e7380a 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -108,9 +108,6 @@ write=撰写 preview=预览 loading=正在加载... -step1=第一步: -step2=第二步: - error=错误 error404=您正尝试访问的页面 不存在您尚未被授权 查看该页面。 go_back=返回 @@ -354,7 +351,6 @@ code_last_indexed_at=最后索引于 %s relevant_repositories_tooltip=派生的仓库,以及缺少主题、图标和描述的仓库将被隐藏。 relevant_repositories=只显示相关的仓库, 显示未过滤结果。 - [auth] create_new_account=注册帐号 register_helper_msg=已经注册?立即登录! @@ -924,7 +920,6 @@ visibility.private=私有 visibility.private_tooltip=仅对您已加入的组织的成员可见。 [repo] -new_repo_helper=代码仓库包含了所有的项目文件,包括版本历史记录。已经在其他地方托管了一个?迁移仓库。 owner=拥有者 owner_helper=由于最大仓库数量限制,一些组织可能不会显示在下拉列表中。 repo_name=仓库名称 @@ -1029,10 +1024,8 @@ transfer.no_permission_to_reject=您没有权限拒绝此转让。 desc.private=私有库 desc.public=公开 -desc.private_template=私有模板 -desc.public_template=模板 +desc.template=模板 desc.internal=内部 -desc.internal_template=内部模板 desc.archived=已存档 template.items=模板选项 @@ -1797,9 +1790,6 @@ pulls.outdated_with_base_branch=此分支相比基础分支已过期 pulls.close=关闭合并请求 pulls.closed_at=`于 %[2]s 关闭此合并请求 ` pulls.reopened_at=`重新打开此合并请求 %[2]s` -pulls.merge_instruction_hint=`你也可以查看 命令行指令` -pulls.merge_instruction_step1_desc=从你的仓库中签出一个新的分支并测试变更。 -pulls.merge_instruction_step2_desc=合并变更并更新到 Gitea 上 pulls.clear_merge_message=清除合并信息 pulls.clear_merge_message_hint=清除合并消息只会删除提交消息内容,并保留生成的 git 附加内容,如“Co-Authored-By …”。 @@ -2311,7 +2301,6 @@ settings.dismiss_stale_approvals_desc=当新的提交更改合并请求内容被 settings.require_signed_commits=需要签名提交 settings.require_signed_commits_desc=拒绝推送未签名或无法验证的提交到分支 settings.protect_branch_name_pattern=受保护的分支名称模式 -settings.protect_branch_name_pattern_desc=分支保护的名称匹配规则。语法请参阅 文档 。如:main, release/** settings.protect_patterns=规则 settings.protect_protected_file_patterns=受保护的文件模式(使用分号 ';' 分隔): settings.protect_protected_file_patterns_desc=即使用户有权添加、编辑或删除此分支中的文件,也不允许直接更改受保护的文件。 可以使用分号 (';') 分隔多个模式。 见github.com/gobwas/glob文档了解模式语法。例如: .drone.yml, /docs/**/*.txt @@ -2507,7 +2496,6 @@ release.releases_for=%s 的版本发布 release.tags_for=%s 的标签 branch.name=分支名称 -branch.search=搜索分支 branch.already_exists=名为 %s 的分支已存在。 branch.delete_head=刪除 branch.delete=删除分支 %s @@ -2530,6 +2518,7 @@ branch.default_deletion_failed=不能删除默认分支"%s"。 branch.restore=`还原分支 "%s"` branch.download=`下载分支 "%s"` branch.rename=`重命名分支 "%s"` +branch.search=搜索分支 branch.included_desc=此分支是默认分支的一部分 branch.included=已包含 branch.create_new_branch=从下列分支创建分支: @@ -2857,7 +2846,6 @@ emails.updated=电子邮件已更新 emails.not_updated=无法更新请求的电子邮件地址: %v emails.duplicate_active=此电子邮件地址已被另一个用户激活使用。 emails.change_email_header=更新电子邮件属性 -emails.change_email_text=您确认要更新这个电子邮件地址吗? orgs.org_manage_panel=组织管理 orgs.name=名称 @@ -3341,8 +3329,6 @@ alpine.repository.repositories=仓库管理 alpine.repository.architectures=架构 cargo.registry=在 Cargo 配置文件中设置此注册中心(例如:~/.cargo/config.toml): cargo.install=要使用 Cargo 安装软件包,请运行以下命令: -cargo.details.repository_site=仓库站点 -cargo.details.documentation_site=文档站点 chef.registry=在您的 ~/.chef/config.rb 文件中设置此注册中心: chef.install=要安装包,请运行以下命令: composer.registry=在您的 ~/.composer/config.json 文件中设置此注册中心: @@ -3354,8 +3340,6 @@ conan.registry=从命令行设置此注册中心: conan.install=要使用 Conan 安装软件包,请运行以下命令: conda.registry=在您的 .condarc 文件中将此注册中心设置为 Conda 仓库: conda.install=要使用 Conda 安装软件包,请运行以下命令: -conda.details.repository_site=仓库站点 -conda.details.documentation_site=文档站点 container.details.type=镜像类型 container.details.platform=平台 container.pull=从命令行拉取镜像: @@ -3564,6 +3548,7 @@ type-3.display_name=组织项目 [git.filemode] changed_filemode=%[1]s -> %[2]s +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … directory=目录 normal_file=普通文件 executable_file=可执行文件 diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini index dfa048c5ef0b9..9b065d7ae512c 100644 --- a/options/locale/locale_zh-HK.ini +++ b/options/locale/locale_zh-HK.ini @@ -55,7 +55,6 @@ enabled=已啟用 - concept_code_repository=儲存庫 @@ -119,7 +118,6 @@ users=使用者 organizations=組織 search=搜尋 - [auth] register_helper_msg=已經註冊?立即登錄! forgot_password_title=忘記密碼 @@ -319,7 +317,7 @@ forks=複製儲存庫 desc.private=私有庫 -desc.public_template=樣板 +desc.template=樣板 template.avatar=頭像 @@ -990,4 +988,5 @@ runners.task_list.repository=儲存庫 [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index e058ca71919fe..99d888c4501b4 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -103,9 +103,6 @@ write=撰寫 preview=預覽 loading=載入中… -step1=第一步: -step2=第二步: - error=錯誤 error404=您正嘗試訪問的頁面 不存在您尚未被授權 查看該頁面。 @@ -333,7 +330,6 @@ code_last_indexed_at=最後索引 %s relevant_repositories_tooltip=已隱藏缺少主題、圖示、說明、Fork 的儲存庫。 relevant_repositories=只顯示相關的儲存庫,顯示未篩選的結果。 - [auth] create_new_account=註冊帳戶 register_helper_msg=已經有帳戶了?立即登入! @@ -939,10 +935,8 @@ transfer.reject_desc=取消轉移到「%s」 desc.private=私有 desc.public=公開 -desc.private_template=私有範本 -desc.public_template=範本 +desc.template=模板 desc.internal=組織內部用 -desc.internal_template=組織內部範本 desc.archived=已封存 template.items=範本項目 @@ -1639,9 +1633,6 @@ pulls.outdated_with_base_branch=相對於基底分支,此分支已過時 pulls.close=關閉合併請求 pulls.closed_at=`關閉了這個合併請求 %[2]s` pulls.reopened_at=`重新開放了這個合併請求 %[2]s` -pulls.merge_instruction_hint=`您也可以查看命令列指南。` -pulls.merge_instruction_step1_desc=在您的儲存庫中切換到新分支並測試變更。 -pulls.merge_instruction_step2_desc=合併變更並更新到 Gitea。 pulls.clear_merge_message=清除合併訊息 pulls.clear_merge_message_hint=清除合併訊息將僅移除提交訊息內容,留下產生的 git 結尾,如「Co-Authored-By …」。 @@ -2607,7 +2598,6 @@ emails.updated=信箱已更新 emails.not_updated=電子信箱更新失敗: %v emails.duplicate_active=此信箱已被其他使用者使用 emails.change_email_header=更新電子信箱屬性 -emails.change_email_text=您確定要更新這個電子信箱? orgs.org_manage_panel=組織管理 orgs.name=名稱 @@ -3072,8 +3062,6 @@ alpine.repository.repositories=儲存庫 alpine.repository.architectures=架構 cargo.registry=在 Cargo 組態檔設定此註冊中心 (例如: ~/.cargo/config.toml): cargo.install=執行下列命令以使用 Cargo 安裝此套件: -cargo.details.repository_site=儲存庫網站 -cargo.details.documentation_site=文件網站 chef.registry=在您的 ~/.chef/config.rb 檔設定此註冊中心: chef.install=執行下列命令安裝此套件: composer.registry=在您的 ~/.composer/config.json 檔設定此註冊中心: @@ -3085,8 +3073,6 @@ conan.registry=透過下列命令設定此註冊中心: conan.install=執行下列命令以使用 Conan 安裝此套件: conda.registry=在您的 .condarc 檔設定此註冊中心為 Conda 存儲庫: conda.install=執行下列命令以使用 Conda 安裝此套件: -conda.details.repository_site=儲存庫網站 -conda.details.documentation_site=文件網站 container.details.type=映像檔類型 container.details.platform=平台 container.pull=透過下列命令拉取映像檔: @@ -3254,5 +3240,6 @@ need_approval_desc=來自 Frok 儲存庫的合併請求需要核可才能執行 [projects] [git.filemode] +; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", … symbolic_link=符號連結 From 4e879fed90665331d2a57e5abee9e0f02372c470 Mon Sep 17 00:00:00 2001 From: Jack Hay Date: Mon, 11 Dec 2023 22:48:53 -0500 Subject: [PATCH 15/60] Deprecate query string auth tokens (#28390) ## Changes - Add deprecation warning to `Token` and `AccessToken` authentication methods in swagger. - Add deprecation warning header to API response. Example: ``` HTTP/1.1 200 OK ... Warning: token and access_token API authentication is deprecated ... ``` - Add setting `DISABLE_QUERY_AUTH_TOKEN` to reject query string auth tokens entirely. Default is `false` ## Next steps - `DISABLE_QUERY_AUTH_TOKEN` should be true in a subsequent release and the methods should be removed in swagger - `DISABLE_QUERY_AUTH_TOKEN` should be removed and the implementation of the auth methods in question should be removed ## Open questions - Should there be further changes to the swagger documentation? Deprecation is not yet supported for security definitions (coming in [OpenAPI Spec version 3.2.0](https://github.com/OAI/OpenAPI-Specification/issues/2506)) - Should the API router logger sanitize urls that use `token` or `access_token`? (This is obviously an insufficient solution on its own) --------- Co-authored-by: delvh --- custom/conf/app.example.ini | 5 +++++ modules/setting/security.go | 8 ++++++++ routers/api/v1/api.go | 11 +++++++++++ services/auth/oauth2.go | 20 +++++++++++++------- templates/swagger/v1_json.tmpl | 2 ++ 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 18d6fe37a8ba2..e10c4f7582e91 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -492,6 +492,11 @@ INTERNAL_TOKEN= ;; Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations. ;; This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security. ;SUCCESSFUL_TOKENS_CACHE_SIZE = 20 +;; +;; Reject API tokens sent in URL query string (Accept Header-based API tokens only). This avoids security vulnerabilities +;; stemming from cached/logged plain-text API tokens. +;; In future releases, this will become the default behavior +;DISABLE_QUERY_AUTH_TOKEN = false ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/modules/setting/security.go b/modules/setting/security.go index 92caa05fad174..4adfe20635e77 100644 --- a/modules/setting/security.go +++ b/modules/setting/security.go @@ -34,6 +34,7 @@ var ( PasswordHashAlgo string PasswordCheckPwn bool SuccessfulTokensCacheSize int + DisableQueryAuthToken bool CSRFCookieName = "_csrf" CSRFCookieHTTPOnly = true ) @@ -157,4 +158,11 @@ func loadSecurityFrom(rootCfg ConfigProvider) { PasswordComplexity = append(PasswordComplexity, name) } } + + // TODO: default value should be true in future releases + DisableQueryAuthToken = sec.Key("DISABLE_QUERY_AUTH_TOKEN").MustBool(false) + + if !DisableQueryAuthToken { + log.Warn("Enabling Query API Auth tokens is not recommended. DISABLE_QUERY_AUTH_TOKEN will default to true in gitea 1.23 and will be removed in gitea 1.24.") + } } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 623c798feea68..13c6762b54d74 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -35,10 +35,12 @@ // type: apiKey // name: token // in: query +// description: This authentication option is deprecated for removal in Gitea 1.23. Please use AuthorizationHeaderToken instead. // AccessToken: // type: apiKey // name: access_token // in: query +// description: This authentication option is deprecated for removal in Gitea 1.23. Please use AuthorizationHeaderToken instead. // AuthorizationHeaderToken: // type: apiKey // name: Authorization @@ -788,6 +790,13 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.APIC } } +// check for and warn against deprecated authentication options +func checkDeprecatedAuthMethods(ctx *context.APIContext) { + if ctx.FormString("token") != "" || ctx.FormString("access_token") != "" { + ctx.Resp.Header().Set("Warning", "token and access_token API authentication is deprecated and will be removed in gitea 1.23. Please use AuthorizationHeaderToken instead. Existing queries will continue to work but without authorization.") + } +} + // Routes registers all v1 APIs routes to web application. func Routes() *web.Route { m := web.NewRoute() @@ -806,6 +815,8 @@ func Routes() *web.Route { } m.Use(context.APIContexter()) + m.Use(checkDeprecatedAuthMethods) + // Get user from session if logged in. m.Use(apiAuth(buildAuthGroup())) diff --git a/services/auth/oauth2.go b/services/auth/oauth2.go index 08a2a05539b5a..f2f7858a850c1 100644 --- a/services/auth/oauth2.go +++ b/services/auth/oauth2.go @@ -14,6 +14,7 @@ import ( auth_model "code.gitea.io/gitea/models/auth" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/services/auth/source/oauth2" @@ -62,14 +63,19 @@ func (o *OAuth2) Name() string { // representing whether the token exists or not func parseToken(req *http.Request) (string, bool) { _ = req.ParseForm() - // Check token. - if token := req.Form.Get("token"); token != "" { - return token, true - } - // Check access token. - if token := req.Form.Get("access_token"); token != "" { - return token, true + if !setting.DisableQueryAuthToken { + // Check token. + if token := req.Form.Get("token"); token != "" { + return token, true + } + // Check access token. + if token := req.Form.Get("access_token"); token != "" { + return token, true + } + } else if req.Form.Get("token") != "" || req.Form.Get("access_token") != "" { + log.Warn("API token sent in query string but DISABLE_QUERY_AUTH_TOKEN=true") } + // check header token if auHead := req.Header.Get("Authorization"); auHead != "" { auths := strings.Fields(auHead) diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 2541726a64b81..6cf2beafec6e8 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -24046,6 +24046,7 @@ }, "securityDefinitions": { "AccessToken": { + "description": "This authentication option is deprecated for removal in Gitea 1.23. Please use AuthorizationHeaderToken instead.", "type": "apiKey", "name": "access_token", "in": "query" @@ -24078,6 +24079,7 @@ "in": "header" }, "Token": { + "description": "This authentication option is deprecated for removal in Gitea 1.23. Please use AuthorizationHeaderToken instead.", "type": "apiKey", "name": "token", "in": "query" From 717d0f5934826e0ddfdce176cf3cab303cd74fbb Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 12 Dec 2023 13:01:17 +0800 Subject: [PATCH 16/60] Do some missing checks (#28423) --- routers/api/v1/api.go | 20 +++++++++++++++++++- routers/web/web.go | 22 ++++++++++++++++++++-- tests/integration/project_test.go | 23 +++++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 tests/integration/project_test.go diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 13c6762b54d74..0e437bb92ec0e 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -790,6 +790,24 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.APIC } } +func individualPermsChecker(ctx *context.APIContext) { + // org permissions have been checked in context.OrgAssignment(), but individual permissions haven't been checked. + if ctx.ContextUser.IsIndividual() { + switch { + case ctx.ContextUser.Visibility == api.VisibleTypePrivate: + if ctx.Doer == nil || (ctx.ContextUser.ID != ctx.Doer.ID && !ctx.Doer.IsAdmin) { + ctx.NotFound("Visit Project", nil) + return + } + case ctx.ContextUser.Visibility == api.VisibleTypeLimited: + if ctx.Doer == nil { + ctx.NotFound("Visit Project", nil) + return + } + } + } +} + // check for and warn against deprecated authentication options func checkDeprecatedAuthMethods(ctx *context.APIContext) { if ctx.FormString("token") != "" || ctx.FormString("access_token") != "" { @@ -899,7 +917,7 @@ func Routes() *web.Route { }, reqSelfOrAdmin(), reqBasicOrRevProxyAuth()) m.Get("/activities/feeds", user.ListUserActivityFeeds) - }, context_service.UserAssignmentAPI()) + }, context_service.UserAssignmentAPI(), individualPermsChecker) }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser)) // Users (requires user scope) diff --git a/routers/web/web.go b/routers/web/web.go index da7360f1b8690..db0588056b531 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -796,6 +796,24 @@ func registerRoutes(m *web.Route) { } } + individualPermsChecker := func(ctx *context.Context) { + // org permissions have been checked in context.OrgAssignment(), but individual permissions haven't been checked. + if ctx.ContextUser.IsIndividual() { + switch { + case ctx.ContextUser.Visibility == structs.VisibleTypePrivate: + if ctx.Doer == nil || (ctx.ContextUser.ID != ctx.Doer.ID && !ctx.Doer.IsAdmin) { + ctx.NotFound("Visit Project", nil) + return + } + case ctx.ContextUser.Visibility == structs.VisibleTypeLimited: + if ctx.Doer == nil { + ctx.NotFound("Visit Project", nil) + return + } + } + } + } + // ***** START: Organization ***** m.Group("/org", func() { m.Group("/{org}", func() { @@ -976,11 +994,11 @@ func registerRoutes(m *web.Route) { return } }) - }) + }, reqUnitAccess(unit.TypeProjects, perm.AccessModeRead, true), individualPermsChecker) m.Group("", func() { m.Get("/code", user.CodeSearch) - }, reqUnitAccess(unit.TypeCode, perm.AccessModeRead, false)) + }, reqUnitAccess(unit.TypeCode, perm.AccessModeRead, false), individualPermsChecker) }, ignSignIn, context_service.UserAssignmentWeb(), context.OrgAssignment()) // for "/{username}/-" (packages, projects, code) m.Group("/{username}/{reponame}", func() { diff --git a/tests/integration/project_test.go b/tests/integration/project_test.go new file mode 100644 index 0000000000000..45061c5b24f1f --- /dev/null +++ b/tests/integration/project_test.go @@ -0,0 +1,23 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package integration + +import ( + "net/http" + "testing" + + "code.gitea.io/gitea/tests" +) + +func TestPrivateRepoProject(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + // not logged in user + req := NewRequest(t, "GET", "/user31/-/projects") + MakeRequest(t, req, http.StatusNotFound) + + sess := loginUser(t, "user1") + req = NewRequest(t, "GET", "/user31/-/projects") + sess.MakeRequest(t, req, http.StatusOK) +} From 0a794b2bcd9f3803e3aa4291387add4e0bb0d124 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 12 Dec 2023 19:31:11 +0800 Subject: [PATCH 17/60] Don't show unnecessary citation JS error on UI (#28433) Fix #28226 --- web_src/js/features/citation.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/web_src/js/features/citation.js b/web_src/js/features/citation.js index 65666864f6956..61f378f0f22b9 100644 --- a/web_src/js/features/citation.js +++ b/web_src/js/features/citation.js @@ -2,7 +2,7 @@ import $ from 'jquery'; const {pageData} = window.config; -const initInputCitationValue = async ($citationCopyApa, $citationCopyBibtex) => { +async function initInputCitationValue($citationCopyApa, $citationCopyBibtex) { const [{Cite, plugins}] = await Promise.all([ import(/* webpackChunkName: "citation-js-core" */'@citation-js/core'), import(/* webpackChunkName: "citation-js-formats" */'@citation-js/plugin-software-formats'), @@ -19,9 +19,9 @@ const initInputCitationValue = async ($citationCopyApa, $citationCopyBibtex) => const bibtexOutput = citationFormatter.format('bibtex', {lang}); $citationCopyBibtex.attr('data-text', bibtexOutput); $citationCopyApa.attr('data-text', apaOutput); -}; +} -export function initCitationFileCopyContent() { +export async function initCitationFileCopyContent() { const defaultCitationFormat = 'apa'; // apa or bibtex if (!pageData.citationFileContent) return; @@ -39,7 +39,14 @@ export function initCitationFileCopyContent() { $citationCopyBibtex.toggleClass('primary', isBibtex); $citationCopyApa.toggleClass('primary', !isBibtex); }; - initInputCitationValue($citationCopyApa, $citationCopyBibtex).then(updateUi); + + try { + await initInputCitationValue($citationCopyApa, $citationCopyBibtex); + } catch (e) { + console.error(`initCitationFileCopyContent error: ${e}`, e); + return; + } + updateUi(); $citationCopyApa.on('click', () => { localStorage.setItem('citation-copy-format', 'apa'); From ff5106d700c51932ae0547212d25b4fbf54ce99a Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Tue, 12 Dec 2023 14:51:33 +0100 Subject: [PATCH 18/60] Fix possible nil pointer access (#28428) There could be a nil pointer exception if the file is not found because that specific error is suppressed but not handled. --- services/packages/alpine/repository.go | 12 ++++-------- services/packages/container/cleanup.go | 6 ++---- services/packages/debian/repository.go | 19 +++++++------------ services/packages/rpm/repository.go | 5 +---- 4 files changed, 14 insertions(+), 28 deletions(-) diff --git a/services/packages/alpine/repository.go b/services/packages/alpine/repository.go index 46093d5bdd2e2..30b7a06eb36d9 100644 --- a/services/packages/alpine/repository.go +++ b/services/packages/alpine/repository.go @@ -82,10 +82,7 @@ func BuildAllRepositoryFiles(ctx context.Context, ownerID int64) error { } for _, pf := range pfs { - if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil { - return err - } - if err := packages_model.DeleteFileByID(ctx, pf.ID); err != nil { + if err := packages_service.DeletePackageFile(ctx, pf); err != nil { return err } } @@ -157,12 +154,11 @@ func buildPackagesIndex(ctx context.Context, ownerID int64, repoVersion *package pf, err := packages_model.GetFileForVersionByName(ctx, repoVersion.ID, IndexFilename, fmt.Sprintf("%s|%s|%s", branch, repository, architecture)) if err != nil && !errors.Is(err, util.ErrNotExist) { return err + } else if pf == nil { + return nil } - if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil { - return err - } - return packages_model.DeleteFileByID(ctx, pf.ID) + return packages_service.DeletePackageFile(ctx, pf) } // Cache data needed for all repository files diff --git a/services/packages/container/cleanup.go b/services/packages/container/cleanup.go index 1a9ef26391488..dd3f158dbf9ff 100644 --- a/services/packages/container/cleanup.go +++ b/services/packages/container/cleanup.go @@ -11,6 +11,7 @@ import ( container_model "code.gitea.io/gitea/models/packages/container" container_module "code.gitea.io/gitea/modules/packages/container" "code.gitea.io/gitea/modules/util" + packages_service "code.gitea.io/gitea/services/packages" digest "github.com/opencontainers/go-digest" ) @@ -47,10 +48,7 @@ func cleanupExpiredUploadedBlobs(ctx context.Context, olderThan time.Duration) e } for _, pf := range pfs { - if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil { - return err - } - if err := packages_model.DeleteFileByID(ctx, pf.ID); err != nil { + if err := packages_service.DeletePackageFile(ctx, pf); err != nil { return err } } diff --git a/services/packages/debian/repository.go b/services/packages/debian/repository.go index fca3cf420320a..86c54e40c840e 100644 --- a/services/packages/debian/repository.go +++ b/services/packages/debian/repository.go @@ -110,10 +110,7 @@ func BuildAllRepositoryFiles(ctx context.Context, ownerID int64) error { } for _, pf := range pfs { - if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil { - return err - } - if err := packages_model.DeleteFileByID(ctx, pf.ID); err != nil { + if err := packages_service.DeletePackageFile(ctx, pf); err != nil { return err } } @@ -181,12 +178,11 @@ func buildPackagesIndices(ctx context.Context, ownerID int64, repoVersion *packa pf, err := packages_model.GetFileForVersionByName(ctx, repoVersion.ID, filename, key) if err != nil && !errors.Is(err, util.ErrNotExist) { return err + } else if pf == nil { + continue } - if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil { - return err - } - if err := packages_model.DeleteFileByID(ctx, pf.ID); err != nil { + if err := packages_service.DeletePackageFile(ctx, pf); err != nil { return err } } @@ -286,12 +282,11 @@ func buildReleaseFiles(ctx context.Context, ownerID int64, repoVersion *packages pf, err := packages_model.GetFileForVersionByName(ctx, repoVersion.ID, filename, distribution) if err != nil && !errors.Is(err, util.ErrNotExist) { return err + } else if pf == nil { + continue } - if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil { - return err - } - if err := packages_model.DeleteFileByID(ctx, pf.ID); err != nil { + if err := packages_service.DeletePackageFile(ctx, pf); err != nil { return err } } diff --git a/services/packages/rpm/repository.go b/services/packages/rpm/repository.go index c9db0247f6d9f..7e718d321fd7f 100644 --- a/services/packages/rpm/repository.go +++ b/services/packages/rpm/repository.go @@ -148,10 +148,7 @@ func BuildRepositoryFiles(ctx context.Context, ownerID int64) error { return err } for _, pf := range pfs { - if err := packages_model.DeleteAllProperties(ctx, packages_model.PropertyTypeFile, pf.ID); err != nil { - return err - } - if err := packages_model.DeleteFileByID(ctx, pf.ID); err != nil { + if err := packages_service.DeletePackageFile(ctx, pf); err != nil { return err } } From c229e6519b2479745095573f4860f6066256209d Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Wed, 13 Dec 2023 00:24:37 +0000 Subject: [PATCH 19/60] [skip ci] Updated translations via Crowdin --- options/locale/locale_lv-LV.ini | 3 +++ 1 file changed, 3 insertions(+) diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 6d24435012177..9f84e78735805 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -80,6 +80,7 @@ milestones=Atskaites punkti ok=Labi cancel=Atcelt +retry=Mēģināt vēlreiz rerun=Palaist atkārtoti rerun_all=Palaist atkārtoti visus darbus save=Saglabāt @@ -95,6 +96,7 @@ disabled=Atspējots copy=Kopēt copy_url=Kopēt saiti +copy_hash=Kopēt jaucējkodu copy_content=Kopēt saturu copy_branch=Kopēt atzara nosaukumu copy_success=Nokopēts! @@ -129,6 +131,7 @@ show_timestamps=Rādīt laika zīmogus show_log_seconds=Rādīt sekundes show_full_screen=Atvērt pilnā logā +confirm_delete_selected=Apstiprināt, lai izdzēstu visus atlasītos vienumus? name=Nosaukums value=Vērtība From 73047854c00589137d6afbd4329d5176290af0c4 Mon Sep 17 00:00:00 2001 From: David Hulick Date: Wed, 13 Dec 2023 02:14:37 -0500 Subject: [PATCH 20/60] docs: Update group membership fields to match application. (#28175) Several fields in the "Verify group membership in LDAP" docs were confusingly titled when compared to the actual fields in the application, this change rectifies that by matching the docs to the fields already present in gitea. Signed-off-by: David Hulick --- docs/content/usage/authentication.en-us.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/content/usage/authentication.en-us.md b/docs/content/usage/authentication.en-us.md index 6a6de08d6c323..adc936dfbecd3 100644 --- a/docs/content/usage/authentication.en-us.md +++ b/docs/content/usage/authentication.en-us.md @@ -145,25 +145,25 @@ Adds the following fields: Uses the following fields: -- Group Search Base (optional) +- Group Search Base DN (optional) - The LDAP DN used for groups. - Example: `ou=group,dc=mydomain,dc=com` -- Group Name Filter (optional) - - - An LDAP filter declaring how to find valid groups in the above DN. - - Example: `(|(cn=gitea_users)(cn=admins))` +- Group Attribute Containing List Of Users (optional) + - The attribute of the group object that lists/contains the group members. + - Example: `memberUid` or `member` -- User Attribute in Group (optional) +- User Attribute Listed in Group (optional) - The user attribute that is used to reference a user in the group object. - Example: `uid` if the group objects contains a `member: bender` and the user object contains a `uid: bender`. - Example: `dn` if the group object contains a `member: uid=bender,ou=users,dc=planetexpress,dc=com`. -- Group Attribute for User (optional) - - The attribute of the group object that lists/contains the group members. - - Example: `memberUid` or `member` +- Verify group membership in LDAP (optional) + + - An LDAP filter declaring how to find valid groups in the above DN. + - Example: `(|(cn=gitea_users)(cn=admins))` ## PAM (Pluggable Authentication Module) From 064f05204c0539d1f92895776dee7f626a628e3b Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Wed, 13 Dec 2023 21:23:53 +0100 Subject: [PATCH 21/60] Add endpoint for not implemented Docker auth (#28457) Recently Docker started to use the optional `POST /v2/token` endpoint which should respond with a `404 Not Found` status code instead of the current `405 Method Not Allowed`. > Note: Not all token servers implement oauth2. If the request to the endpoint returns 404 using the HTTP POST method, refer to Token Documentation for using the HTTP GET method supported by all token servers. --- routers/api/packages/api.go | 5 ++++- routers/api/packages/container/container.go | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index 722ee3f87b193..76116d0751d7f 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -603,7 +603,10 @@ func ContainerRoutes() *web.Route { }) r.Get("", container.ReqContainerAccess, container.DetermineSupport) - r.Get("/token", container.Authenticate) + r.Group("/token", func() { + r.Get("", container.Authenticate) + r.Post("", container.AuthenticateNotImplemented) + }) r.Get("/_catalog", container.ReqContainerAccess, container.GetRepositoryList) r.Group("/{username}", func() { r.Group("/{image}", func() { diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index 62eec3064cdf9..dce38092641ed 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -156,6 +156,17 @@ func Authenticate(ctx *context.Context) { }) } +// https://distribution.github.io/distribution/spec/auth/oauth/ +func AuthenticateNotImplemented(ctx *context.Context) { + // This optional endpoint can be used to authenticate a client. + // It must implement the specification described in: + // https://datatracker.ietf.org/doc/html/rfc6749 + // https://distribution.github.io/distribution/spec/auth/oauth/ + // Purpose of this stub is to respond with 404 Not Found instead of 405 Method Not Allowed. + + ctx.Status(http.StatusNotFound) +} + // https://docs.docker.com/registry/spec/api/#listing-repositories func GetRepositoryList(ctx *context.Context) { n := ctx.FormInt("n") From cbf923e87bca0f50c2c01a60ccf544b63c365e98 Mon Sep 17 00:00:00 2001 From: Adam Majer Date: Wed, 13 Dec 2023 21:02:00 +0000 Subject: [PATCH 22/60] Abstract hash function usage (#28138) Refactor Hash interfaces and centralize hash function. This will allow easier introduction of different hash function later on. This forms the "no-op" part of the SHA256 enablement patch. --- cmd/hook.go | 7 +- models/git/branch_test.go | 2 +- models/git/commit_status.go | 13 +- models/repo/repo.go | 6 +- modules/context/api.go | 9 +- modules/context/repo.go | 18 ++- modules/git/batch_reader.go | 30 ++-- modules/git/blame.go | 39 ++--- modules/git/blame_test.go | 4 +- modules/git/blob_gogit.go | 2 +- modules/git/blob_nogogit.go | 2 +- modules/git/commit.go | 19 ++- modules/git/commit_convert_gogit.go | 4 +- modules/git/commit_info_gogit.go | 2 +- modules/git/commit_info_nogogit.go | 2 +- modules/git/commit_reader.go | 8 +- modules/git/commit_test.go | 6 +- modules/git/last_commit_cache.go | 10 +- modules/git/last_commit_cache_gogit.go | 3 +- modules/git/log_name_status.go | 13 +- modules/git/notes_gogit.go | 3 +- modules/git/object_format.go | 103 +++++++++++++ modules/git/object_id.go | 143 ++++++++++++++++++ modules/git/object_id_gogit.go | 28 ++++ modules/git/object_id_test.go | 21 +++ modules/git/parse_gogit.go | 16 +- modules/git/parse_gogit_test.go | 20 ++- modules/git/parse_nogogit.go | 16 +- modules/git/parse_nogogit_test.go | 22 +-- modules/git/pipeline/lfs.go | 14 +- modules/git/pipeline/lfs_nogogit.go | 39 ++--- modules/git/ref.go | 4 +- modules/git/repo.go | 31 +++- modules/git/repo_base_gogit.go | 3 + modules/git/repo_base_nogogit.go | 7 + modules/git/repo_blob.go | 2 +- modules/git/repo_blob_gogit.go | 4 +- modules/git/repo_blob_nogogit.go | 2 +- modules/git/repo_blob_test.go | 2 +- modules/git/repo_commit.go | 35 ++--- modules/git/repo_commit_gogit.go | 35 +++-- modules/git/repo_commit_nogogit.go | 25 +-- modules/git/repo_compare.go | 2 +- modules/git/repo_compare_test.go | 6 +- modules/git/repo_gpg.go | 2 +- modules/git/repo_index.go | 19 ++- modules/git/repo_language_stats_nogogit.go | 2 +- modules/git/repo_object.go | 44 +++++- modules/git/repo_ref_gogit.go | 4 +- modules/git/repo_ref_nogogit.go | 2 +- modules/git/repo_tag.go | 14 +- modules/git/repo_tag_gogit.go | 12 +- modules/git/repo_tag_nogogit.go | 8 +- modules/git/repo_tag_test.go | 15 +- modules/git/repo_tree.go | 6 +- modules/git/repo_tree_gogit.go | 14 +- modules/git/repo_tree_nogogit.go | 10 +- modules/git/sha1.go | 72 --------- modules/git/sha1_gogit.go | 19 --- modules/git/sha1_nogogit.go | 61 -------- modules/git/sha1_test.go | 20 --- modules/git/tag.go | 10 +- modules/git/tag_test.go | 10 +- modules/git/tree.go | 2 +- modules/git/tree_blob_gogit.go | 2 +- modules/git/tree_entry_gogit.go | 4 +- modules/git/tree_entry_nogogit.go | 2 +- modules/git/tree_gogit.go | 10 +- modules/git/tree_nogogit.go | 10 +- modules/indexer/code/git.go | 17 ++- modules/repository/commits_test.go | 7 +- modules/repository/generate.go | 6 +- modules/repository/init.go | 4 +- modules/repository/push.go | 6 +- routers/api/v1/repo/notes.go | 4 +- routers/api/v1/repo/repo.go | 1 + routers/api/v1/utils/git.go | 17 ++- routers/private/hook_post_receive.go | 3 +- routers/private/hook_pre_receive.go | 7 +- routers/private/hook_verification.go | 8 +- routers/private/hook_verification_test.go | 7 +- routers/web/repo/blame.go | 9 +- routers/web/repo/branch.go | 9 +- routers/web/repo/commit.go | 2 +- routers/web/repo/compare.go | 3 +- routers/web/repo/githttp.go | 2 +- routers/web/repo/repo.go | 2 + routers/web/repo/setting/lfs.go | 11 +- routers/web/repo/setting/webhook.go | 8 +- services/actions/commit_status.go | 7 +- services/agit/agit.go | 6 +- services/convert/git_commit_test.go | 10 +- services/forms/repo_form.go | 2 + services/gitdiff/gitdiff.go | 24 ++- services/migrations/common.go | 8 +- services/migrations/gitea_uploader.go | 3 +- services/migrations/gitea_uploader_test.go | 2 +- services/mirror/mirror_pull.go | 6 +- services/packages/cargo/index.go | 2 +- services/pull/check.go | 19 ++- services/pull/merge.go | 3 +- services/pull/patch.go | 9 +- services/pull/pull.go | 3 +- services/pull/temp_repo.go | 10 +- services/release/release.go | 11 +- services/repository/archiver/archiver.go | 28 +--- services/repository/branch.go | 7 +- services/repository/check.go | 2 +- services/repository/create.go | 8 +- services/repository/files/cherry_pick.go | 5 +- services/repository/files/commit.go | 11 +- services/repository/files/patch.go | 2 +- services/repository/files/temp_repo.go | 4 +- services/repository/files/tree.go | 18 ++- services/repository/files/update.go | 5 +- services/repository/files/upload.go | 2 +- services/repository/lfs.go | 3 +- services/repository/push.go | 21 ++- services/webhook/slack.go | 1 + services/wiki/wiki.go | 2 +- services/wiki/wiki_test.go | 2 +- .../git_helper_for_declarative_test.go | 2 +- 122 files changed, 945 insertions(+), 592 deletions(-) create mode 100644 modules/git/object_format.go create mode 100644 modules/git/object_id.go create mode 100644 modules/git/object_id_gogit.go create mode 100644 modules/git/object_id_test.go delete mode 100644 modules/git/sha1.go delete mode 100644 modules/git/sha1_gogit.go delete mode 100644 modules/git/sha1_nogogit.go delete mode 100644 modules/git/sha1_test.go diff --git a/cmd/hook.go b/cmd/hook.go index f38fd8831b8d5..624569cdfa7ea 100644 --- a/cmd/hook.go +++ b/cmd/hook.go @@ -376,7 +376,9 @@ Gitea or set your environment appropriately.`, "") oldCommitIDs[count] = string(fields[0]) newCommitIDs[count] = string(fields[1]) refFullNames[count] = git.RefName(fields[2]) - if refFullNames[count] == git.BranchPrefix+"master" && newCommitIDs[count] != git.EmptySHA && count == total { + + commitID, _ := git.IDFromString(newCommitIDs[count]) + if refFullNames[count] == git.BranchPrefix+"master" && !commitID.IsZero() && count == total { masterPushed = true } count++ @@ -669,7 +671,8 @@ Gitea or set your environment appropriately.`, "") if err != nil { return err } - if rs.OldOID != git.EmptySHA { + commitID, _ := git.IDFromString(rs.OldOID) + if !commitID.IsZero() { err = writeDataPktLine(ctx, os.Stdout, []byte("option old-oid "+rs.OldOID)) if err != nil { return err diff --git a/models/git/branch_test.go b/models/git/branch_test.go index ce4cbd56a123d..adcf9fd305ae8 100644 --- a/models/git/branch_test.go +++ b/models/git/branch_test.go @@ -30,7 +30,7 @@ func TestAddDeletedBranch(t *testing.T) { assert.True(t, secondBranch.IsDeleted) commit := &git.Commit{ - ID: git.MustIDFromString(secondBranch.CommitID), + ID: repo.ObjectFormat.MustIDFromString(secondBranch.CommitID), CommitMessage: secondBranch.CommitMessage, Committer: &git.Signature{ When: secondBranch.CommitTime.AsLocalTime(), diff --git a/models/git/commit_status.go b/models/git/commit_status.go index 097ce01c1442a..a22fd2304362a 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -114,7 +114,8 @@ WHEN NOT MATCHED // GetNextCommitStatusIndex retried 3 times to generate a resource index func GetNextCommitStatusIndex(ctx context.Context, repoID int64, sha string) (int64, error) { - if !git.IsValidSHAPattern(sha) { + _, err := git.IDFromString(sha) + if err != nil { return 0, git.ErrInvalidSHA{SHA: sha} } @@ -425,7 +426,7 @@ func FindRepoRecentCommitStatusContexts(ctx context.Context, repoID int64, befor type NewCommitStatusOptions struct { Repo *repo_model.Repository Creator *user_model.User - SHA string + SHA git.ObjectID CommitStatus *CommitStatus } @@ -440,10 +441,6 @@ func NewCommitStatus(ctx context.Context, opts NewCommitStatusOptions) error { return fmt.Errorf("NewCommitStatus[%s, %s]: no user specified", repoPath, opts.SHA) } - if _, err := git.NewIDFromString(opts.SHA); err != nil { - return fmt.Errorf("NewCommitStatus[%s, %s]: invalid sha: %w", repoPath, opts.SHA, err) - } - ctx, committer, err := db.TxContext(ctx) if err != nil { return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", opts.Repo.ID, opts.Creator.ID, opts.SHA, err) @@ -451,7 +448,7 @@ func NewCommitStatus(ctx context.Context, opts NewCommitStatusOptions) error { defer committer.Close() // Get the next Status Index - idx, err := GetNextCommitStatusIndex(ctx, opts.Repo.ID, opts.SHA) + idx, err := GetNextCommitStatusIndex(ctx, opts.Repo.ID, opts.SHA.String()) if err != nil { return fmt.Errorf("generate commit status index failed: %w", err) } @@ -459,7 +456,7 @@ func NewCommitStatus(ctx context.Context, opts NewCommitStatusOptions) error { opts.CommitStatus.Description = strings.TrimSpace(opts.CommitStatus.Description) opts.CommitStatus.Context = strings.TrimSpace(opts.CommitStatus.Context) opts.CommitStatus.TargetURL = strings.TrimSpace(opts.CommitStatus.TargetURL) - opts.CommitStatus.SHA = opts.SHA + opts.CommitStatus.SHA = opts.SHA.String() opts.CommitStatus.CreatorID = opts.Creator.ID opts.CommitStatus.RepoID = opts.Repo.ID opts.CommitStatus.Index = idx diff --git a/models/repo/repo.go b/models/repo/repo.go index db3709f1e8025..59f68df996a46 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/setting" @@ -179,6 +180,7 @@ type Repository struct { IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"` CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"` Topics []string `xorm:"TEXT JSON"` + ObjectFormat git.ObjectFormat `xorm:"-"` TrustModel TrustModelType @@ -274,6 +276,8 @@ func (repo *Repository) AfterLoad() { repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects repo.NumOpenActionRuns = repo.NumActionRuns - repo.NumClosedActionRuns + + repo.ObjectFormat = git.ObjectFormatFromID(git.Sha1) } // LoadAttributes loads attributes of the repository. @@ -313,7 +317,7 @@ func (repo *Repository) HTMLURL() string { // CommitLink make link to by commit full ID // note: won't check whether it's an right id func (repo *Repository) CommitLink(commitID string) (result string) { - if commitID == "" || commitID == "0000000000000000000000000000000000000000" { + if git.IsEmptyCommitID(commitID) { result = "" } else { result = repo.Link() + "/commit/" + url.PathEscape(commitID) diff --git a/modules/context/api.go b/modules/context/api.go index ba35adf8310d7..f41228ad7674e 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -308,6 +308,12 @@ func RepoRefForAPI(next http.Handler) http.Handler { return } + objectFormat, err := ctx.Repo.GitRepo.GetObjectFormat() + if err != nil { + ctx.Error(http.StatusInternalServerError, "GetCommit", err) + return + } + if ref := ctx.FormTrim("ref"); len(ref) > 0 { commit, err := ctx.Repo.GitRepo.GetCommit(ref) if err != nil { @@ -325,7 +331,6 @@ func RepoRefForAPI(next http.Handler) http.Handler { return } - var err error refName := getRefName(ctx.Base, ctx.Repo, RepoRefAny) if ctx.Repo.GitRepo.IsBranchExist(refName) { @@ -342,7 +347,7 @@ func RepoRefForAPI(next http.Handler) http.Handler { return } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() - } else if len(refName) == git.SHAFullLength { + } else if len(refName) == objectFormat.FullLength() { ctx.Repo.CommitID = refName ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName) if err != nil { diff --git a/modules/context/repo.go b/modules/context/repo.go index a18dc873b6444..882a406731f54 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -825,7 +825,9 @@ func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string { } // For legacy and API support only full commit sha parts := strings.Split(path, "/") - if len(parts) > 0 && len(parts[0]) == git.SHAFullLength { + objectFormat, _ := repo.GitRepo.GetObjectFormat() + + if len(parts) > 0 && len(parts[0]) == objectFormat.FullLength() { repo.TreePath = strings.Join(parts[1:], "/") return parts[0] } @@ -869,7 +871,9 @@ func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string { return getRefNameFromPath(ctx, repo, path, repo.GitRepo.IsTagExist) case RepoRefCommit: parts := strings.Split(path, "/") - if len(parts) > 0 && len(parts[0]) >= 7 && len(parts[0]) <= git.SHAFullLength { + objectFormat, _ := repo.GitRepo.GetObjectFormat() + + if len(parts) > 0 && len(parts[0]) >= 7 && len(parts[0]) <= objectFormat.FullLength() { repo.TreePath = strings.Join(parts[1:], "/") return parts[0] } @@ -929,6 +933,12 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context } } + objectFormat, err := ctx.Repo.GitRepo.GetObjectFormat() + if err != nil { + log.Error("Cannot determine objectFormat for repository: %w", err) + ctx.Repo.Repository.MarkAsBrokenEmpty() + } + // Get default branch. if len(ctx.Params("*")) == 0 { refName = ctx.Repo.Repository.DefaultBranch @@ -995,7 +1005,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context return cancel } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() - } else if len(refName) >= 7 && len(refName) <= git.SHAFullLength { + } else if len(refName) >= 7 && len(refName) <= objectFormat.FullLength() { ctx.Repo.IsViewCommit = true ctx.Repo.CommitID = refName @@ -1005,7 +1015,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context return cancel } // If short commit ID add canonical link header - if len(refName) < git.SHAFullLength { + if len(refName) < objectFormat.FullLength() { ctx.RespHeader().Set("Link", fmt.Sprintf("<%s>; rel=\"canonical\"", util.URLJoin(setting.AppURL, strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1)))) } diff --git a/modules/git/batch_reader.go b/modules/git/batch_reader.go index 7a44e6295c4e2..53a9393d5fc18 100644 --- a/modules/git/batch_reader.go +++ b/modules/git/batch_reader.go @@ -148,7 +148,7 @@ func CatFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufi // ReadBatchLine reads the header line from cat-file --batch // We expect: // SP SP LF -// sha is a 40byte not 20byte here +// sha is a hex encoded here func ReadBatchLine(rd *bufio.Reader) (sha []byte, typ string, size int64, err error) { typ, err = rd.ReadString('\n') if err != nil { @@ -251,20 +251,19 @@ headerLoop: } // git tree files are a list: -// SP NUL <20-byte SHA> +// SP NUL // // Unfortunately this 20-byte notation is somewhat in conflict to all other git tools -// Therefore we need some method to convert these 20-byte SHAs to a 40-byte SHA +// Therefore we need some method to convert these binary hashes to hex hashes -// constant hextable to help quickly convert between 20byte and 40byte hashes +// constant hextable to help quickly convert between binary and hex representation const hextable = "0123456789abcdef" -// To40ByteSHA converts a 20-byte SHA into a 40-byte sha. Input and output can be the -// same 40 byte slice to support in place conversion without allocations. +// BinToHexHeash converts a binary Hash into a hex encoded one. Input and output can be the +// same byte slice to support in place conversion without allocations. // This is at least 100x quicker that hex.EncodeToString -// NB This requires that out is a 40-byte slice -func To40ByteSHA(sha, out []byte) []byte { - for i := 19; i >= 0; i-- { +func BinToHex(objectFormat ObjectFormat, sha, out []byte) []byte { + for i := objectFormat.FullLength()/2 - 1; i >= 0; i-- { v := sha[i] vhi, vlo := v>>4, v&0x0f shi, slo := hextable[vhi], hextable[vlo] @@ -278,10 +277,10 @@ func To40ByteSHA(sha, out []byte) []byte { // It is recommended therefore to pass in an fnameBuf large enough to avoid almost all allocations // // Each line is composed of: -// SP NUL <20-byte SHA> +// SP NUL // -// We don't attempt to convert the 20-byte SHA to 40-byte SHA to save a lot of time -func ParseTreeLine(rd *bufio.Reader, modeBuf, fnameBuf, shaBuf []byte) (mode, fname, sha []byte, n int, err error) { +// We don't attempt to convert the raw HASH to save a lot of time +func ParseTreeLine(objectFormat ObjectFormat, rd *bufio.Reader, modeBuf, fnameBuf, shaBuf []byte) (mode, fname, sha []byte, n int, err error) { var readBytes []byte // Read the Mode & fname @@ -324,11 +323,12 @@ func ParseTreeLine(rd *bufio.Reader, modeBuf, fnameBuf, shaBuf []byte) (mode, fn fnameBuf = fnameBuf[:len(fnameBuf)-1] fname = fnameBuf - // Deal with the 20-byte SHA + // Deal with the binary hash idx = 0 - for idx < 20 { + len := objectFormat.FullLength() / 2 + for idx < len { var read int - read, err = rd.Read(shaBuf[idx:20]) + read, err = rd.Read(shaBuf[idx:len]) n += read if err != nil { return mode, fname, sha, n, err diff --git a/modules/git/blame.go b/modules/git/blame.go index 93c7f184fa220..64095a218a31c 100644 --- a/modules/git/blame.go +++ b/modules/git/blame.go @@ -10,8 +10,6 @@ import ( "fmt" "io" "os" - "regexp" - "strings" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" @@ -33,14 +31,13 @@ type BlameReader struct { done chan error lastSha *string ignoreRevsFile *string + objectFormat ObjectFormat } func (r *BlameReader) UsesIgnoreRevs() bool { return r.ignoreRevsFile != nil } -var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})") - // NextPart returns next part of blame (sequential code lines with the same commit) func (r *BlameReader) NextPart() (*BlamePart, error) { var blamePart *BlamePart @@ -52,6 +49,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) { } } + const previousHeader = "previous " var lineBytes []byte var isPrefix bool var err error @@ -67,21 +65,22 @@ func (r *BlameReader) NextPart() (*BlamePart, error) { continue } - line := string(lineBytes) - - lines := shaLineRegex.FindStringSubmatch(line) - if lines != nil { - sha1 := lines[1] + var objectID string + objectFormatLength := r.objectFormat.FullLength() + if len(lineBytes) > objectFormatLength && lineBytes[objectFormatLength] == ' ' && r.objectFormat.IsValid(string(lineBytes[0:objectFormatLength])) { + objectID = string(lineBytes[0:objectFormatLength]) + } + if len(objectID) > 0 { if blamePart == nil { blamePart = &BlamePart{ - Sha: sha1, + Sha: objectID, Lines: make([]string, 0), } } - if blamePart.Sha != sha1 { - r.lastSha = &sha1 + if blamePart.Sha != objectID { + r.lastSha = &objectID // need to munch to end of line... for isPrefix { _, isPrefix, err = r.bufferedReader.ReadLine() @@ -91,12 +90,13 @@ func (r *BlameReader) NextPart() (*BlamePart, error) { } return blamePart, nil } - } else if line[0] == '\t' { - blamePart.Lines = append(blamePart.Lines, line[1:]) - } else if strings.HasPrefix(line, "previous ") { - parts := strings.SplitN(line[len("previous "):], " ", 2) - blamePart.PreviousSha = parts[0] - blamePart.PreviousPath = parts[1] + } else if lineBytes[0] == '\t' { + blamePart.Lines = append(blamePart.Lines, string(lineBytes[1:])) + } else if bytes.HasPrefix(lineBytes, []byte(previousHeader)) { + offset := len(previousHeader) // already includes a space + blamePart.PreviousSha = string(lineBytes[offset : offset+objectFormatLength]) + offset += objectFormatLength + 1 // +1 for space + blamePart.PreviousPath = string(lineBytes[offset:]) } // need to munch to end of line... @@ -126,7 +126,7 @@ func (r *BlameReader) Close() error { } // CreateBlameReader creates reader for given repository, commit and file -func CreateBlameReader(ctx context.Context, repoPath string, commit *Commit, file string, bypassBlameIgnore bool) (*BlameReader, error) { +func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath string, commit *Commit, file string, bypassBlameIgnore bool) (*BlameReader, error) { var ignoreRevsFile *string if CheckGitVersionAtLeast("2.23") == nil && !bypassBlameIgnore { ignoreRevsFile = tryCreateBlameIgnoreRevsFile(commit) @@ -175,6 +175,7 @@ func CreateBlameReader(ctx context.Context, repoPath string, commit *Commit, fil bufferedReader: bufferedReader, done: done, ignoreRevsFile: ignoreRevsFile, + objectFormat: objectFormat, }, nil } diff --git a/modules/git/blame_test.go b/modules/git/blame_test.go index 040f4e822dac7..0afc6d2a1f0f7 100644 --- a/modules/git/blame_test.go +++ b/modules/git/blame_test.go @@ -39,7 +39,7 @@ func TestReadingBlameOutput(t *testing.T) { } for _, bypass := range []bool{false, true} { - blameReader, err := CreateBlameReader(ctx, "./tests/repos/repo5_pulls", commit, "README.md", bypass) + blameReader, err := CreateBlameReader(ctx, &Sha1ObjectFormat{}, "./tests/repos/repo5_pulls", commit, "README.md", bypass) assert.NoError(t, err) assert.NotNil(t, blameReader) defer blameReader.Close() @@ -122,7 +122,7 @@ func TestReadingBlameOutput(t *testing.T) { commit, err := repo.GetCommit(c.CommitID) assert.NoError(t, err) - blameReader, err := CreateBlameReader(ctx, "./tests/repos/repo6_blame", commit, "blame.txt", c.Bypass) + blameReader, err := CreateBlameReader(ctx, repo.objectFormat, "./tests/repos/repo6_blame", commit, "blame.txt", c.Bypass) assert.NoError(t, err) assert.NotNil(t, blameReader) defer blameReader.Close() diff --git a/modules/git/blob_gogit.go b/modules/git/blob_gogit.go index aa206409d0b6f..8c79c067c1749 100644 --- a/modules/git/blob_gogit.go +++ b/modules/git/blob_gogit.go @@ -14,7 +14,7 @@ import ( // Blob represents a Git object. type Blob struct { - ID SHA1 + ID ObjectID gogitEncodedObj plumbing.EncodedObject name string diff --git a/modules/git/blob_nogogit.go b/modules/git/blob_nogogit.go index 511332eb50641..6e8a48b1db0f1 100644 --- a/modules/git/blob_nogogit.go +++ b/modules/git/blob_nogogit.go @@ -16,7 +16,7 @@ import ( // Blob represents a Git object. type Blob struct { - ID SHA1 + ID ObjectID gotSize bool size int64 diff --git a/modules/git/commit.go b/modules/git/commit.go index 4ff8f6148f741..a8b6c0e8f793e 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -21,13 +21,13 @@ import ( // Commit represents a git commit. type Commit struct { Tree - ID SHA1 // The ID of this commit object + ID ObjectID // The ID of this commit object Author *Signature Committer *Signature CommitMessage string Signature *CommitGPGSignature - Parents []SHA1 // SHA1 strings + Parents []ObjectID // ID strings submoduleCache *ObjectCache } @@ -50,9 +50,9 @@ func (c *Commit) Summary() string { // ParentID returns oid of n-th parent (0-based index). // It returns nil if no such parent exists. -func (c *Commit) ParentID(n int) (SHA1, error) { +func (c *Commit) ParentID(n int) (ObjectID, error) { if n >= len(c.Parents) { - return SHA1{}, ErrNotExist{"", ""} + return nil, ErrNotExist{"", ""} } return c.Parents[n], nil } @@ -209,9 +209,9 @@ func (c *Commit) CommitsBefore() ([]*Commit, error) { } // HasPreviousCommit returns true if a given commitHash is contained in commit's parents -func (c *Commit) HasPreviousCommit(commitHash SHA1) (bool, error) { +func (c *Commit) HasPreviousCommit(objectID ObjectID) (bool, error) { this := c.ID.String() - that := commitHash.String() + that := objectID.String() if this == that { return false, nil @@ -232,9 +232,14 @@ func (c *Commit) HasPreviousCommit(commitHash SHA1) (bool, error) { // IsForcePush returns true if a push from oldCommitHash to this is a force push func (c *Commit) IsForcePush(oldCommitID string) (bool, error) { - if oldCommitID == EmptySHA { + objectFormat, err := c.repo.GetObjectFormat() + if err != nil { + return false, err + } + if oldCommitID == objectFormat.Empty().String() { return false, nil } + oldCommit, err := c.repo.GetCommit(oldCommitID) if err != nil { return false, err diff --git a/modules/git/commit_convert_gogit.go b/modules/git/commit_convert_gogit.go index 669f1b15d5389..819ea0d1dba3e 100644 --- a/modules/git/commit_convert_gogit.go +++ b/modules/git/commit_convert_gogit.go @@ -59,11 +59,11 @@ func convertPGPSignature(c *object.Commit) *CommitGPGSignature { func convertCommit(c *object.Commit) *Commit { return &Commit{ - ID: c.Hash, + ID: ParseGogitHash(c.Hash), CommitMessage: c.Message, Committer: &c.Committer, Author: &c.Author, Signature: convertPGPSignature(c), - Parents: c.ParentHashes, + Parents: ParseGogitHashArray(c.ParentHashes), } } diff --git a/modules/git/commit_info_gogit.go b/modules/git/commit_info_gogit.go index c61d27993cd78..31ffc9aec1c38 100644 --- a/modules/git/commit_info_gogit.go +++ b/modules/git/commit_info_gogit.go @@ -29,7 +29,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath defer commitGraphFile.Close() } - c, err := commitNodeIndex.Get(commit.ID) + c, err := commitNodeIndex.Get(plumbing.Hash(commit.ID.RawValue())) if err != nil { return nil, nil, err } diff --git a/modules/git/commit_info_nogogit.go b/modules/git/commit_info_nogogit.go index e469d2cab6374..8cf8200c3f741 100644 --- a/modules/git/commit_info_nogogit.go +++ b/modules/git/commit_info_nogogit.go @@ -153,7 +153,7 @@ func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string, if typ != "commit" { return nil, fmt.Errorf("unexpected type: %s for commit id: %s", typ, commitID) } - c, err = CommitFromReader(commit.repo, MustIDFromString(commitID), io.LimitReader(batchReader, size)) + c, err = CommitFromReader(commit.repo, commit.ID.Type().MustIDFromString(commitID), io.LimitReader(batchReader, size)) if err != nil { return nil, err } diff --git a/modules/git/commit_reader.go b/modules/git/commit_reader.go index 23607c43abe25..08a529a13219c 100644 --- a/modules/git/commit_reader.go +++ b/modules/git/commit_reader.go @@ -14,9 +14,9 @@ import ( // We need this to interpret commits from cat-file or cat-file --batch // // If used as part of a cat-file --batch stream you need to limit the reader to the correct size -func CommitFromReader(gitRepo *Repository, sha SHA1, reader io.Reader) (*Commit, error) { +func CommitFromReader(gitRepo *Repository, objectID ObjectID, reader io.Reader) (*Commit, error) { commit := &Commit{ - ID: sha, + ID: objectID, Author: &Signature{}, Committer: &Signature{}, } @@ -71,10 +71,10 @@ readLoop: switch string(split[0]) { case "tree": - commit.Tree = *NewTree(gitRepo, MustIDFromString(string(data))) + commit.Tree = *NewTree(gitRepo, objectID.Type().MustIDFromString(string(data))) _, _ = payloadSB.Write(line) case "parent": - commit.Parents = append(commit.Parents, MustIDFromString(string(data))) + commit.Parents = append(commit.Parents, objectID.Type().MustIDFromString(string(data))) _, _ = payloadSB.Write(line) case "author": commit.Author = &Signature{} diff --git a/modules/git/commit_test.go b/modules/git/commit_test.go index ac586fdf09d3e..dec67f6628609 100644 --- a/modules/git/commit_test.go +++ b/modules/git/commit_test.go @@ -81,7 +81,7 @@ gpgsig -----BEGIN PGP SIGNATURE----- empty commit` - sha := SHA1{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2} + sha := &Sha1Hash{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2} gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare")) assert.NoError(t, err) assert.NotNil(t, gitRepo) @@ -135,8 +135,8 @@ func TestHasPreviousCommit(t *testing.T) { commit, err := repo.GetCommit("8006ff9adbf0cb94da7dad9e537e53817f9fa5c0") assert.NoError(t, err) - parentSHA := MustIDFromString("8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2") - notParentSHA := MustIDFromString("2839944139e0de9737a044f78b0e4b40d989a9e3") + parentSHA := repo.objectFormat.MustIDFromString("8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2") + notParentSHA := repo.objectFormat.MustIDFromString("2839944139e0de9737a044f78b0e4b40d989a9e3") haz, err := commit.HasPreviousCommit(parentSHA) assert.NoError(t, err) diff --git a/modules/git/last_commit_cache.go b/modules/git/last_commit_cache.go index 20bc79608557a..55585ac4ac9ec 100644 --- a/modules/git/last_commit_cache.go +++ b/modules/git/last_commit_cache.go @@ -92,17 +92,21 @@ func (c *LastCommitCache) Get(ref, entryPath string) (*Commit, error) { // GetCommitByPath gets the last commit for the entry in the provided commit func (c *LastCommitCache) GetCommitByPath(commitID, entryPath string) (*Commit, error) { - sha1, err := NewIDFromString(commitID) + objectFormat, err := c.repo.GetObjectFormat() + if err != nil { + return nil, err + } + sha, err := objectFormat.NewIDFromString(commitID) if err != nil { return nil, err } - lastCommit, err := c.Get(sha1.String(), entryPath) + lastCommit, err := c.Get(sha.String(), entryPath) if err != nil || lastCommit != nil { return lastCommit, err } - lastCommit, err = c.repo.getCommitByPathWithID(sha1, entryPath) + lastCommit, err = c.repo.getCommitByPathWithID(sha, entryPath) if err != nil { return nil, err } diff --git a/modules/git/last_commit_cache_gogit.go b/modules/git/last_commit_cache_gogit.go index 90e609fc81c7b..3afc213094225 100644 --- a/modules/git/last_commit_cache_gogit.go +++ b/modules/git/last_commit_cache_gogit.go @@ -8,6 +8,7 @@ package git import ( "context" + "github.com/go-git/go-git/v5/plumbing" cgobject "github.com/go-git/go-git/v5/plumbing/object/commitgraph" ) @@ -18,7 +19,7 @@ func (c *Commit) CacheCommit(ctx context.Context) error { } commitNodeIndex, _ := c.repo.CommitNodeIndex() - index, err := commitNodeIndex.Get(c.ID) + index, err := commitNodeIndex.Get(plumbing.Hash(c.ID.RawValue())) if err != nil { return err } diff --git a/modules/git/log_name_status.go b/modules/git/log_name_status.go index 7519e32b90027..26a0d28098a82 100644 --- a/modules/git/log_name_status.go +++ b/modules/git/log_name_status.go @@ -143,17 +143,20 @@ func (g *LogNameStatusRepoParser) Next(treepath string, paths2ids map[string]int } // Our "line" must look like: SP ( SP) * NUL - ret.CommitID = string(g.next[0:40]) - parents := string(g.next[41:]) + commitIds := string(g.next) if g.buffull { more, err := g.rd.ReadString('\x00') if err != nil { return nil, err } - parents += more + commitIds += more + } + commitIds = commitIds[:len(commitIds)-1] + splitIds := strings.Split(commitIds, " ") + ret.CommitID = splitIds[0] + if len(splitIds) > 1 { + ret.ParentIDs = splitIds[1:] } - parents = parents[:len(parents)-1] - ret.ParentIDs = strings.Split(parents, " ") // now read the next "line" g.buffull = false diff --git a/modules/git/notes_gogit.go b/modules/git/notes_gogit.go index c2297d89703ea..f802443b00e5b 100644 --- a/modules/git/notes_gogit.go +++ b/modules/git/notes_gogit.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/modules/log" + "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" ) @@ -72,7 +73,7 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) defer commitGraphFile.Close() } - commitNode, err := commitNodeIndex.Get(notes.ID) + commitNode, err := commitNodeIndex.Get(plumbing.Hash(notes.ID.RawValue())) if err != nil { return err } diff --git a/modules/git/object_format.go b/modules/git/object_format.go new file mode 100644 index 0000000000000..7f5d09170c6fb --- /dev/null +++ b/modules/git/object_format.go @@ -0,0 +1,103 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package git + +import ( + "crypto/sha1" + "fmt" + "regexp" + "strings" +) + +type ObjectFormatID int + +const ( + Sha1 ObjectFormatID = iota +) + +// sha1Pattern can be used to determine if a string is an valid sha +var sha1Pattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`) + +type ObjectFormat interface { + ID() ObjectFormatID + String() string + + // Empty is the hash of empty git + Empty() ObjectID + // EmptyTree is the hash of an empty tree + EmptyTree() ObjectID + // FullLength is the length of the hash's hex string + FullLength() int + + IsValid(input string) bool + MustID(b []byte) ObjectID + MustIDFromString(s string) ObjectID + NewID(b []byte) (ObjectID, error) + NewIDFromString(s string) (ObjectID, error) + NewEmptyID() ObjectID + + NewHasher() HasherInterface +} + +/* SHA1 Type */ +type Sha1ObjectFormat struct{} + +func (*Sha1ObjectFormat) ID() ObjectFormatID { return Sha1 } +func (*Sha1ObjectFormat) String() string { return "sha1" } +func (*Sha1ObjectFormat) Empty() ObjectID { return &Sha1Hash{} } +func (*Sha1ObjectFormat) EmptyTree() ObjectID { + return &Sha1Hash{ + 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, + 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04, + } +} +func (*Sha1ObjectFormat) FullLength() int { return 40 } +func (*Sha1ObjectFormat) IsValid(input string) bool { + return sha1Pattern.MatchString(input) +} + +func (*Sha1ObjectFormat) MustID(b []byte) ObjectID { + var id Sha1Hash + copy(id[0:20], b) + return &id +} + +func (h *Sha1ObjectFormat) MustIDFromString(s string) ObjectID { + return MustIDFromString(h, s) +} + +func (h *Sha1ObjectFormat) NewID(b []byte) (ObjectID, error) { + return IDFromRaw(h, b) +} + +func (h *Sha1ObjectFormat) NewIDFromString(s string) (ObjectID, error) { + return genericIDFromString(h, s) +} + +func (*Sha1ObjectFormat) NewEmptyID() ObjectID { + return NewSha1() +} + +func (h *Sha1ObjectFormat) NewHasher() HasherInterface { + return &Sha1Hasher{sha1.New()} +} + +// utils +func ObjectFormatFromID(id ObjectFormatID) ObjectFormat { + switch id { + case Sha1: + return &Sha1ObjectFormat{} + } + + return nil +} + +func ObjectFormatFromString(hash string) (ObjectFormat, error) { + switch strings.ToLower(hash) { + case "sha1": + return &Sha1ObjectFormat{}, nil + } + + return nil, fmt.Errorf("unknown hash type: %s", hash) +} diff --git a/modules/git/object_id.go b/modules/git/object_id.go new file mode 100644 index 0000000000000..3cba6d4f724db --- /dev/null +++ b/modules/git/object_id.go @@ -0,0 +1,143 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package git + +import ( + "bytes" + "encoding/hex" + "errors" + "fmt" + "hash" + "strconv" + "strings" +) + +type ObjectID interface { + String() string + IsZero() bool + RawValue() []byte + Type() ObjectFormat +} + +/* SHA1 */ +type Sha1Hash [20]byte + +func (h *Sha1Hash) String() string { + return hex.EncodeToString(h[:]) +} + +func (h *Sha1Hash) IsZero() bool { + empty := Sha1Hash{} + return bytes.Equal(empty[:], h[:]) +} +func (h *Sha1Hash) RawValue() []byte { return h[:] } +func (*Sha1Hash) Type() ObjectFormat { return &Sha1ObjectFormat{} } + +func NewSha1() *Sha1Hash { + return &Sha1Hash{} +} + +// generic implementations +func NewHash(hash string) (ObjectID, error) { + hash = strings.ToLower(hash) + switch hash { + case "sha1": + return &Sha1Hash{}, nil + } + + return nil, errors.New("unsupported hash type") +} + +func IDFromRaw(h ObjectFormat, b []byte) (ObjectID, error) { + if len(b) != h.FullLength()/2 { + return h.Empty(), fmt.Errorf("length must be %d: %v", h.FullLength(), b) + } + return h.MustID(b), nil +} + +func MustIDFromString(h ObjectFormat, s string) ObjectID { + b, _ := hex.DecodeString(s) + return h.MustID(b) +} + +func genericIDFromString(h ObjectFormat, s string) (ObjectID, error) { + s = strings.TrimSpace(s) + if len(s) != h.FullLength() { + return h.Empty(), fmt.Errorf("length must be %d: %s", h.FullLength(), s) + } + b, err := hex.DecodeString(s) + if err != nil { + return h.Empty(), err + } + return h.NewID(b) +} + +// utils +func IDFromString(hexHash string) (ObjectID, error) { + switch len(hexHash) { + case 40: + hashType := Sha1ObjectFormat{} + h, err := hashType.NewIDFromString(hexHash) + if err != nil { + return nil, err + } + return h, nil + } + + return nil, fmt.Errorf("invalid hash hex string: '%s' len: %d", hexHash, len(hexHash)) +} + +func IsEmptyCommitID(commitID string) bool { + if commitID == "" { + return true + } + + id, err := IDFromString(commitID) + if err != nil { + return false + } + + return id.IsZero() +} + +// HashInterface is a struct that will generate a Hash +type HasherInterface interface { + hash.Hash + + HashSum() ObjectID +} + +type Sha1Hasher struct { + hash.Hash +} + +// ComputeBlobHash compute the hash for a given blob content +func ComputeBlobHash(hashType ObjectFormat, content []byte) ObjectID { + return ComputeHash(hashType, ObjectBlob, content) +} + +// ComputeHash compute the hash for a given ObjectType and content +func ComputeHash(hashType ObjectFormat, t ObjectType, content []byte) ObjectID { + h := hashType.NewHasher() + _, _ = h.Write(t.Bytes()) + _, _ = h.Write([]byte(" ")) + _, _ = h.Write([]byte(strconv.FormatInt(int64(len(content)), 10))) + _, _ = h.Write([]byte{0}) + return h.HashSum() +} + +// Sum generates a SHA1 for the provided hash +func (h *Sha1Hasher) HashSum() ObjectID { + var sha1 Sha1Hash + copy(sha1[:], h.Hash.Sum(nil)) + return &sha1 +} + +type ErrInvalidSHA struct { + SHA string +} + +func (err ErrInvalidSHA) Error() string { + return fmt.Sprintf("invalid sha: %s", err.SHA) +} diff --git a/modules/git/object_id_gogit.go b/modules/git/object_id_gogit.go new file mode 100644 index 0000000000000..50917f0552d54 --- /dev/null +++ b/modules/git/object_id_gogit.go @@ -0,0 +1,28 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT +//go:build gogit + +package git + +import ( + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/hash" +) + +func ParseGogitHash(h plumbing.Hash) ObjectID { + switch hash.Size { + case 20: + return ObjectFormatFromID(Sha1).MustID(h[:]) + } + + return nil +} + +func ParseGogitHashArray(objectIDs []plumbing.Hash) []ObjectID { + ret := make([]ObjectID, len(objectIDs)) + for i, h := range objectIDs { + ret[i] = ParseGogitHash(h) + } + + return ret +} diff --git a/modules/git/object_id_test.go b/modules/git/object_id_test.go new file mode 100644 index 0000000000000..c78a215755396 --- /dev/null +++ b/modules/git/object_id_test.go @@ -0,0 +1,21 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package git + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIsValidSHAPattern(t *testing.T) { + h := NewSha1().Type() + assert.True(t, h.IsValid("fee1")) + assert.True(t, h.IsValid("abc000")) + assert.True(t, h.IsValid("9023902390239023902390239023902390239023")) + assert.False(t, h.IsValid("90239023902390239023902390239023902390239023")) + assert.False(t, h.IsValid("abc")) + assert.False(t, h.IsValid("123g")) + assert.False(t, h.IsValid("some random text")) +} diff --git a/modules/git/parse_gogit.go b/modules/git/parse_gogit.go index 226ef5df7319f..6c22ea8da7bf5 100644 --- a/modules/git/parse_gogit.go +++ b/modules/git/parse_gogit.go @@ -11,12 +11,14 @@ import ( "strconv" "strings" + "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/filemode" + "github.com/go-git/go-git/v5/plumbing/hash" "github.com/go-git/go-git/v5/plumbing/object" ) // ParseTreeEntries parses the output of a `git ls-tree -l` command. -func ParseTreeEntries(data []byte) ([]*TreeEntry, error) { +func ParseTreeEntries(h ObjectFormat, data []byte) ([]*TreeEntry, error) { return parseTreeEntries(data, nil) } @@ -50,15 +52,16 @@ func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) { return nil, fmt.Errorf("unknown type: %v", string(data[pos:pos+6])) } - if pos+40 > len(data) { + // in hex format, not byte format .... + if pos+hash.Size*2 > len(data) { return nil, fmt.Errorf("Invalid ls-tree output: %s", string(data)) } - id, err := NewIDFromString(string(data[pos : pos+40])) + var err error + entry.ID, err = IDFromString(string(data[pos : pos+hash.Size*2])) if err != nil { - return nil, fmt.Errorf("Invalid ls-tree output: %w", err) + return nil, fmt.Errorf("invalid ls-tree output: %w", err) } - entry.ID = id - entry.gogitTreeEntry.Hash = id + entry.gogitTreeEntry.Hash = plumbing.Hash(entry.ID.RawValue()) pos += 41 // skip over sha and trailing space end := pos + bytes.IndexByte(data[pos:], '\t') @@ -77,6 +80,7 @@ func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) { // In case entry name is surrounded by double quotes(it happens only in git-shell). if data[pos] == '"' { + var err error entry.gogitTreeEntry.Name, err = strconv.Unquote(string(data[pos:end])) if err != nil { return nil, fmt.Errorf("Invalid ls-tree output: %w", err) diff --git a/modules/git/parse_gogit_test.go b/modules/git/parse_gogit_test.go index f6e32401e66eb..7ba50cbff90d4 100644 --- a/modules/git/parse_gogit_test.go +++ b/modules/git/parse_gogit_test.go @@ -6,8 +6,10 @@ package git import ( + "fmt" "testing" + "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/filemode" "github.com/go-git/go-git/v5/plumbing/object" "github.com/stretchr/testify/assert" @@ -26,9 +28,9 @@ func TestParseTreeEntries(t *testing.T) { Input: "100644 blob 61ab7345a1a3bbc590068ccae37b8515cfc5843c 1022\texample/file2.txt\n", Expected: []*TreeEntry{ { - ID: MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), + ID: ObjectFormatFromID(Sha1).MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), gogitTreeEntry: &object.TreeEntry{ - Hash: MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), + Hash: plumbing.Hash(ObjectFormatFromID(Sha1).MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c").RawValue()), Name: "example/file2.txt", Mode: filemode.Regular, }, @@ -42,9 +44,9 @@ func TestParseTreeEntries(t *testing.T) { "040000 tree 1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8 -\texample\n", Expected: []*TreeEntry{ { - ID: MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), + ID: ObjectFormatFromID(Sha1).MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), gogitTreeEntry: &object.TreeEntry{ - Hash: MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), + Hash: plumbing.Hash(ObjectFormatFromID(Sha1).MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c").RawValue()), Name: "example/\n.txt", Mode: filemode.Symlink, }, @@ -52,10 +54,10 @@ func TestParseTreeEntries(t *testing.T) { sized: true, }, { - ID: MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8"), + ID: ObjectFormatFromID(Sha1).MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8"), sized: true, gogitTreeEntry: &object.TreeEntry{ - Hash: MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8"), + Hash: plumbing.Hash(ObjectFormatFromID(Sha1).MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8").RawValue()), Name: "example", Mode: filemode.Dir, }, @@ -65,8 +67,12 @@ func TestParseTreeEntries(t *testing.T) { } for _, testCase := range testCases { - entries, err := ParseTreeEntries([]byte(testCase.Input)) + entries, err := ParseTreeEntries(ObjectFormatFromID(Sha1), []byte(testCase.Input)) assert.NoError(t, err) + if len(entries) > 1 { + fmt.Println(testCase.Expected[0].ID) + fmt.Println(entries[0].ID) + } assert.EqualValues(t, testCase.Expected, entries) } } diff --git a/modules/git/parse_nogogit.go b/modules/git/parse_nogogit.go index 8b94c69200c01..e35704eb34e9c 100644 --- a/modules/git/parse_nogogit.go +++ b/modules/git/parse_nogogit.go @@ -17,13 +17,13 @@ import ( ) // ParseTreeEntries parses the output of a `git ls-tree -l` command. -func ParseTreeEntries(data []byte) ([]*TreeEntry, error) { - return parseTreeEntries(data, nil) +func ParseTreeEntries(objectFormat ObjectFormat, data []byte) ([]*TreeEntry, error) { + return parseTreeEntries(objectFormat, data, nil) } var sepSpace = []byte{' '} -func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) { +func parseTreeEntries(objectFormat ObjectFormat, data []byte, ptree *Tree) ([]*TreeEntry, error) { var err error entries := make([]*TreeEntry, 0, bytes.Count(data, []byte{'\n'})+1) for pos := 0; pos < len(data); { @@ -72,7 +72,7 @@ func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) { return nil, fmt.Errorf("unknown type: %v", string(entryMode)) } - entry.ID, err = NewIDFromString(string(entryObjectID)) + entry.ID, err = objectFormat.NewIDFromString(string(entryObjectID)) if err != nil { return nil, fmt.Errorf("invalid ls-tree output (invalid object id): %q, err: %w", line, err) } @@ -92,15 +92,15 @@ func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) { return entries, nil } -func catBatchParseTreeEntries(ptree *Tree, rd *bufio.Reader, sz int64) ([]*TreeEntry, error) { +func catBatchParseTreeEntries(objectFormat ObjectFormat, ptree *Tree, rd *bufio.Reader, sz int64) ([]*TreeEntry, error) { fnameBuf := make([]byte, 4096) modeBuf := make([]byte, 40) - shaBuf := make([]byte, 40) + shaBuf := make([]byte, objectFormat.FullLength()) entries := make([]*TreeEntry, 0, 10) loop: for sz > 0 { - mode, fname, sha, count, err := ParseTreeLine(rd, modeBuf, fnameBuf, shaBuf) + mode, fname, sha, count, err := ParseTreeLine(objectFormat, rd, modeBuf, fnameBuf, shaBuf) if err != nil { if err == io.EOF { break loop @@ -127,7 +127,7 @@ loop: return nil, fmt.Errorf("unknown mode: %v", string(mode)) } - entry.ID = MustID(sha) + entry.ID = objectFormat.MustID(sha) entry.name = string(fname) entries = append(entries, entry) } diff --git a/modules/git/parse_nogogit_test.go b/modules/git/parse_nogogit_test.go index 23fddb014c1bf..0b78c081cd6f7 100644 --- a/modules/git/parse_nogogit_test.go +++ b/modules/git/parse_nogogit_test.go @@ -12,6 +12,8 @@ import ( ) func TestParseTreeEntriesLong(t *testing.T) { + objectFormat := ObjectFormatFromID(Sha1) + testCases := []struct { Input string Expected []*TreeEntry @@ -24,28 +26,28 @@ func TestParseTreeEntriesLong(t *testing.T) { `, Expected: []*TreeEntry{ { - ID: MustIDFromString("ea0d83c9081af9500ac9f804101b3fd0a5c293af"), + ID: objectFormat.MustIDFromString("ea0d83c9081af9500ac9f804101b3fd0a5c293af"), name: "README.md", entryMode: EntryModeBlob, size: 8218, sized: true, }, { - ID: MustIDFromString("037f27dc9d353ae4fd50f0474b2194c593914e35"), + ID: objectFormat.MustIDFromString("037f27dc9d353ae4fd50f0474b2194c593914e35"), name: "README_ZH.md", entryMode: EntryModeBlob, size: 4681, sized: true, }, { - ID: MustIDFromString("9846a94f7e8350a916632929d0fda38c90dd2ca8"), + ID: objectFormat.MustIDFromString("9846a94f7e8350a916632929d0fda38c90dd2ca8"), name: "SECURITY.md", entryMode: EntryModeBlob, size: 429, sized: true, }, { - ID: MustIDFromString("84b90550547016f73c5dd3f50dea662389e67b6d"), + ID: objectFormat.MustIDFromString("84b90550547016f73c5dd3f50dea662389e67b6d"), name: "assets", entryMode: EntryModeTree, sized: true, @@ -54,7 +56,7 @@ func TestParseTreeEntriesLong(t *testing.T) { }, } for _, testCase := range testCases { - entries, err := ParseTreeEntries([]byte(testCase.Input)) + entries, err := ParseTreeEntries(objectFormat, []byte(testCase.Input)) assert.NoError(t, err) assert.Len(t, entries, len(testCase.Expected)) for i, entry := range entries { @@ -64,6 +66,8 @@ func TestParseTreeEntriesLong(t *testing.T) { } func TestParseTreeEntriesShort(t *testing.T) { + objectFormat := ObjectFormatFromID(Sha1) + testCases := []struct { Input string Expected []*TreeEntry @@ -74,12 +78,12 @@ func TestParseTreeEntriesShort(t *testing.T) { `, Expected: []*TreeEntry{ { - ID: MustIDFromString("ea0d83c9081af9500ac9f804101b3fd0a5c293af"), + ID: objectFormat.MustIDFromString("ea0d83c9081af9500ac9f804101b3fd0a5c293af"), name: "README.md", entryMode: EntryModeBlob, }, { - ID: MustIDFromString("84b90550547016f73c5dd3f50dea662389e67b6d"), + ID: objectFormat.MustIDFromString("84b90550547016f73c5dd3f50dea662389e67b6d"), name: "assets", entryMode: EntryModeTree, }, @@ -87,7 +91,7 @@ func TestParseTreeEntriesShort(t *testing.T) { }, } for _, testCase := range testCases { - entries, err := ParseTreeEntries([]byte(testCase.Input)) + entries, err := ParseTreeEntries(objectFormat, []byte(testCase.Input)) assert.NoError(t, err) assert.Len(t, entries, len(testCase.Expected)) for i, entry := range entries { @@ -98,7 +102,7 @@ func TestParseTreeEntriesShort(t *testing.T) { func TestParseTreeEntriesInvalid(t *testing.T) { // there was a panic: "runtime error: slice bounds out of range" when the input was invalid: #20315 - entries, err := ParseTreeEntries([]byte("100644 blob ea0d83c9081af9500ac9f804101b3fd0a5c293af")) + entries, err := ParseTreeEntries(ObjectFormatFromID(Sha1), []byte("100644 blob ea0d83c9081af9500ac9f804101b3fd0a5c293af")) assert.Error(t, err) assert.Len(t, entries, 0) } diff --git a/modules/git/pipeline/lfs.go b/modules/git/pipeline/lfs.go index ee0505f29f909..6dfca24f29a4f 100644 --- a/modules/git/pipeline/lfs.go +++ b/modules/git/pipeline/lfs.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/modules/git" gogit "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" ) @@ -26,7 +27,7 @@ type LFSResult struct { SHA string Summary string When time.Time - ParentHashes []git.SHA1 + ParentHashes []git.ObjectID BranchName string FullCommitName string } @@ -38,7 +39,7 @@ func (a lfsResultSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a lfsResultSlice) Less(i, j int) bool { return a[j].When.After(a[i].When) } // FindLFSFile finds commits that contain a provided pointer file hash -func FindLFSFile(repo *git.Repository, hash git.SHA1) ([]*LFSResult, error) { +func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, error) { resultsMap := map[string]*LFSResult{} results := make([]*LFSResult, 0) @@ -65,13 +66,18 @@ func FindLFSFile(repo *git.Repository, hash git.SHA1) ([]*LFSResult, error) { if err == io.EOF { break } - if entry.Hash == hash { + if entry.Hash == plumbing.Hash(objectID.RawValue()) { + parents := make([]git.ObjectID, len(gitCommit.ParentHashes)) + for i, parentCommitID := range gitCommit.ParentHashes { + parents[i] = git.ParseGogitHash(parentCommitID) + } + result := LFSResult{ Name: name, SHA: gitCommit.Hash.String(), Summary: strings.Split(strings.TrimSpace(gitCommit.Message), "\n")[0], When: gitCommit.Author.When, - ParentHashes: gitCommit.ParentHashes, + ParentHashes: parents, } resultsMap[gitCommit.Hash.String()+":"+name] = &result } diff --git a/modules/git/pipeline/lfs_nogogit.go b/modules/git/pipeline/lfs_nogogit.go index 49390f7c00c66..89cbf740ffa9e 100644 --- a/modules/git/pipeline/lfs_nogogit.go +++ b/modules/git/pipeline/lfs_nogogit.go @@ -24,7 +24,7 @@ type LFSResult struct { SHA string Summary string When time.Time - ParentHashes []git.SHA1 + ParentIDs []git.ObjectID BranchName string FullCommitName string } @@ -36,7 +36,7 @@ func (a lfsResultSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a lfsResultSlice) Less(i, j int) bool { return a[j].When.After(a[i].When) } // FindLFSFile finds commits that contain a provided pointer file hash -func FindLFSFile(repo *git.Repository, hash git.SHA1) ([]*LFSResult, error) { +func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, error) { resultsMap := map[string]*LFSResult{} results := make([]*LFSResult, 0) @@ -75,7 +75,7 @@ func FindLFSFile(repo *git.Repository, hash git.SHA1) ([]*LFSResult, error) { fnameBuf := make([]byte, 4096) modeBuf := make([]byte, 40) - workingShaBuf := make([]byte, 20) + workingShaBuf := make([]byte, objectID.Type().FullLength()/2) for scan.Scan() { // Get the next commit ID @@ -115,7 +115,11 @@ func FindLFSFile(repo *git.Repository, hash git.SHA1) ([]*LFSResult, error) { continue case "commit": // Read in the commit to get its tree and in case this is one of the last used commits - curCommit, err = git.CommitFromReader(repo, git.MustIDFromString(string(commitID)), io.LimitReader(batchReader, size)) + objectFormat, err := repo.GetObjectFormat() + if err != nil { + return nil, err + } + curCommit, err = git.CommitFromReader(repo, objectFormat.MustIDFromString(string(commitID)), io.LimitReader(batchReader, size)) if err != nil { return nil, err } @@ -123,32 +127,31 @@ func FindLFSFile(repo *git.Repository, hash git.SHA1) ([]*LFSResult, error) { return nil, err } - _, err := batchStdinWriter.Write([]byte(curCommit.Tree.ID.String() + "\n")) - if err != nil { + if _, err := batchStdinWriter.Write([]byte(curCommit.Tree.ID.String() + "\n")); err != nil { return nil, err } curPath = "" case "tree": var n int64 for n < size { - mode, fname, sha20byte, count, err := git.ParseTreeLine(batchReader, modeBuf, fnameBuf, workingShaBuf) + mode, fname, binObjectID, count, err := git.ParseTreeLine(objectID.Type(), batchReader, modeBuf, fnameBuf, workingShaBuf) if err != nil { return nil, err } n += int64(count) - if bytes.Equal(sha20byte, hash[:]) { + if bytes.Equal(binObjectID, objectID.RawValue()) { result := LFSResult{ - Name: curPath + string(fname), - SHA: curCommit.ID.String(), - Summary: strings.Split(strings.TrimSpace(curCommit.CommitMessage), "\n")[0], - When: curCommit.Author.When, - ParentHashes: curCommit.Parents, + Name: curPath + string(fname), + SHA: curCommit.ID.String(), + Summary: strings.Split(strings.TrimSpace(curCommit.CommitMessage), "\n")[0], + When: curCommit.Author.When, + ParentIDs: curCommit.Parents, } resultsMap[curCommit.ID.String()+":"+curPath+string(fname)] = &result } else if string(mode) == git.EntryModeTree.String() { - sha40Byte := make([]byte, 40) - git.To40ByteSHA(sha20byte, sha40Byte) - trees = append(trees, sha40Byte) + hexObjectID := make([]byte, objectID.Type().FullLength()) + git.BinToHex(objectID.Type(), binObjectID, hexObjectID) + trees = append(trees, hexObjectID) paths = append(paths, curPath+string(fname)+"/") } } @@ -180,8 +183,8 @@ func FindLFSFile(repo *git.Repository, hash git.SHA1) ([]*LFSResult, error) { for _, result := range resultsMap { hasParent := false - for _, parentHash := range result.ParentHashes { - if _, hasParent = resultsMap[parentHash.String()+":"+result.Name]; hasParent { + for _, parentID := range result.ParentIDs { + if _, hasParent = resultsMap[parentID.String()+":"+result.Name]; hasParent { break } } diff --git a/modules/git/ref.go b/modules/git/ref.go index ad251515e7dbb..b96b4ababb412 100644 --- a/modules/git/ref.go +++ b/modules/git/ref.go @@ -44,7 +44,7 @@ func SanitizeRefPattern(name string) string { type Reference struct { Name string repo *Repository - Object SHA1 // The id of this commit object + Object ObjectID // The id of this commit object Type string } @@ -205,7 +205,7 @@ func RefURL(repoURL, ref string) string { return repoURL + "/src/branch/" + refName case refFullName.IsTag(): return repoURL + "/src/tag/" + refName - case !IsValidSHAPattern(ref): + case !ObjectFormatFromID(Sha1).IsValid(ref): // assume they mean a branch return repoURL + "/src/branch/" + refName default: diff --git a/modules/git/repo.go b/modules/git/repo.go index 32f0e7007eb0b..871d267a5b84c 100644 --- a/modules/git/repo.go +++ b/modules/git/repo.go @@ -7,6 +7,7 @@ package git import ( "bytes" "context" + "errors" "fmt" "io" "net/url" @@ -62,14 +63,40 @@ func IsRepoURLAccessible(ctx context.Context, url string) bool { return err == nil } +// GetObjectFormatOfRepo returns the hash type of a repository at a given path +func GetObjectFormatOfRepo(ctx context.Context, repoPath string) (ObjectFormat, error) { + var stdout, stderr strings.Builder + + err := NewCommand(ctx, "hash-object", "--stdin").Run(&RunOpts{ + Dir: repoPath, + Stdout: &stdout, + Stderr: &stderr, + Stdin: &strings.Reader{}, + }) + if err != nil { + return nil, err + } + + if stderr.Len() > 0 { + return nil, errors.New(stderr.String()) + } + + h, err := IDFromString(strings.TrimRight(stdout.String(), "\n")) + if err != nil { + return nil, err + } + + return h.Type(), nil +} + // InitRepository initializes a new Git repository. -func InitRepository(ctx context.Context, repoPath string, bare bool) error { +func InitRepository(ctx context.Context, repoPath string, bare bool, objectFormat ObjectFormat) error { err := os.MkdirAll(repoPath, os.ModePerm) if err != nil { return err } - cmd := NewCommand(ctx, "init") + cmd := NewCommand(ctx, "init", "--object-format").AddDynamicArguments(objectFormat.String()) if bare { cmd.AddArguments("--bare") } diff --git a/modules/git/repo_base_gogit.go b/modules/git/repo_base_gogit.go index ef59ead9003b8..d0b8e79368420 100644 --- a/modules/git/repo_base_gogit.go +++ b/modules/git/repo_base_gogit.go @@ -16,6 +16,7 @@ import ( "github.com/go-git/go-billy/v5/osfs" gogit "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/cache" "github.com/go-git/go-git/v5/storage/filesystem" ) @@ -32,6 +33,7 @@ type Repository struct { Ctx context.Context LastCommitCache *LastCommitCache + objectFormat ObjectFormat } // openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext. @@ -68,6 +70,7 @@ func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) { gogitStorage: storage, tagCache: newObjectCache(), Ctx: ctx, + objectFormat: ParseGogitHash(plumbing.ZeroHash).Type(), }, nil } diff --git a/modules/git/repo_base_nogogit.go b/modules/git/repo_base_nogogit.go index 414e4eb1a83de..a783366cc1f0c 100644 --- a/modules/git/repo_base_nogogit.go +++ b/modules/git/repo_base_nogogit.go @@ -33,6 +33,8 @@ type Repository struct { Ctx context.Context LastCommitCache *LastCommitCache + + objectFormat ObjectFormat } // openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext. @@ -63,6 +65,11 @@ func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) { repo.batchWriter, repo.batchReader, repo.batchCancel = CatFileBatch(ctx, repoPath) repo.checkWriter, repo.checkReader, repo.checkCancel = CatFileBatchCheck(ctx, repoPath) + repo.objectFormat, err = repo.GetObjectFormat() + if err != nil { + return nil, err + } + return repo, nil } diff --git a/modules/git/repo_blob.go b/modules/git/repo_blob.go index 698b6c7074a68..b5447b2bb131a 100644 --- a/modules/git/repo_blob.go +++ b/modules/git/repo_blob.go @@ -5,7 +5,7 @@ package git // GetBlob finds the blob object in the repository. func (repo *Repository) GetBlob(idStr string) (*Blob, error) { - id, err := NewIDFromString(idStr) + id, err := repo.objectFormat.NewIDFromString(idStr) if err != nil { return nil, err } diff --git a/modules/git/repo_blob_gogit.go b/modules/git/repo_blob_gogit.go index 7f0892f6f5e91..66c8c2775ce54 100644 --- a/modules/git/repo_blob_gogit.go +++ b/modules/git/repo_blob_gogit.go @@ -9,8 +9,8 @@ import ( "github.com/go-git/go-git/v5/plumbing" ) -func (repo *Repository) getBlob(id SHA1) (*Blob, error) { - encodedObj, err := repo.gogitRepo.Storer.EncodedObject(plumbing.AnyObject, id) +func (repo *Repository) getBlob(id ObjectID) (*Blob, error) { + encodedObj, err := repo.gogitRepo.Storer.EncodedObject(plumbing.AnyObject, plumbing.Hash(id.RawValue())) if err != nil { return nil, ErrNotExist{id.String(), ""} } diff --git a/modules/git/repo_blob_nogogit.go b/modules/git/repo_blob_nogogit.go index 184a2bc9dd0c2..04b0fb00ff734 100644 --- a/modules/git/repo_blob_nogogit.go +++ b/modules/git/repo_blob_nogogit.go @@ -5,7 +5,7 @@ package git -func (repo *Repository) getBlob(id SHA1) (*Blob, error) { +func (repo *Repository) getBlob(id ObjectID) (*Blob, error) { if id.IsZero() { return nil, ErrNotExist{id.String(), ""} } diff --git a/modules/git/repo_blob_test.go b/modules/git/repo_blob_test.go index 026c73a283360..e122573954180 100644 --- a/modules/git/repo_blob_test.go +++ b/modules/git/repo_blob_test.go @@ -61,7 +61,7 @@ func TestRepository_GetBlob_NoId(t *testing.T) { defer r.Close() testCase := "" - testError := fmt.Errorf("Length must be 40: %s", testCase) + testError := fmt.Errorf("length must be 40: %s", testCase) blob, err := r.GetBlob(testCase) assert.Nil(t, blob) diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go index 6b06fef656ec6..58bbcf9303f2c 100644 --- a/modules/git/repo_commit.go +++ b/modules/git/repo_commit.go @@ -6,8 +6,6 @@ package git import ( "bytes" - "encoding/hex" - "fmt" "io" "strconv" "strings" @@ -28,7 +26,7 @@ func (repo *Repository) GetTagCommitID(name string) (string, error) { // GetCommit returns commit object of by ID string. func (repo *Repository) GetCommit(commitID string) (*Commit, error) { - id, err := repo.ConvertToSHA1(commitID) + id, err := repo.ConvertToGitID(commitID) if err != nil { return nil, err } @@ -54,7 +52,7 @@ func (repo *Repository) GetTagCommit(name string) (*Commit, error) { return repo.GetCommit(commitID) } -func (repo *Repository) getCommitByPathWithID(id SHA1, relpath string) (*Commit, error) { +func (repo *Repository) getCommitByPathWithID(id ObjectID, relpath string) (*Commit, error) { // File name starts with ':' must be escaped. if relpath[0] == ':' { relpath = `\` + relpath @@ -65,7 +63,7 @@ func (repo *Repository) getCommitByPathWithID(id SHA1, relpath string) (*Commit, return nil, runErr } - id, err := NewIDFromString(stdout) + id, err := repo.objectFormat.NewIDFromString(stdout) if err != nil { return nil, err } @@ -90,7 +88,7 @@ func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) { return commits[0], nil } -func (repo *Repository) commitsByRange(id SHA1, page, pageSize int, not string) ([]*Commit, error) { +func (repo *Repository) commitsByRange(id ObjectID, page, pageSize int, not string) ([]*Commit, error) { cmd := NewCommand(repo.Ctx, "log"). AddOptionFormat("--skip=%d", (page-1)*pageSize). AddOptionFormat("--max-count=%d", pageSize). @@ -109,7 +107,7 @@ func (repo *Repository) commitsByRange(id SHA1, page, pageSize int, not string) return repo.parsePrettyFormatLogToList(stdout) } -func (repo *Repository) searchCommits(id SHA1, opts SearchCommitsOptions) ([]*Commit, error) { +func (repo *Repository) searchCommits(id ObjectID, opts SearchCommitsOptions) ([]*Commit, error) { // add common arguments to git command addCommonSearchArgs := func(c *Command) { // ignore case @@ -164,7 +162,7 @@ func (repo *Repository) searchCommits(id SHA1, opts SearchCommitsOptions) ([]*Co // then let's iterate over them for _, v := range opts.Keywords { // ignore anything not matching a valid sha pattern - if IsValidSHAPattern(v) { + if id.Type().IsValid(v) { // create new git log command with 1 commit limit hashCmd := NewCommand(repo.Ctx, "log", "-1", prettyLogFormat) // add previous arguments except for --grep and --all @@ -245,25 +243,22 @@ func (repo *Repository) CommitsByFileAndRange(opts CommitsByFileAndRangeOptions) } }() + len := repo.objectFormat.FullLength() commits := []*Commit{} - shaline := [41]byte{} - var sha1 SHA1 + shaline := make([]byte, len+1) for { - n, err := io.ReadFull(stdoutReader, shaline[:]) - if err != nil || n < 40 { + n, err := io.ReadFull(stdoutReader, shaline) + if err != nil || n < len { if err == io.EOF { err = nil } return commits, err } - n, err = hex.Decode(sha1[:], shaline[0:40]) - if n != 20 { - err = fmt.Errorf("invalid sha %q", string(shaline[:40])) - } + objectID, err := repo.objectFormat.NewIDFromString(string(shaline[0:len])) if err != nil { return nil, err } - commit, err := repo.getCommit(sha1) + commit, err := repo.getCommit(objectID) if err != nil { return nil, err } @@ -392,7 +387,7 @@ func (repo *Repository) CommitsCountBetween(start, end string) (int64, error) { } // commitsBefore the limit is depth, not total number of returned commits. -func (repo *Repository) commitsBefore(id SHA1, limit int) ([]*Commit, error) { +func (repo *Repository) commitsBefore(id ObjectID, limit int) ([]*Commit, error) { cmd := NewCommand(repo.Ctx, "log", prettyLogFormat) if limit > 0 { cmd.AddOptionFormat("-%d", limit) @@ -426,11 +421,11 @@ func (repo *Repository) commitsBefore(id SHA1, limit int) ([]*Commit, error) { return commits, nil } -func (repo *Repository) getCommitsBefore(id SHA1) ([]*Commit, error) { +func (repo *Repository) getCommitsBefore(id ObjectID) ([]*Commit, error) { return repo.commitsBefore(id, 0) } -func (repo *Repository) getCommitsBeforeLimit(id SHA1, num int) ([]*Commit, error) { +func (repo *Repository) getCommitsBeforeLimit(id ObjectID, num int) ([]*Commit, error) { return repo.commitsBefore(id, num) } diff --git a/modules/git/repo_commit_gogit.go b/modules/git/repo_commit_gogit.go index ce0af936140db..893055bccdf6b 100644 --- a/modules/git/repo_commit_gogit.go +++ b/modules/git/repo_commit_gogit.go @@ -10,6 +10,7 @@ import ( "strings" "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/hash" "github.com/go-git/go-git/v5/plumbing/object" ) @@ -38,40 +39,46 @@ func (repo *Repository) RemoveReference(name string) error { return repo.gogitRepo.Storer.RemoveReference(plumbing.ReferenceName(name)) } -// ConvertToSHA1 returns a Hash object from a potential ID string -func (repo *Repository) ConvertToSHA1(commitID string) (SHA1, error) { - if len(commitID) == SHAFullLength { - sha1, err := NewIDFromString(commitID) +// ConvertToHash returns a Hash object from a potential ID string +func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) { + objectFormat := repo.objectFormat + if len(commitID) == hash.HexSize && objectFormat.IsValid(commitID) { + ID, err := objectFormat.NewIDFromString(commitID) if err == nil { - return sha1, nil + return ID, nil } } actualCommitID, _, err := NewCommand(repo.Ctx, "rev-parse", "--verify").AddDynamicArguments(commitID).RunStdString(&RunOpts{Dir: repo.Path}) + actualCommitID = strings.TrimSpace(actualCommitID) if err != nil { if strings.Contains(err.Error(), "unknown revision or path") || strings.Contains(err.Error(), "fatal: Needed a single revision") { - return SHA1{}, ErrNotExist{commitID, ""} + return objectFormat.Empty(), ErrNotExist{commitID, ""} } - return SHA1{}, err + return objectFormat.Empty(), err } - return NewIDFromString(actualCommitID) + return objectFormat.NewIDFromString(actualCommitID) } // IsCommitExist returns true if given commit exists in current repository. func (repo *Repository) IsCommitExist(name string) bool { - hash := plumbing.NewHash(name) - _, err := repo.gogitRepo.CommitObject(hash) + hash, err := repo.ConvertToGitID(name) + if err != nil { + return false + } + _, err = repo.gogitRepo.CommitObject(plumbing.Hash(hash.RawValue())) return err == nil } -func (repo *Repository) getCommit(id SHA1) (*Commit, error) { +func (repo *Repository) getCommit(id ObjectID) (*Commit, error) { var tagObject *object.Tag - gogitCommit, err := repo.gogitRepo.CommitObject(id) + commitID := plumbing.Hash(id.RawValue()) + gogitCommit, err := repo.gogitRepo.CommitObject(commitID) if err == plumbing.ErrObjectNotFound { - tagObject, err = repo.gogitRepo.TagObject(id) + tagObject, err = repo.gogitRepo.TagObject(commitID) if err == plumbing.ErrObjectNotFound { return nil, ErrNotExist{ ID: id.String(), @@ -94,7 +101,7 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) { return nil, err } - commit.Tree.ID = tree.Hash + commit.Tree.ID = ParseGogitHash(tree.Hash) commit.Tree.gogitTree = tree return commit, nil diff --git a/modules/git/repo_commit_nogogit.go b/modules/git/repo_commit_nogogit.go index d5eb723100a73..018e271c394ef 100644 --- a/modules/git/repo_commit_nogogit.go +++ b/modules/git/repo_commit_nogogit.go @@ -65,7 +65,7 @@ func (repo *Repository) IsCommitExist(name string) bool { return err == nil } -func (repo *Repository) getCommit(id SHA1) (*Commit, error) { +func (repo *Repository) getCommit(id ObjectID) (*Commit, error) { wr, rd, cancel := repo.CatFileBatch(repo.Ctx) defer cancel() @@ -74,7 +74,7 @@ func (repo *Repository) getCommit(id SHA1) (*Commit, error) { return repo.getCommitFromBatchReader(rd, id) } -func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Commit, error) { +func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id ObjectID) (*Commit, error) { _, typ, size, err := ReadBatchLine(rd) if err != nil { if errors.Is(err, io.EOF) || IsErrNotExist(err) { @@ -97,7 +97,7 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Co if err != nil { return nil, err } - tag, err := parseTagData(data) + tag, err := parseTagData(id.Type(), data) if err != nil { return nil, err } @@ -131,12 +131,13 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Co } } -// ConvertToSHA1 returns a Hash object from a potential ID string -func (repo *Repository) ConvertToSHA1(commitID string) (SHA1, error) { - if len(commitID) == SHAFullLength && IsValidSHAPattern(commitID) { - sha1, err := NewIDFromString(commitID) +// ConvertToGitID returns a GitHash object from a potential ID string +func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) { + IDType := repo.objectFormat + if len(commitID) == IDType.FullLength() && IDType.IsValid(commitID) { + ID, err := repo.objectFormat.NewIDFromString(commitID) if err == nil { - return sha1, nil + return ID, nil } } @@ -144,15 +145,15 @@ func (repo *Repository) ConvertToSHA1(commitID string) (SHA1, error) { defer cancel() _, err := wr.Write([]byte(commitID + "\n")) if err != nil { - return SHA1{}, err + return nil, err } sha, _, _, err := ReadBatchLine(rd) if err != nil { if IsErrNotExist(err) { - return SHA1{}, ErrNotExist{commitID, ""} + return nil, ErrNotExist{commitID, ""} } - return SHA1{}, err + return nil, err } - return MustIDFromString(string(sha)), nil + return repo.objectFormat.MustIDFromString(string(sha)), nil } diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go index aad725fa9db89..8885df4f7088e 100644 --- a/modules/git/repo_compare.go +++ b/modules/git/repo_compare.go @@ -284,7 +284,7 @@ func (repo *Repository) GetPatch(base, head string, w io.Writer) error { // If base is the SHA of an empty tree (EmptyTreeSHA), it returns the files changes from the initial commit to the head commit func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, error) { cmd := NewCommand(repo.Ctx, "diff-tree", "--name-only", "--root", "--no-commit-id", "-r", "-z") - if base == EmptySHA { + if base == repo.objectFormat.Empty().String() { cmd.AddDynamicArguments(head) } else { cmd.AddDynamicArguments(base, head) diff --git a/modules/git/repo_compare_test.go b/modules/git/repo_compare_test.go index 603aabde42a09..9bfaa5c02a564 100644 --- a/modules/git/repo_compare_test.go +++ b/modules/git/repo_compare_test.go @@ -131,12 +131,12 @@ func TestGetCommitFilesChanged(t *testing.T) { files []string }{ { - EmptySHA, + repo.objectFormat.Empty().String(), "95bb4d39648ee7e325106df01a621c530863a653", []string{"file1.txt"}, }, { - EmptySHA, + repo.objectFormat.Empty().String(), "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2", []string{"file2.txt"}, }, @@ -146,7 +146,7 @@ func TestGetCommitFilesChanged(t *testing.T) { []string{"file2.txt"}, }, { - EmptyTreeSHA, + repo.objectFormat.EmptyTree().String(), "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2", []string{"file1.txt", "file2.txt"}, }, diff --git a/modules/git/repo_gpg.go b/modules/git/repo_gpg.go index 4803be58165f7..e2b45064fd38f 100644 --- a/modules/git/repo_gpg.go +++ b/modules/git/repo_gpg.go @@ -17,7 +17,7 @@ func (gpgSettings *GPGSettings) LoadPublicKeyContent() error { "gpg -a --export", "gpg", "-a", "--export", gpgSettings.KeyID) if err != nil { - return fmt.Errorf("Unable to get default signing key: %s, %s, %w", gpgSettings.KeyID, stderr, err) + return fmt.Errorf("unable to get default signing key: %s, %s, %w", gpgSettings.KeyID, stderr, err) } gpgSettings.PublicKeyContent = content return nil diff --git a/modules/git/repo_index.go b/modules/git/repo_index.go index 34dd1e0129158..6f43734655f35 100644 --- a/modules/git/repo_index.go +++ b/modules/git/repo_index.go @@ -16,7 +16,12 @@ import ( // ReadTreeToIndex reads a treeish to the index func (repo *Repository) ReadTreeToIndex(treeish string, indexFilename ...string) error { - if len(treeish) != SHAFullLength { + objectFormat, err := repo.GetObjectFormat() + if err != nil { + return err + } + + if len(treeish) != objectFormat.FullLength() { res, _, err := NewCommand(repo.Ctx, "rev-parse", "--verify").AddDynamicArguments(treeish).RunStdString(&RunOpts{Dir: repo.Path}) if err != nil { return err @@ -25,14 +30,14 @@ func (repo *Repository) ReadTreeToIndex(treeish string, indexFilename ...string) treeish = res[:len(res)-1] } } - id, err := NewIDFromString(treeish) + id, err := objectFormat.NewIDFromString(treeish) if err != nil { return err } return repo.readTreeToIndex(id, indexFilename...) } -func (repo *Repository) readTreeToIndex(id SHA1, indexFilename ...string) error { +func (repo *Repository) readTreeToIndex(id ObjectID, indexFilename ...string) error { var env []string if len(indexFilename) > 0 { env = append(os.Environ(), "GIT_INDEX_FILE="+indexFilename[0]) @@ -95,7 +100,9 @@ func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error { buffer := new(bytes.Buffer) for _, file := range filenames { if file != "" { - buffer.WriteString("0 0000000000000000000000000000000000000000\t") + buffer.WriteString("0 ") + buffer.WriteString(repo.objectFormat.Empty().String()) + buffer.WriteByte('\t') buffer.WriteString(file) buffer.WriteByte('\000') } @@ -109,7 +116,7 @@ func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error { } // AddObjectToIndex adds the provided object hash to the index at the provided filename -func (repo *Repository) AddObjectToIndex(mode string, object SHA1, filename string) error { +func (repo *Repository) AddObjectToIndex(mode string, object ObjectID, filename string) error { cmd := NewCommand(repo.Ctx, "update-index", "--add", "--replace", "--cacheinfo").AddDynamicArguments(mode, object.String(), filename) _, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path}) return err @@ -121,7 +128,7 @@ func (repo *Repository) WriteTree() (*Tree, error) { if runErr != nil { return nil, runErr } - id, err := NewIDFromString(strings.TrimSpace(stdout)) + id, err := repo.objectFormat.NewIDFromString(strings.TrimSpace(stdout)) if err != nil { return nil, err } diff --git a/modules/git/repo_language_stats_nogogit.go b/modules/git/repo_language_stats_nogogit.go index 1d94ad6c00f4b..b733c119f9e7c 100644 --- a/modules/git/repo_language_stats_nogogit.go +++ b/modules/git/repo_language_stats_nogogit.go @@ -39,7 +39,7 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err return nil, ErrNotExist{commitID, ""} } - sha, err := NewIDFromString(string(shaBytes)) + sha, err := repo.objectFormat.NewIDFromString(string(shaBytes)) if err != nil { log.Debug("Unable to get commit for: %s. Err: %v", commitID, err) return nil, ErrNotExist{commitID, ""} diff --git a/modules/git/repo_object.go b/modules/git/repo_object.go index 9edc201fead7e..220fdb38074de 100644 --- a/modules/git/repo_object.go +++ b/modules/git/repo_object.go @@ -31,17 +31,47 @@ func (o ObjectType) Bytes() []byte { return []byte(o) } -// HashObject takes a reader and returns SHA1 hash for that reader -func (repo *Repository) HashObject(reader io.Reader) (SHA1, error) { - idStr, err := repo.hashObject(reader) +type EmptyReader struct{} + +func (EmptyReader) Read(p []byte) (int, error) { + return 0, io.EOF +} + +func (repo *Repository) GetObjectFormat() (ObjectFormat, error) { + if repo != nil && repo.objectFormat != nil { + return repo.objectFormat, nil + } + + str, err := repo.hashObject(EmptyReader{}, false) + if err != nil { + return nil, err + } + hash, err := IDFromString(str) if err != nil { - return SHA1{}, err + return nil, err } - return NewIDFromString(idStr) + + repo.objectFormat = hash.Type() + + return repo.objectFormat, nil } -func (repo *Repository) hashObject(reader io.Reader) (string, error) { - cmd := NewCommand(repo.Ctx, "hash-object", "-w", "--stdin") +// HashObject takes a reader and returns hash for that reader +func (repo *Repository) HashObject(reader io.Reader) (ObjectID, error) { + idStr, err := repo.hashObject(reader, true) + if err != nil { + return nil, err + } + return repo.objectFormat.NewIDFromString(idStr) +} + +func (repo *Repository) hashObject(reader io.Reader, save bool) (string, error) { + var cmd *Command + if save { + cmd = NewCommand(repo.Ctx, "hash-object", "-w", "--stdin") + } else { + cmd = NewCommand(repo.Ctx, "hash-object", "--stdin") + } stdout := new(bytes.Buffer) stderr := new(bytes.Buffer) err := cmd.Run(&RunOpts{ diff --git a/modules/git/repo_ref_gogit.go b/modules/git/repo_ref_gogit.go index 8a68a4574f1bc..fc43ce5545d5b 100644 --- a/modules/git/repo_ref_gogit.go +++ b/modules/git/repo_ref_gogit.go @@ -30,13 +30,13 @@ func (repo *Repository) GetRefsFiltered(pattern string) ([]*Reference, error) { refType := string(ObjectCommit) if ref.Name().IsTag() { // tags can be of type `commit` (lightweight) or `tag` (annotated) - if tagType, _ := repo.GetTagType(ref.Hash()); err == nil { + if tagType, _ := repo.GetTagType(ParseGogitHash(ref.Hash())); err == nil { refType = tagType } } r := &Reference{ Name: ref.Name().String(), - Object: ref.Hash(), + Object: ParseGogitHash(ref.Hash()), Type: refType, repo: repo, } diff --git a/modules/git/repo_ref_nogogit.go b/modules/git/repo_ref_nogogit.go index ac53d661b517b..c1be60871cfe4 100644 --- a/modules/git/repo_ref_nogogit.go +++ b/modules/git/repo_ref_nogogit.go @@ -75,7 +75,7 @@ func (repo *Repository) GetRefsFiltered(pattern string) ([]*Reference, error) { if pattern == "" || strings.HasPrefix(refName, pattern) { r := &Reference{ Name: refName, - Object: MustIDFromString(sha), + Object: repo.objectFormat.MustIDFromString(sha), Type: typ, repo: repo, } diff --git a/modules/git/repo_tag.go b/modules/git/repo_tag.go index ae877f0211002..0b08e457cbe94 100644 --- a/modules/git/repo_tag.go +++ b/modules/git/repo_tag.go @@ -84,7 +84,7 @@ func (repo *Repository) GetTag(name string) (*Tag, error) { return nil, err } - id, err := NewIDFromString(idStr) + id, err := repo.objectFormat.NewIDFromString(idStr) if err != nil { return nil, err } @@ -98,7 +98,7 @@ func (repo *Repository) GetTag(name string) (*Tag, error) { // GetTagWithID returns a Git tag by given name and ID func (repo *Repository) GetTagWithID(idStr, name string) (*Tag, error) { - id, err := NewIDFromString(idStr) + id, err := repo.objectFormat.NewIDFromString(idStr) if err != nil { return nil, err } @@ -139,7 +139,7 @@ func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, int, error) { break } - tag, err := parseTagRef(ref) + tag, err := parseTagRef(repo.objectFormat, ref) if err != nil { return nil, 0, fmt.Errorf("GetTagInfos: parse tag: %w", err) } @@ -159,13 +159,13 @@ func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, int, error) { } // parseTagRef parses a tag from a 'git for-each-ref'-produced reference. -func parseTagRef(ref map[string]string) (tag *Tag, err error) { +func parseTagRef(objectFormat ObjectFormat, ref map[string]string) (tag *Tag, err error) { tag = &Tag{ Type: ref["objecttype"], Name: ref["refname:short"], } - tag.ID, err = NewIDFromString(ref["objectname"]) + tag.ID, err = objectFormat.NewIDFromString(ref["objectname"]) if err != nil { return nil, fmt.Errorf("parse objectname '%s': %w", ref["objectname"], err) } @@ -175,7 +175,7 @@ func parseTagRef(ref map[string]string) (tag *Tag, err error) { tag.Object = tag.ID } else { // annotated tag - tag.Object, err = NewIDFromString(ref["object"]) + tag.Object, err = objectFormat.NewIDFromString(ref["object"]) if err != nil { return nil, fmt.Errorf("parse object '%s': %w", ref["object"], err) } @@ -208,7 +208,7 @@ func parseTagRef(ref map[string]string) (tag *Tag, err error) { // GetAnnotatedTag returns a Git tag by its SHA, must be an annotated tag func (repo *Repository) GetAnnotatedTag(sha string) (*Tag, error) { - id, err := NewIDFromString(sha) + id, err := repo.objectFormat.NewIDFromString(sha) if err != nil { return nil, err } diff --git a/modules/git/repo_tag_gogit.go b/modules/git/repo_tag_gogit.go index 2bc75e7cf9b1d..c3711ba5a07d0 100644 --- a/modules/git/repo_tag_gogit.go +++ b/modules/git/repo_tag_gogit.go @@ -55,9 +55,9 @@ func (repo *Repository) GetTags(skip, limit int) ([]string, error) { } // GetTagType gets the type of the tag, either commit (simple) or tag (annotated) -func (repo *Repository) GetTagType(id SHA1) (string, error) { +func (repo *Repository) GetTagType(id ObjectID) (string, error) { // Get tag type - obj, err := repo.gogitRepo.Object(plumbing.AnyObject, id) + obj, err := repo.gogitRepo.Object(plumbing.AnyObject, plumbing.Hash(id.RawValue())) if err != nil { if err == plumbing.ErrReferenceNotFound { return "", &ErrNotExist{ID: id.String()} @@ -68,7 +68,7 @@ func (repo *Repository) GetTagType(id SHA1) (string, error) { return obj.Type().String(), nil } -func (repo *Repository) getTag(tagID SHA1, name string) (*Tag, error) { +func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) { t, ok := repo.tagCache.Get(tagID.String()) if ok { log.Debug("Hit cache: %s", tagID) @@ -88,7 +88,7 @@ func (repo *Repository) getTag(tagID SHA1, name string) (*Tag, error) { // every tag should have a commit ID so return all errors return nil, err } - commitID, err := NewIDFromString(commitIDStr) + commitID, err := IDFromString(commitIDStr) if err != nil { return nil, err } @@ -112,7 +112,7 @@ func (repo *Repository) getTag(tagID SHA1, name string) (*Tag, error) { return tag, nil } - gogitTag, err := repo.gogitRepo.TagObject(tagID) + gogitTag, err := repo.gogitRepo.TagObject(plumbing.Hash(tagID.RawValue())) if err != nil { if err == plumbing.ErrReferenceNotFound { return nil, &ErrNotExist{ID: tagID.String()} @@ -124,7 +124,7 @@ func (repo *Repository) getTag(tagID SHA1, name string) (*Tag, error) { tag := &Tag{ Name: name, ID: tagID, - Object: gogitTag.Target, + Object: commitID.Type().MustID(gogitTag.Target[:]), Type: tp, Tagger: &gogitTag.Tagger, Message: gogitTag.Message, diff --git a/modules/git/repo_tag_nogogit.go b/modules/git/repo_tag_nogogit.go index 9080ffcfd7820..3cea4894f17a2 100644 --- a/modules/git/repo_tag_nogogit.go +++ b/modules/git/repo_tag_nogogit.go @@ -30,7 +30,7 @@ func (repo *Repository) GetTags(skip, limit int) (tags []string, err error) { } // GetTagType gets the type of the tag, either commit (simple) or tag (annotated) -func (repo *Repository) GetTagType(id SHA1) (string, error) { +func (repo *Repository) GetTagType(id ObjectID) (string, error) { wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) defer cancel() _, err := wr.Write([]byte(id.String() + "\n")) @@ -44,7 +44,7 @@ func (repo *Repository) GetTagType(id SHA1) (string, error) { return typ, nil } -func (repo *Repository) getTag(tagID SHA1, name string) (*Tag, error) { +func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) { t, ok := repo.tagCache.Get(tagID.String()) if ok { log.Debug("Hit cache: %s", tagID) @@ -64,7 +64,7 @@ func (repo *Repository) getTag(tagID SHA1, name string) (*Tag, error) { // every tag should have a commit ID so return all errors return nil, err } - commitID, err := NewIDFromString(commitIDStr) + commitID, err := repo.objectFormat.NewIDFromString(commitIDStr) if err != nil { return nil, err } @@ -117,7 +117,7 @@ func (repo *Repository) getTag(tagID SHA1, name string) (*Tag, error) { return nil, err } - tag, err := parseTagData(data) + tag, err := parseTagData(tagID.Type(), data) if err != nil { return nil, err } diff --git a/modules/git/repo_tag_test.go b/modules/git/repo_tag_test.go index 4d94efd1acfb1..c7699f4a7d2c6 100644 --- a/modules/git/repo_tag_test.go +++ b/modules/git/repo_tag_test.go @@ -194,6 +194,7 @@ func TestRepository_GetAnnotatedTag(t *testing.T) { } func TestRepository_parseTagRef(t *testing.T) { + sha1 := ObjectFormatFromID(Sha1) tests := []struct { name string @@ -223,8 +224,8 @@ func TestRepository_parseTagRef(t *testing.T) { want: &Tag{ Name: "v1.9.1", - ID: MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), - Object: MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), + ID: sha1.MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), + Object: sha1.MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), Type: "commit", Tagger: parseAuthorLine(t, "Foo Bar 1565789218 +0300"), Message: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md\n", @@ -252,8 +253,8 @@ func TestRepository_parseTagRef(t *testing.T) { want: &Tag{ Name: "v0.0.1", - ID: MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), - Object: MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), + ID: sha1.MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), + Object: sha1.MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), Type: "tag", Tagger: parseAuthorLine(t, "Foo Bar 1565789218 +0300"), Message: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md\n", @@ -310,8 +311,8 @@ qbHDASXl want: &Tag{ Name: "v0.0.1", - ID: MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), - Object: MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), + ID: sha1.MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), + Object: sha1.MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), Type: "tag", Tagger: parseAuthorLine(t, "Foo Bar 1565789218 +0300"), Message: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md", @@ -350,7 +351,7 @@ Add changelog of v1.9.1 (#7859) for _, test := range tests { tc := test // don't close over loop variable t.Run(tc.name, func(t *testing.T) { - got, err := parseTagRef(tc.givenRef) + got, err := parseTagRef(sha1, tc.givenRef) if tc.wantErr { require.Error(t, err) diff --git a/modules/git/repo_tree.go b/modules/git/repo_tree.go index 63c33379bf5dc..9ee80351f0f61 100644 --- a/modules/git/repo_tree.go +++ b/modules/git/repo_tree.go @@ -21,7 +21,7 @@ type CommitTreeOpts struct { } // CommitTree creates a commit from a given tree id for the user with provided message -func (repo *Repository) CommitTree(author, committer *Signature, tree *Tree, opts CommitTreeOpts) (SHA1, error) { +func (repo *Repository) CommitTree(author, committer *Signature, tree *Tree, opts CommitTreeOpts) (ObjectID, error) { commitTimeStr := time.Now().Format(time.RFC3339) // Because this may call hooks we should pass in the environment @@ -61,7 +61,7 @@ func (repo *Repository) CommitTree(author, committer *Signature, tree *Tree, opt Stderr: stderr, }) if err != nil { - return SHA1{}, ConcatenateError(err, stderr.String()) + return nil, ConcatenateError(err, stderr.String()) } - return NewIDFromString(strings.TrimSpace(stdout.String())) + return repo.objectFormat.NewIDFromString(strings.TrimSpace(stdout.String())) } diff --git a/modules/git/repo_tree_gogit.go b/modules/git/repo_tree_gogit.go index a7b1081b15f18..415572e65a138 100644 --- a/modules/git/repo_tree_gogit.go +++ b/modules/git/repo_tree_gogit.go @@ -6,8 +6,10 @@ package git -func (repo *Repository) getTree(id SHA1) (*Tree, error) { - gogitTree, err := repo.gogitRepo.TreeObject(id) +import "github.com/go-git/go-git/v5/plumbing" + +func (repo *Repository) getTree(id ObjectID) (*Tree, error) { + gogitTree, err := repo.gogitRepo.TreeObject(plumbing.Hash(id.RawValue())) if err != nil { return nil, err } @@ -19,7 +21,7 @@ func (repo *Repository) getTree(id SHA1) (*Tree, error) { // GetTree find the tree object in the repository. func (repo *Repository) GetTree(idStr string) (*Tree, error) { - if len(idStr) != SHAFullLength { + if len(idStr) != repo.objectFormat.FullLength() { res, _, err := NewCommand(repo.Ctx, "rev-parse", "--verify").AddDynamicArguments(idStr).RunStdString(&RunOpts{Dir: repo.Path}) if err != nil { return nil, err @@ -28,14 +30,14 @@ func (repo *Repository) GetTree(idStr string) (*Tree, error) { idStr = res[:len(res)-1] } } - id, err := NewIDFromString(idStr) + id, err := repo.objectFormat.NewIDFromString(idStr) if err != nil { return nil, err } resolvedID := id - commitObject, err := repo.gogitRepo.CommitObject(id) + commitObject, err := repo.gogitRepo.CommitObject(plumbing.Hash(id.RawValue())) if err == nil { - id = SHA1(commitObject.TreeHash) + id = ParseGogitHash(commitObject.TreeHash) } treeObject, err := repo.getTree(id) if err != nil { diff --git a/modules/git/repo_tree_nogogit.go b/modules/git/repo_tree_nogogit.go index 4fd77df2b8249..f502cc140b7f9 100644 --- a/modules/git/repo_tree_nogogit.go +++ b/modules/git/repo_tree_nogogit.go @@ -9,7 +9,7 @@ import ( "io" ) -func (repo *Repository) getTree(id SHA1) (*Tree, error) { +func (repo *Repository) getTree(id ObjectID) (*Tree, error) { wr, rd, cancel := repo.CatFileBatch(repo.Ctx) defer cancel() @@ -28,7 +28,7 @@ func (repo *Repository) getTree(id SHA1) (*Tree, error) { if err != nil { return nil, err } - tag, err := parseTagData(data) + tag, err := parseTagData(id.Type(), data) if err != nil { return nil, err } @@ -51,7 +51,7 @@ func (repo *Repository) getTree(id SHA1) (*Tree, error) { case "tree": tree := NewTree(repo, id) tree.ResolvedID = id - tree.entries, err = catBatchParseTreeEntries(tree, rd, size) + tree.entries, err = catBatchParseTreeEntries(repo.objectFormat, tree, rd, size) if err != nil { return nil, err } @@ -66,7 +66,7 @@ func (repo *Repository) getTree(id SHA1) (*Tree, error) { // GetTree find the tree object in the repository. func (repo *Repository) GetTree(idStr string) (*Tree, error) { - if len(idStr) != SHAFullLength { + if len(idStr) != repo.objectFormat.FullLength() { res, err := repo.GetRefCommitID(idStr) if err != nil { return nil, err @@ -75,7 +75,7 @@ func (repo *Repository) GetTree(idStr string) (*Tree, error) { idStr = res } } - id, err := NewIDFromString(idStr) + id, err := repo.objectFormat.NewIDFromString(idStr) if err != nil { return nil, err } diff --git a/modules/git/sha1.go b/modules/git/sha1.go deleted file mode 100644 index 8d6403e8657fb..0000000000000 --- a/modules/git/sha1.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2015 The Gogs Authors. All rights reserved. -// Copyright 2019 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package git - -import ( - "encoding/hex" - "fmt" - "regexp" - "strings" -) - -// EmptySHA defines empty git SHA (undefined, non-existent) -const EmptySHA = "0000000000000000000000000000000000000000" - -// EmptyTreeSHA is the SHA of an empty tree, the root of all git repositories -const EmptyTreeSHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904" - -// SHAFullLength is the full length of a git SHA -const SHAFullLength = 40 - -// SHAPattern can be used to determine if a string is an valid sha -var shaPattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`) - -// IsValidSHAPattern will check if the provided string matches the SHA Pattern -func IsValidSHAPattern(sha string) bool { - return shaPattern.MatchString(sha) -} - -type ErrInvalidSHA struct { - SHA string -} - -func (err ErrInvalidSHA) Error() string { - return fmt.Sprintf("invalid sha: %s", err.SHA) -} - -// MustID always creates a new SHA1 from a [20]byte array with no validation of input. -func MustID(b []byte) SHA1 { - var id SHA1 - copy(id[:], b) - return id -} - -// NewID creates a new SHA1 from a [20]byte array. -func NewID(b []byte) (SHA1, error) { - if len(b) != 20 { - return SHA1{}, fmt.Errorf("Length must be 20: %v", b) - } - return MustID(b), nil -} - -// MustIDFromString always creates a new sha from a ID with no validation of input. -func MustIDFromString(s string) SHA1 { - b, _ := hex.DecodeString(s) - return MustID(b) -} - -// NewIDFromString creates a new SHA1 from a ID string of length 40. -func NewIDFromString(s string) (SHA1, error) { - var id SHA1 - s = strings.TrimSpace(s) - if len(s) != SHAFullLength { - return id, fmt.Errorf("Length must be 40: %s", s) - } - b, err := hex.DecodeString(s) - if err != nil { - return id, err - } - return NewID(b) -} diff --git a/modules/git/sha1_gogit.go b/modules/git/sha1_gogit.go deleted file mode 100644 index 28f35d17a98e1..0000000000000 --- a/modules/git/sha1_gogit.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015 The Gogs Authors. All rights reserved. -// Copyright 2019 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -//go:build gogit - -package git - -import ( - "github.com/go-git/go-git/v5/plumbing" -) - -// SHA1 a git commit name -type SHA1 = plumbing.Hash - -// ComputeBlobHash compute the hash for a given blob content -func ComputeBlobHash(content []byte) SHA1 { - return plumbing.ComputeHash(plumbing.BlobObject, content) -} diff --git a/modules/git/sha1_nogogit.go b/modules/git/sha1_nogogit.go deleted file mode 100644 index d818d86a3a0cc..0000000000000 --- a/modules/git/sha1_nogogit.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2015 The Gogs Authors. All rights reserved. -// Copyright 2019 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -//go:build !gogit - -package git - -import ( - "crypto/sha1" - "encoding/hex" - "hash" - "strconv" -) - -// SHA1 a git commit name -type SHA1 [20]byte - -// String returns a string representation of the SHA -func (s SHA1) String() string { - return hex.EncodeToString(s[:]) -} - -// IsZero returns whether this SHA1 is all zeroes -func (s SHA1) IsZero() bool { - var empty SHA1 - return s == empty -} - -// ComputeBlobHash compute the hash for a given blob content -func ComputeBlobHash(content []byte) SHA1 { - return ComputeHash(ObjectBlob, content) -} - -// ComputeHash compute the hash for a given ObjectType and content -func ComputeHash(t ObjectType, content []byte) SHA1 { - h := NewHasher(t, int64(len(content))) - _, _ = h.Write(content) - return h.Sum() -} - -// Hasher is a struct that will generate a SHA1 -type Hasher struct { - hash.Hash -} - -// NewHasher takes an object type and size and creates a hasher to generate a SHA -func NewHasher(t ObjectType, size int64) Hasher { - h := Hasher{sha1.New()} - _, _ = h.Write(t.Bytes()) - _, _ = h.Write([]byte(" ")) - _, _ = h.Write([]byte(strconv.FormatInt(size, 10))) - _, _ = h.Write([]byte{0}) - return h -} - -// Sum generates a SHA1 for the provided hash -func (h Hasher) Sum() (sha1 SHA1) { - copy(sha1[:], h.Hash.Sum(nil)) - return sha1 -} diff --git a/modules/git/sha1_test.go b/modules/git/sha1_test.go deleted file mode 100644 index db2944fc53d56..0000000000000 --- a/modules/git/sha1_test.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2022 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package git - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestIsValidSHAPattern(t *testing.T) { - assert.True(t, IsValidSHAPattern("fee1")) - assert.True(t, IsValidSHAPattern("abc000")) - assert.True(t, IsValidSHAPattern("9023902390239023902390239023902390239023")) - assert.False(t, IsValidSHAPattern("90239023902390239023902390239023902390239023")) - assert.False(t, IsValidSHAPattern("abc")) - assert.False(t, IsValidSHAPattern("123g")) - assert.False(t, IsValidSHAPattern("some random text")) -} diff --git a/modules/git/tag.go b/modules/git/tag.go index d0ddef64e087d..27358d74f8db8 100644 --- a/modules/git/tag.go +++ b/modules/git/tag.go @@ -17,8 +17,8 @@ const ( // Tag represents a Git tag. type Tag struct { Name string - ID SHA1 - Object SHA1 // The id of this commit object + ID ObjectID + Object ObjectID // The id of this commit object Type string Tagger *Signature Message string @@ -33,8 +33,10 @@ func (tag *Tag) Commit(gitRepo *Repository) (*Commit, error) { // Parse commit information from the (uncompressed) raw // data from the commit object. // \n\n separate headers from message -func parseTagData(data []byte) (*Tag, error) { +func parseTagData(objectFormat ObjectFormat, data []byte) (*Tag, error) { tag := new(Tag) + tag.ID = objectFormat.NewEmptyID() + tag.Object = objectFormat.NewEmptyID() tag.Tagger = &Signature{} // we now have the contents of the commit object. Let's investigate... nextline := 0 @@ -48,7 +50,7 @@ l: reftype := line[:spacepos] switch string(reftype) { case "object": - id, err := NewIDFromString(string(line[spacepos+1:])) + id, err := objectFormat.NewIDFromString(string(line[spacepos+1:])) if err != nil { return nil, err } diff --git a/modules/git/tag_test.go b/modules/git/tag_test.go index 2337e69c6afcb..129c1e3a02303 100644 --- a/modules/git/tag_test.go +++ b/modules/git/tag_test.go @@ -22,8 +22,8 @@ tagger Lucas Michot 1484491741 +0100 `), tag: Tag{ Name: "", - ID: SHA1{}, - Object: SHA1{0x3b, 0x11, 0x4a, 0xb8, 0x0, 0xc6, 0x43, 0x2a, 0xd4, 0x23, 0x87, 0xcc, 0xf6, 0xbc, 0x8d, 0x43, 0x88, 0xa2, 0x88, 0x5a}, + ID: NewSha1(), + Object: &Sha1Hash{0x3b, 0x11, 0x4a, 0xb8, 0x0, 0xc6, 0x43, 0x2a, 0xd4, 0x23, 0x87, 0xcc, 0xf6, 0xbc, 0x8d, 0x43, 0x88, 0xa2, 0x88, 0x5a}, Type: "commit", Tagger: &Signature{Name: "Lucas Michot", Email: "lucas@semalead.com", When: time.Unix(1484491741, 0)}, Message: "", @@ -39,8 +39,8 @@ o ono`), tag: Tag{ Name: "", - ID: SHA1{}, - Object: SHA1{0x7c, 0xdf, 0x42, 0xc0, 0xb1, 0xcc, 0x76, 0x3a, 0xb7, 0xe4, 0xc3, 0x3c, 0x47, 0xa2, 0x4e, 0x27, 0xc6, 0x6b, 0xfc, 0xcc}, + ID: NewSha1(), + Object: &Sha1Hash{0x7c, 0xdf, 0x42, 0xc0, 0xb1, 0xcc, 0x76, 0x3a, 0xb7, 0xe4, 0xc3, 0x3c, 0x47, 0xa2, 0x4e, 0x27, 0xc6, 0x6b, 0xfc, 0xcc}, Type: "commit", Tagger: &Signature{Name: "Lucas Michot", Email: "lucas@semalead.com", When: time.Unix(1484553735, 0)}, Message: "test message\no\n\nono", @@ -49,7 +49,7 @@ ono`), tag: Tag{ } for _, test := range testData { - tag, err := parseTagData(test.data) + tag, err := parseTagData(ObjectFormatFromID(Sha1), test.data) assert.NoError(t, err) assert.EqualValues(t, test.tag.ID, tag.ID) assert.EqualValues(t, test.tag.Object, tag.Object) diff --git a/modules/git/tree.go b/modules/git/tree.go index 856b8cef53c67..1da4a9fa5debc 100644 --- a/modules/git/tree.go +++ b/modules/git/tree.go @@ -10,7 +10,7 @@ import ( ) // NewTree create a new tree according the repository and tree id -func NewTree(repo *Repository, id SHA1) *Tree { +func NewTree(repo *Repository, id ObjectID) *Tree { return &Tree{ ID: id, repo: repo, diff --git a/modules/git/tree_blob_gogit.go b/modules/git/tree_blob_gogit.go index f1afc5d0a6fec..92c25cb92c12b 100644 --- a/modules/git/tree_blob_gogit.go +++ b/modules/git/tree_blob_gogit.go @@ -24,7 +24,7 @@ func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) { gogitTreeEntry: &object.TreeEntry{ Name: "", Mode: filemode.Dir, - Hash: t.ID, + Hash: plumbing.Hash(t.ID.RawValue()), }, }, nil } diff --git a/modules/git/tree_entry_gogit.go b/modules/git/tree_entry_gogit.go index 194dd12f7dbb1..eb9b012681474 100644 --- a/modules/git/tree_entry_gogit.go +++ b/modules/git/tree_entry_gogit.go @@ -14,7 +14,7 @@ import ( // TreeEntry the leaf in the git tree type TreeEntry struct { - ID SHA1 + ID ObjectID gogitTreeEntry *object.TreeEntry ptree *Tree @@ -88,7 +88,7 @@ func (te *TreeEntry) Blob() *Blob { } return &Blob{ - ID: te.gogitTreeEntry.Hash, + ID: ParseGogitHash(te.gogitTreeEntry.Hash), gogitEncodedObj: encodedObj, name: te.Name(), } diff --git a/modules/git/tree_entry_nogogit.go b/modules/git/tree_entry_nogogit.go index cda755886a8e2..89244e27ee80e 100644 --- a/modules/git/tree_entry_nogogit.go +++ b/modules/git/tree_entry_nogogit.go @@ -9,7 +9,7 @@ import "code.gitea.io/gitea/modules/log" // TreeEntry the leaf in the git tree type TreeEntry struct { - ID SHA1 + ID ObjectID ptree *Tree diff --git a/modules/git/tree_gogit.go b/modules/git/tree_gogit.go index fa601e6533c6b..421b0ecb0f0f9 100644 --- a/modules/git/tree_gogit.go +++ b/modules/git/tree_gogit.go @@ -15,8 +15,8 @@ import ( // Tree represents a flat directory listing. type Tree struct { - ID SHA1 - ResolvedID SHA1 + ID ObjectID + ResolvedID ObjectID repo *Repository gogitTree *object.Tree @@ -26,7 +26,7 @@ type Tree struct { } func (t *Tree) loadTreeObject() error { - gogitTree, err := t.repo.gogitRepo.TreeObject(t.ID) + gogitTree, err := t.repo.gogitRepo.TreeObject(plumbing.Hash(t.ID.RawValue())) if err != nil { return err } @@ -47,7 +47,7 @@ func (t *Tree) ListEntries() (Entries, error) { entries := make([]*TreeEntry, len(t.gogitTree.Entries)) for i, entry := range t.gogitTree.Entries { entries[i] = &TreeEntry{ - ID: entry.Hash, + ID: ParseGogitHash(entry.Hash), gogitTreeEntry: &t.gogitTree.Entries[i], ptree: t, } @@ -81,7 +81,7 @@ func (t *Tree) ListEntriesRecursiveWithSize() (Entries, error) { } convertedEntry := &TreeEntry{ - ID: entry.Hash, + ID: ParseGogitHash(entry.Hash), gogitTreeEntry: &entry, ptree: t, fullName: fullName, diff --git a/modules/git/tree_nogogit.go b/modules/git/tree_nogogit.go index ef598d7e91327..89d3aebbc0bd5 100644 --- a/modules/git/tree_nogogit.go +++ b/modules/git/tree_nogogit.go @@ -13,8 +13,8 @@ import ( // Tree represents a flat directory listing. type Tree struct { - ID SHA1 - ResolvedID SHA1 + ID ObjectID + ResolvedID ObjectID repo *Repository // parent tree @@ -54,7 +54,7 @@ func (t *Tree) ListEntries() (Entries, error) { } } if typ == "tree" { - t.entries, err = catBatchParseTreeEntries(t, rd, sz) + t.entries, err = catBatchParseTreeEntries(t.ID.Type(), t, rd, sz) if err != nil { return nil, err } @@ -90,7 +90,7 @@ func (t *Tree) ListEntries() (Entries, error) { } var err error - t.entries, err = parseTreeEntries(stdout, t) + t.entries, err = parseTreeEntries(t.repo.objectFormat, stdout, t) if err == nil { t.entriesParsed = true } @@ -114,7 +114,7 @@ func (t *Tree) listEntriesRecursive(extraArgs TrustedCmdArgs) (Entries, error) { } var err error - t.entriesRecursive, err = parseTreeEntries(stdout, t) + t.entriesRecursive, err = parseTreeEntries(t.repo.objectFormat, stdout, t) if err == nil { t.entriesRecursiveParsed = true } diff --git a/modules/indexer/code/git.go b/modules/indexer/code/git.go index e4686fa01f441..76cd78e11e6bf 100644 --- a/modules/indexer/code/git.go +++ b/modules/indexer/code/git.go @@ -62,8 +62,8 @@ func isIndexable(entry *git.TreeEntry) bool { } // parseGitLsTreeOutput parses the output of a `git ls-tree -r --full-name` command -func parseGitLsTreeOutput(stdout []byte) ([]internal.FileUpdate, error) { - entries, err := git.ParseTreeEntries(stdout) +func parseGitLsTreeOutput(objectFormat git.ObjectFormat, stdout []byte) ([]internal.FileUpdate, error) { + entries, err := git.ParseTreeEntries(objectFormat, stdout) if err != nil { return nil, err } @@ -92,7 +92,11 @@ func genesisChanges(ctx context.Context, repo *repo_model.Repository, revision s } var err error - changes.Updates, err = parseGitLsTreeOutput(stdout) + objectFormat, err := git.GetObjectFormatOfRepo(ctx, repo.RepoPath()) + if err != nil { + return nil, err + } + changes.Updates, err = parseGitLsTreeOutput(objectFormat, stdout) return &changes, err } @@ -169,6 +173,11 @@ func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revisio if err != nil { return nil, err } - changes.Updates, err = parseGitLsTreeOutput(lsTreeStdout) + + objectFormat, err := git.GetObjectFormatOfRepo(ctx, repo.RepoPath()) + if err != nil { + return nil, err + } + changes.Updates, err = parseGitLsTreeOutput(objectFormat, lsTreeStdout) return &changes, err } diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go index 827b2a98493b0..57f0c90fc6c6e 100644 --- a/modules/repository/commits_test.go +++ b/modules/repository/commits_test.go @@ -144,7 +144,7 @@ func TestCommitToPushCommit(t *testing.T) { When: now, } const hexString = "0123456789abcdef0123456789abcdef01234567" - sha1, err := git.NewIDFromString(hexString) + sha1, err := git.IDFromString(hexString) assert.NoError(t, err) pushCommit := CommitToPushCommit(&git.Commit{ ID: sha1, @@ -169,11 +169,12 @@ func TestListToPushCommits(t *testing.T) { When: now, } + hashType := git.ObjectFormatFromID(git.Sha1) const hexString1 = "0123456789abcdef0123456789abcdef01234567" - hash1, err := git.NewIDFromString(hexString1) + hash1, err := hashType.NewIDFromString(hexString1) assert.NoError(t, err) const hexString2 = "fedcba9876543210fedcba9876543210fedcba98" - hash2, err := git.NewIDFromString(hexString2) + hash2, err := hashType.NewIDFromString(hexString2) assert.NoError(t, err) l := []*git.Commit{ diff --git a/modules/repository/generate.go b/modules/repository/generate.go index 4055029d22a13..c143431b7c6a8 100644 --- a/modules/repository/generate.go +++ b/modules/repository/generate.go @@ -223,7 +223,8 @@ func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *r } } - if err := git.InitRepository(ctx, tmpDir, false); err != nil { + // FIXME: fix the hash + if err := git.InitRepository(ctx, tmpDir, false, git.ObjectFormatFromID(git.Sha1)); err != nil { return err } @@ -356,7 +357,8 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ } } - if err = CheckInitRepository(ctx, owner.Name, generateRepo.Name); err != nil { + // FIXME - fix the hash + if err = CheckInitRepository(ctx, owner.Name, generateRepo.Name, git.ObjectFormatFromID(git.Sha1)); err != nil { return generateRepo, err } diff --git a/modules/repository/init.go b/modules/repository/init.go index 6f791f742b124..a9b5aab16aab5 100644 --- a/modules/repository/init.go +++ b/modules/repository/init.go @@ -188,7 +188,7 @@ func InitRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi return nil } -func CheckInitRepository(ctx context.Context, owner, name string) (err error) { +func CheckInitRepository(ctx context.Context, owner, name string, objectFormat git.ObjectFormat) (err error) { // Somehow the directory could exist. repoPath := repo_model.RepoPath(owner, name) isExist, err := util.IsExist(repoPath) @@ -204,7 +204,7 @@ func CheckInitRepository(ctx context.Context, owner, name string) (err error) { } // Init git bare new repository. - if err = git.InitRepository(ctx, repoPath, true); err != nil { + if err = git.InitRepository(ctx, repoPath, true, objectFormat); err != nil { return fmt.Errorf("git.InitRepository: %w", err) } else if err = CreateDelegateHooks(repoPath); err != nil { return fmt.Errorf("createDelegateHooks: %w", err) diff --git a/modules/repository/push.go b/modules/repository/push.go index ea03f9e1537f7..25695336a52d3 100644 --- a/modules/repository/push.go +++ b/modules/repository/push.go @@ -20,12 +20,14 @@ type PushUpdateOptions struct { // IsNewRef return true if it's a first-time push to a branch, tag or etc. func (opts *PushUpdateOptions) IsNewRef() bool { - return opts.OldCommitID == git.EmptySHA + commitID, err := git.IDFromString(opts.OldCommitID) + return err == nil && commitID.IsZero() } // IsDelRef return true if it's a deletion to a branch or tag func (opts *PushUpdateOptions) IsDelRef() bool { - return opts.NewCommitID == git.EmptySHA + commitID, err := git.IDFromString(opts.NewCommitID) + return err == nil && commitID.IsZero() } // IsUpdateRef return true if it's an update operation diff --git a/routers/api/v1/repo/notes.go b/routers/api/v1/repo/notes.go index 0b259703deaaf..e7e00dae41802 100644 --- a/routers/api/v1/repo/notes.go +++ b/routers/api/v1/repo/notes.go @@ -66,7 +66,7 @@ func getNote(ctx *context.APIContext, identifier string) { return } - commitSHA, err := ctx.Repo.GitRepo.ConvertToSHA1(identifier) + commitID, err := ctx.Repo.GitRepo.ConvertToGitID(identifier) if err != nil { if git.IsErrNotExist(err) { ctx.NotFound(err) @@ -77,7 +77,7 @@ func getNote(ctx *context.APIContext, identifier string) { } var note git.Note - if err := git.GetNote(ctx, ctx.Repo.GitRepo, commitSHA.String(), ¬e); err != nil { + if err := git.GetNote(ctx, ctx.Repo.GitRepo, commitID.String(), ¬e); err != nil { if git.IsErrNotExist(err) { ctx.NotFound(identifier) return diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 64c41d3a97e6c..1767a7fa674d5 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -253,6 +253,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre DefaultBranch: opt.DefaultBranch, TrustModel: repo_model.ToTrustModel(opt.TrustModel), IsTemplate: opt.Template, + ObjectFormat: git.ObjectFormatFromID(git.Sha1), }) if err != nil { if repo_model.IsErrRepoAlreadyExist(err) { diff --git a/routers/api/v1/utils/git.go b/routers/api/v1/utils/git.go index 32f5c85319d46..eb82c505440fe 100644 --- a/routers/api/v1/utils/git.go +++ b/routers/api/v1/utils/git.go @@ -69,27 +69,28 @@ func searchRefCommitByType(ctx *context.APIContext, refType, filter string) (str return "", "", nil } -// ConvertToSHA1 returns a full-length SHA1 from a potential ID string -func ConvertToSHA1(ctx gocontext.Context, repo *context.Repository, commitID string) (git.SHA1, error) { - if len(commitID) == git.SHAFullLength && git.IsValidSHAPattern(commitID) { - sha1, err := git.NewIDFromString(commitID) +// ConvertToObjectID returns a full-length SHA1 from a potential ID string +func ConvertToObjectID(ctx gocontext.Context, repo *context.Repository, commitID string) (git.ObjectID, error) { + objectFormat, _ := repo.GitRepo.GetObjectFormat() + if len(commitID) == objectFormat.FullLength() && objectFormat.IsValid(commitID) { + sha, err := objectFormat.NewIDFromString(commitID) if err == nil { - return sha1, nil + return sha, nil } } gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.Repository.RepoPath()) if err != nil { - return git.SHA1{}, fmt.Errorf("RepositoryFromContextOrOpen: %w", err) + return objectFormat.Empty(), fmt.Errorf("RepositoryFromContextOrOpen: %w", err) } defer closer.Close() - return gitRepo.ConvertToSHA1(commitID) + return gitRepo.ConvertToGitID(commitID) } // MustConvertToSHA1 returns a full-length SHA1 string from a potential ID string, or returns origin input if it can't convert to SHA1 func MustConvertToSHA1(ctx gocontext.Context, repo *context.Repository, commitID string) string { - sha, err := ConvertToSHA1(ctx, repo, commitID) + sha, err := ConvertToObjectID(ctx, repo, commitID) if err != nil { return commitID } diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go index d5a46e4e7fe45..1b274ae154d2f 100644 --- a/routers/private/hook_post_receive.go +++ b/routers/private/hook_post_receive.go @@ -159,8 +159,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) { } // If we've pushed a branch (and not deleted it) - if newCommitID != git.EmptySHA && refFullName.IsBranch() { - + if git.IsEmptyCommitID(newCommitID) && refFullName.IsBranch() { // First ensure we have the repository loaded, we're allowed pulls requests and we can get the base repo if repo == nil { repo = loadRepository(ctx, ownerName, repoName) diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index 4399e49851871..8811809710116 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -145,8 +145,9 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r repo := ctx.Repo.Repository gitRepo := ctx.Repo.GitRepo + objectFormat, _ := gitRepo.GetObjectFormat() - if branchName == repo.DefaultBranch && newCommitID == git.EmptySHA { + if branchName == repo.DefaultBranch && newCommitID == objectFormat.Empty().String() { log.Warn("Forbidden: Branch: %s is the default branch in %-v and cannot be deleted", branchName, repo) ctx.JSON(http.StatusForbidden, private.Response{ UserMsg: fmt.Sprintf("branch %s is the default branch and cannot be deleted", branchName), @@ -174,7 +175,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r // First of all we need to enforce absolutely: // // 1. Detect and prevent deletion of the branch - if newCommitID == git.EmptySHA { + if newCommitID == objectFormat.Empty().String() { log.Warn("Forbidden: Branch: %s in %-v is protected from deletion", branchName, repo) ctx.JSON(http.StatusForbidden, private.Response{ UserMsg: fmt.Sprintf("branch %s is protected from deletion", branchName), @@ -183,7 +184,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r } // 2. Disallow force pushes to protected branches - if git.EmptySHA != oldCommitID { + if oldCommitID != objectFormat.Empty().String() { output, _, err := git.NewCommand(ctx, "rev-list", "--max-count=1").AddDynamicArguments(oldCommitID, "^"+newCommitID).RunStdString(&git.RunOpts{Dir: repo.RepoPath(), Env: ctx.env}) if err != nil { log.Error("Unable to detect force push between: %s and %s in %-v Error: %v", oldCommitID, newCommitID, repo, err) diff --git a/routers/private/hook_verification.go b/routers/private/hook_verification.go index 8604789529a6e..6725205cc6d2c 100644 --- a/routers/private/hook_verification.go +++ b/routers/private/hook_verification.go @@ -29,7 +29,8 @@ func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env [] }() var command *git.Command - if oldCommitID == git.EmptySHA { + objectFormat, _ := repo.GetObjectFormat() + if oldCommitID == objectFormat.Empty().String() { // When creating a new branch, the oldCommitID is empty, by using "newCommitID --not --all": // List commits that are reachable by following the newCommitID, exclude "all" existing heads/tags commits // So, it only lists the new commits received, doesn't list the commits already present in the receiving repository @@ -82,7 +83,8 @@ func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error { _ = stdoutReader.Close() _ = stdoutWriter.Close() }() - hash := git.MustIDFromString(sha) + objectFormat, _ := repo.GetObjectFormat() + commitID := objectFormat.MustIDFromString(sha) return git.NewCommand(repo.Ctx, "cat-file", "commit").AddDynamicArguments(sha). Run(&git.RunOpts{ @@ -91,7 +93,7 @@ func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error { Stdout: stdoutWriter, PipelineFunc: func(ctx context.Context, cancel context.CancelFunc) error { _ = stdoutWriter.Close() - commit, err := git.CommitFromReader(repo, hash, stdoutReader) + commit, err := git.CommitFromReader(repo, commitID, stdoutReader) if err != nil { return err } diff --git a/routers/private/hook_verification_test.go b/routers/private/hook_verification_test.go index cd0c05ff50a71..7263ebc4235d3 100644 --- a/routers/private/hook_verification_test.go +++ b/routers/private/hook_verification_test.go @@ -22,14 +22,17 @@ func TestVerifyCommits(t *testing.T) { defer gitRepo.Close() assert.NoError(t, err) + objectFormat, err := gitRepo.GetObjectFormat() + assert.NoError(t, err) + testCases := []struct { base, head string verified bool }{ {"72920278f2f999e3005801e5d5b8ab8139d3641c", "d766f2917716d45be24bfa968b8409544941be32", true}, - {git.EmptySHA, "93eac826f6188f34646cea81bf426aa5ba7d3bfe", true}, // New branch with verified commit + {objectFormat.Empty().String(), "93eac826f6188f34646cea81bf426aa5ba7d3bfe", true}, // New branch with verified commit {"9779d17a04f1e2640583d35703c62460b2d86e0a", "72920278f2f999e3005801e5d5b8ab8139d3641c", false}, - {git.EmptySHA, "9ce3f779ae33f31fce17fac3c512047b75d7498b", false}, // New branch with unverified commit + {objectFormat.Empty().String(), "9ce3f779ae33f31fce17fac3c512047b75d7498b", false}, // New branch with unverified commit } for _, tc := range testCases { diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go index 52d350ff665a0..db9be51257e7f 100644 --- a/routers/web/repo/blame.go +++ b/routers/web/repo/blame.go @@ -131,7 +131,12 @@ type blameResult struct { } func performBlame(ctx *context.Context, repoPath string, commit *git.Commit, file string, bypassBlameIgnore bool) (*blameResult, error) { - blameReader, err := git.CreateBlameReader(ctx, repoPath, commit, file, bypassBlameIgnore) + objectFormat, err := ctx.Repo.GitRepo.GetObjectFormat() + if err != nil { + ctx.NotFound("CreateBlameReader", err) + return nil, err + } + blameReader, err := git.CreateBlameReader(ctx, objectFormat, repoPath, commit, file, bypassBlameIgnore) if err != nil { return nil, err } @@ -147,7 +152,7 @@ func performBlame(ctx *context.Context, repoPath string, commit *git.Commit, fil if len(r.Parts) == 0 && r.UsesIgnoreRevs { // try again without ignored revs - blameReader, err = git.CreateBlameReader(ctx, repoPath, commit, file, true) + blameReader, err = git.CreateBlameReader(ctx, objectFormat, repoPath, commit, file, true) if err != nil { return nil, err } diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index a0bc1dadade8b..b6de5bf800e2d 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -147,11 +147,18 @@ func RestoreBranchPost(ctx *context.Context) { return } + objectFormat, err := git.GetObjectFormatOfRepo(ctx, ctx.Repo.Repository.RepoPath()) + if err != nil { + log.Error("RestoreBranch: CreateBranch: %w", err) + ctx.Flash.Error(ctx.Tr("repo.branch.restore_failed", deletedBranch.Name)) + return + } + // Don't return error below this if err := repo_service.PushUpdate( &repo_module.PushUpdateOptions{ RefFullName: git.RefNameFromBranch(deletedBranch.Name), - OldCommitID: git.EmptySHA, + OldCommitID: objectFormat.Empty().String(), NewCommitID: deletedBranch.CommitID, PusherID: ctx.Doer.ID, PusherName: ctx.Doer.Name, diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index 3587d287fc5ef..bd393e7fb7f1c 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -294,7 +294,7 @@ func Diff(ctx *context.Context) { } return } - if len(commitID) != git.SHAFullLength { + if len(commitID) != commit.ID.Type().FullLength() { commitID = commit.ID.String() } diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index b69af3c61cc54..5b1638d3f5f53 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -310,13 +310,14 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo { baseIsCommit := ctx.Repo.GitRepo.IsCommitExist(ci.BaseBranch) baseIsBranch := ctx.Repo.GitRepo.IsBranchExist(ci.BaseBranch) baseIsTag := ctx.Repo.GitRepo.IsTagExist(ci.BaseBranch) + objectFormat, _ := ctx.Repo.GitRepo.GetObjectFormat() if !baseIsCommit && !baseIsBranch && !baseIsTag { // Check if baseBranch is short sha commit hash if baseCommit, _ := ctx.Repo.GitRepo.GetCommit(ci.BaseBranch); baseCommit != nil { ci.BaseBranch = baseCommit.ID.String() ctx.Data["BaseBranch"] = ci.BaseBranch baseIsCommit = true - } else if ci.BaseBranch == git.EmptySHA { + } else if ci.BaseBranch == objectFormat.Empty().String() { if isSameRepo { ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ci.HeadBranch)) } else { diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go index 6ff385f989050..dd47bd79d94e1 100644 --- a/routers/web/repo/githttp.go +++ b/routers/web/repo/githttp.go @@ -329,7 +329,7 @@ func dummyInfoRefs(ctx *context.Context) { } }() - if err := git.InitRepository(ctx, tmpDir, true); err != nil { + if err := git.InitRepository(ctx, tmpDir, true, git.ObjectFormatFromID(git.Sha1)); err != nil { log.Error("Failed to init bare repo for git-receive-pack cache: %v", err) return } diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 482fbaac2bc57..7a2976f8dcaac 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -159,6 +159,7 @@ func Create(ctx *context.Context) { ctx.Data["private"] = getRepoPrivate(ctx) ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate ctx.Data["default_branch"] = setting.Repository.DefaultBranch + ctx.Data["hash_type"] = "sha1" ctxUser := checkContextUser(ctx, ctx.FormInt64("org")) if ctx.Written() { @@ -288,6 +289,7 @@ func CreatePost(ctx *context.Context) { AutoInit: form.AutoInit, IsTemplate: form.Template, TrustModel: repo_model.ToTrustModel(form.TrustModel), + ObjectFormat: form.ObjectFormat, }) if err == nil { log.Trace("Repository created [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name) diff --git a/routers/web/repo/setting/lfs.go b/routers/web/repo/setting/lfs.go index d478acdde0dbe..230f1a2a608a5 100644 --- a/routers/web/repo/setting/lfs.go +++ b/routers/web/repo/setting/lfs.go @@ -388,20 +388,21 @@ func LFSFileFind(ctx *context.Context) { sha := ctx.FormString("sha") ctx.Data["Title"] = oid ctx.Data["PageIsSettingsLFS"] = true - var hash git.SHA1 + objectFormat, _ := ctx.Repo.GitRepo.GetObjectFormat() + var objectID git.ObjectID if len(sha) == 0 { pointer := lfs.Pointer{Oid: oid, Size: size} - hash = git.ComputeBlobHash([]byte(pointer.StringContent())) - sha = hash.String() + objectID = git.ComputeBlobHash(objectFormat, []byte(pointer.StringContent())) + sha = objectID.String() } else { - hash = git.MustIDFromString(sha) + objectID = objectFormat.MustIDFromString(sha) } ctx.Data["LFSFilesLink"] = ctx.Repo.RepoLink + "/settings/lfs" ctx.Data["Oid"] = oid ctx.Data["Size"] = size ctx.Data["SHA"] = sha - results, err := pipeline.FindLFSFile(ctx.Repo.GitRepo, hash) + results, err := pipeline.FindLFSFile(ctx.Repo.GitRepo, objectID) if err != nil && err != io.EOF { log.Error("Failure in FindLFSFile: %v", err) ctx.ServerError("LFSFind: FindLFSFile.", err) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index 5100bf782f06f..8c232a4cb8d43 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -655,8 +655,14 @@ func TestWebhook(ctx *context.Context) { commit := ctx.Repo.Commit if commit == nil { ghost := user_model.NewGhostUser() + objectFormat, err := git.GetObjectFormatOfRepo(ctx, ctx.Repo.Repository.RepoPath()) + if err != nil { + ctx.Flash.Error("GetObjectFormatOfRepo: " + err.Error()) + ctx.Status(http.StatusInternalServerError) + return + } commit = &git.Commit{ - ID: git.MustIDFromString(git.EmptySHA), + ID: objectFormat.NewEmptyID(), Author: ghost.NewGitSig(), Committer: ghost.NewGitSig(), CommitMessage: "This is a fake commit", diff --git a/services/actions/commit_status.go b/services/actions/commit_status.go index 08a7dde67c85b..c1fc1eda92aab 100644 --- a/services/actions/commit_status.go +++ b/services/actions/commit_status.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" user_model "code.gitea.io/gitea/models/user" + git "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" webhook_module "code.gitea.io/gitea/modules/webhook" @@ -114,9 +115,13 @@ func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er } creator := user_model.NewActionsUser() + commitID, err := git.IDFromString(sha) + if err != nil { + return fmt.Errorf("HashTypeInterfaceFromHashString: %w", err) + } if err := git_model.NewCommitStatus(ctx, git_model.NewCommitStatusOptions{ Repo: repo, - SHA: sha, + SHA: commitID, Creator: creator, CommitStatus: &git_model.CommitStatus{ SHA: sha, diff --git a/services/agit/agit.go b/services/agit/agit.go index acfedf09d425d..e354b9169a201 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -36,9 +36,10 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. topicBranch = opts.GitPushOptions["topic"] _, forcePush = opts.GitPushOptions["force-push"] + objectFormat, _ := gitRepo.GetObjectFormat() for i := range opts.OldCommitIDs { - if opts.NewCommitIDs[i] == git.EmptySHA { + if opts.NewCommitIDs[i] == objectFormat.Empty().String() { results = append(results, private.HookProcReceiveRefResult{ OriginalRef: opts.RefFullNames[i], OldOID: opts.OldCommitIDs[i], @@ -148,10 +149,11 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. log.Trace("Pull request created: %d/%d", repo.ID, prIssue.ID) + objectFormat, _ := gitRepo.GetObjectFormat() results = append(results, private.HookProcReceiveRefResult{ Ref: pr.GetGitRefName(), OriginalRef: opts.RefFullNames[i], - OldOID: git.EmptySHA, + OldOID: objectFormat.Empty().String(), NewOID: opts.NewCommitIDs[i], }) continue diff --git a/services/convert/git_commit_test.go b/services/convert/git_commit_test.go index 8c4ef88ebe0eb..d8c1fdfed78a7 100644 --- a/services/convert/git_commit_test.go +++ b/services/convert/git_commit_test.go @@ -19,12 +19,12 @@ import ( func TestToCommitMeta(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - sha1, _ := git.NewIDFromString("0000000000000000000000000000000000000000") + sha1 := git.ObjectFormatFromID(git.Sha1) signature := &git.Signature{Name: "Test Signature", Email: "test@email.com", When: time.Unix(0, 0)} tag := &git.Tag{ Name: "Test Tag", - ID: sha1, - Object: sha1, + ID: sha1.Empty(), + Object: sha1.Empty(), Type: "Test Type", Tagger: signature, Message: "Test Message", @@ -34,8 +34,8 @@ func TestToCommitMeta(t *testing.T) { assert.NotNil(t, commitMeta) assert.EqualValues(t, &api.CommitMeta{ - SHA: "0000000000000000000000000000000000000000", - URL: util.URLJoin(headRepo.APIURL(), "git/commits", "0000000000000000000000000000000000000000"), + SHA: sha1.Empty().String(), + URL: util.URLJoin(headRepo.APIURL(), "git/commits", sha1.Empty().String()), Created: time.Unix(0, 0), }, commitMeta) } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 5df7ec8fd609a..f6ef97dfdc3b6 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -13,6 +13,7 @@ import ( issues_model "code.gitea.io/gitea/models/issues" project_model "code.gitea.io/gitea/models/project" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web/middleware" @@ -53,6 +54,7 @@ type CreateRepoForm struct { TrustModel string ForkSingleBranch string + ObjectFormat git.ObjectFormat } // Validate validates the fields diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 8bf6cba844d6b..05d4a0555fc6c 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -1115,10 +1115,15 @@ func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, fi } cmdDiff := git.NewCommand(gitRepo.Ctx) - if (len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == git.EmptySHA) && commit.ParentCount() == 0 { + objectFormat, err := gitRepo.GetObjectFormat() + if err != nil { + return nil, err + } + + if (len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == objectFormat.Empty().String()) && commit.ParentCount() == 0 { cmdDiff.AddArguments("diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M"). AddArguments(opts.WhitespaceBehavior...). - AddArguments("4b825dc642cb6eb9a060e54bf8d69288fbee4904"). // append empty tree ref + AddDynamicArguments(objectFormat.EmptyTree().String()). AddDynamicArguments(opts.AfterCommitID) } else { actualBeforeCommitID := opts.BeforeCommitID @@ -1224,8 +1229,8 @@ func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, fi } diffPaths := []string{opts.BeforeCommitID + separator + opts.AfterCommitID} - if len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == git.EmptySHA { - diffPaths = []string{git.EmptyTreeSHA, opts.AfterCommitID} + if len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == objectFormat.Empty().String() { + diffPaths = []string{objectFormat.EmptyTree().String(), opts.AfterCommitID} } diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...) if err != nil && strings.Contains(err.Error(), "no merge base") { @@ -1256,12 +1261,15 @@ func GetPullDiffStats(gitRepo *git.Repository, opts *DiffOptions) (*PullDiffStat separator = ".." } - diffPaths := []string{opts.BeforeCommitID + separator + opts.AfterCommitID} - if len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == git.EmptySHA { - diffPaths = []string{git.EmptyTreeSHA, opts.AfterCommitID} + objectFormat, err := gitRepo.GetObjectFormat() + if err != nil { + return nil, err } - var err error + diffPaths := []string{opts.BeforeCommitID + separator + opts.AfterCommitID} + if len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == objectFormat.Empty().String() { + diffPaths = []string{objectFormat.EmptyTree().String(), opts.AfterCommitID} + } _, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...) if err != nil && strings.Contains(err.Error(), "no merge base") { diff --git a/services/migrations/common.go b/services/migrations/common.go index 4f9837472d9dc..278c156b036cb 100644 --- a/services/migrations/common.go +++ b/services/migrations/common.go @@ -48,16 +48,18 @@ func CheckAndEnsureSafePR(pr *base.PullRequest, commonCloneBaseURL string, g bas } // SECURITY: SHAs Must be a SHA - if pr.MergeCommitSHA != "" && !git.IsValidSHAPattern(pr.MergeCommitSHA) { + // FIXME: hash only a SHA1 + CommitType := git.ObjectFormatFromID(git.Sha1) + if pr.MergeCommitSHA != "" && !CommitType.IsValid(pr.MergeCommitSHA) { WarnAndNotice("PR #%d in %s has invalid MergeCommitSHA: %s", pr.Number, g, pr.MergeCommitSHA) pr.MergeCommitSHA = "" } - if pr.Head.SHA != "" && !git.IsValidSHAPattern(pr.Head.SHA) { + if pr.Head.SHA != "" && !CommitType.IsValid(pr.Head.SHA) { WarnAndNotice("PR #%d in %s has invalid HeadSHA: %s", pr.Number, g, pr.Head.SHA) pr.Head.SHA = "" valid = false } - if pr.Base.SHA != "" && !git.IsValidSHAPattern(pr.Base.SHA) { + if pr.Base.SHA != "" && !CommitType.IsValid(pr.Base.SHA) { WarnAndNotice("PR #%d in %s has invalid BaseSHA: %s", pr.Number, g, pr.Base.SHA) pr.Base.SHA = "" valid = false diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go index 6ad0a2326bd16..23d855d615d7c 100644 --- a/services/migrations/gitea_uploader.go +++ b/services/migrations/gitea_uploader.go @@ -892,7 +892,8 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error { comment.UpdatedAt = comment.CreatedAt } - if !git.IsValidSHAPattern(comment.CommitID) { + objectFormat, _ := g.gitRepo.GetObjectFormat() + if !objectFormat.IsValid(comment.CommitID) { log.Warn("Invalid comment CommitID[%s] on comment[%d] in PR #%d of %s/%s replaced with %s", comment.CommitID, pr.Index, g.repoOwner, g.repoName, headCommitID) comment.CommitID = headCommitID } diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index 7c291eabafa62..b6c9b814772a5 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -232,7 +232,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { // fromRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) baseRef := "master" - assert.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false)) + assert.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false, fromRepo.ObjectFormat)) err := git.NewCommand(git.DefaultContext, "symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(&git.RunOpts{Dir: fromRepo.RepoPath()}) assert.NoError(t, err) assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", fromRepo.RepoPath())), 0o644)) diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index be426d4312894..b3ecf2fc54e1a 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -478,9 +478,13 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool { log.Error("SyncMirrors [repo: %-v]: unable to GetRefCommitID [ref_name: %s]: %v", m.Repo, result.refName, err) continue } + objectFormat, err := git.GetObjectFormatOfRepo(ctx, m.Repo.RepoPath()) + if err != nil { + log.Error("SyncMirrors [repo: %-v]: unable to GetHashTypeOfRepo: %v", m.Repo, err) + } notify_service.SyncPushCommits(ctx, m.Repo.MustOwner(ctx), m.Repo, &repo_module.PushUpdateOptions{ RefFullName: result.refName, - OldCommitID: git.EmptySHA, + OldCommitID: objectFormat.Empty().String(), NewCommitID: commitID, }, repo_module.NewPushCommits()) notify_service.SyncCreateRef(ctx, m.Repo.MustOwner(ctx), m.Repo, result.refName, commitID) diff --git a/services/packages/cargo/index.go b/services/packages/cargo/index.go index 8164ffb01cb28..48bd0a4d80a25 100644 --- a/services/packages/cargo/index.go +++ b/services/packages/cargo/index.go @@ -271,7 +271,7 @@ func alterRepositoryContent(ctx context.Context, doer *user_model.User, repo *re if !git.IsErrBranchNotExist(err) || !repo.IsEmpty { return err } - if err := t.Init(); err != nil { + if err := t.Init(repo.ObjectFormat); err != nil { return err } } else { diff --git a/services/pull/check.go b/services/pull/check.go index b51b58f480f3d..ebe4c6d61b038 100644 --- a/services/pull/check.go +++ b/services/pull/check.go @@ -215,24 +215,29 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com return nil, fmt.Errorf("GetFullCommitID(%s) in %s: %w", prHeadRef, pr.BaseRepo.FullName(), err) } + gitRepo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) + if err != nil { + return nil, fmt.Errorf("%-v OpenRepository: %w", pr.BaseRepo, err) + } + defer gitRepo.Close() + + objectFormat, err := gitRepo.GetObjectFormat() + if err != nil { + return nil, fmt.Errorf("%-v GetObjectFormat: %w", pr.BaseRepo, err) + } + // Get the commit from BaseBranch where the pull request got merged mergeCommit, _, err := git.NewCommand(ctx, "rev-list", "--ancestry-path", "--merges", "--reverse"). AddDynamicArguments(prHeadCommitID + ".." + pr.BaseBranch). RunStdString(&git.RunOpts{Dir: pr.BaseRepo.RepoPath()}) if err != nil { return nil, fmt.Errorf("git rev-list --ancestry-path --merges --reverse: %w", err) - } else if len(mergeCommit) < git.SHAFullLength { + } else if len(mergeCommit) < objectFormat.FullLength() { // PR was maybe fast-forwarded, so just use last commit of PR mergeCommit = prHeadCommitID } mergeCommit = strings.TrimSpace(mergeCommit) - gitRepo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) - if err != nil { - return nil, fmt.Errorf("%-v OpenRepository: %w", pr.BaseRepo, err) - } - defer gitRepo.Close() - commit, err := gitRepo.GetCommit(mergeCommit) if err != nil { return nil, fmt.Errorf("GetMergeCommit[%s]: %w", mergeCommit, err) diff --git a/services/pull/merge.go b/services/pull/merge.go index 33c7455c08773..63f0268bebece 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -486,7 +486,8 @@ func MergedManually(ctx context.Context, pr *issues_model.PullRequest, doer *use return models.ErrInvalidMergeStyle{ID: pr.BaseRepo.ID, Style: repo_model.MergeStyleManuallyMerged} } - if len(commitID) < git.SHAFullLength { + objectFormat, _ := baseGitRepo.GetObjectFormat() + if len(commitID) != objectFormat.FullLength() { return fmt.Errorf("Wrong commit ID") } diff --git a/services/pull/patch.go b/services/pull/patch.go index 688cbcc027db2..1dbbec373d165 100644 --- a/services/pull/patch.go +++ b/services/pull/patch.go @@ -129,6 +129,9 @@ func (e *errMergeConflict) Error() string { func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, gitRepo *git.Repository) error { log.Trace("Attempt to merge:\n%v", file) + + objectFormat, _ := gitRepo.GetObjectFormat() + switch { case file.stage1 != nil && (file.stage2 == nil || file.stage3 == nil): // 1. Deleted in one or both: @@ -145,7 +148,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, g // 2. Added in ours but not in theirs or identical in both // // Not a genuine conflict just add to the index - if err := gitRepo.AddObjectToIndex(file.stage2.mode, git.MustIDFromString(file.stage2.sha), file.stage2.path); err != nil { + if err := gitRepo.AddObjectToIndex(file.stage2.mode, objectFormat.MustIDFromString(file.stage2.sha), file.stage2.path); err != nil { return err } return nil @@ -158,7 +161,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, g // 4. Added in theirs but not ours: // // Not a genuine conflict just add to the index - return gitRepo.AddObjectToIndex(file.stage3.mode, git.MustIDFromString(file.stage3.sha), file.stage3.path) + return gitRepo.AddObjectToIndex(file.stage3.mode, objectFormat.MustIDFromString(file.stage3.sha), file.stage3.path) case file.stage1 == nil: // 5. Created by new in both // @@ -219,7 +222,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, g return err } hash = strings.TrimSpace(hash) - return gitRepo.AddObjectToIndex(file.stage2.mode, git.MustIDFromString(hash), file.stage2.path) + return gitRepo.AddObjectToIndex(file.stage2.mode, objectFormat.MustIDFromString(hash), file.stage2.path) default: if file.stage1 != nil { return &errMergeConflict{file.stage1.path} diff --git a/services/pull/pull.go b/services/pull/pull.go index 2f5143903aa83..a16d1be1c1cbd 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -327,7 +327,8 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, } if err == nil { for _, pr := range prs { - if newCommitID != "" && newCommitID != git.EmptySHA { + objectFormat, _ := git.GetObjectFormatOfRepo(ctx, pr.BaseRepo.RepoPath()) + if newCommitID != "" && newCommitID != objectFormat.Empty().String() { changed, err := checkIfPRContentChanged(ctx, pr, oldCommitID, newCommitID) if err != nil { log.Error("checkIfPRContentChanged: %v", err) diff --git a/services/pull/temp_repo.go b/services/pull/temp_repo.go index db32940e3835a..fde8673a2403f 100644 --- a/services/pull/temp_repo.go +++ b/services/pull/temp_repo.go @@ -93,8 +93,14 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest) baseRepoPath := pr.BaseRepo.RepoPath() headRepoPath := pr.HeadRepo.RepoPath() + objectFormat, err := git.GetObjectFormatOfRepo(ctx, baseRepoPath) + if err != nil { + log.Error("Unable to fetch ObjectFormat of repository %s: %v", baseRepoPath, err) + cancel() + return nil, nil, err + } - if err := git.InitRepository(ctx, tmpBasePath, false); err != nil { + if err := git.InitRepository(ctx, tmpBasePath, false, objectFormat); err != nil { log.Error("Unable to init tmpBasePath for %-v: %v", pr, err) cancel() return nil, nil, err @@ -172,7 +178,7 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest) var headBranch string if pr.Flow == issues_model.PullRequestFlowGithub { headBranch = git.BranchPrefix + pr.HeadBranch - } else if len(pr.HeadCommitID) == git.SHAFullLength { // for not created pull request + } else if len(pr.HeadCommitID) == objectFormat.FullLength() { // for not created pull request headBranch = pr.HeadCommitID } else { headBranch = pr.GetGitRefName() diff --git a/services/release/release.go b/services/release/release.go index 3ba2a3f611786..4cd520e82f965 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -86,16 +86,17 @@ func createTag(ctx context.Context, gitRepo *git.Repository, rel *repo_model.Rel created = true rel.LowerTagName = strings.ToLower(rel.TagName) + objectFormat, _ := gitRepo.GetObjectFormat() commits := repository.NewPushCommits() commits.HeadCommit = repository.CommitToPushCommit(commit) - commits.CompareURL = rel.Repo.ComposeCompareURL(git.EmptySHA, commit.ID.String()) + commits.CompareURL = rel.Repo.ComposeCompareURL(objectFormat.Empty().String(), commit.ID.String()) refFullName := git.RefNameFromTag(rel.TagName) notify_service.PushCommits( ctx, rel.Publisher, rel.Repo, &repository.PushUpdateOptions{ RefFullName: refFullName, - OldCommitID: git.EmptySHA, + OldCommitID: objectFormat.Empty().String(), NewCommitID: commit.ID.String(), }, commits) notify_service.CreateRef(ctx, rel.Publisher, rel.Repo, refFullName, commit.ID.String()) @@ -325,12 +326,16 @@ func DeleteReleaseByID(ctx context.Context, repo *repo_model.Repository, rel *re } refName := git.RefNameFromTag(rel.TagName) + objectFormat, err := git.GetObjectFormatOfRepo(ctx, repo.RepoPath()) + if err != nil { + return err + } notify_service.PushCommits( ctx, doer, repo, &repository.PushUpdateOptions{ RefFullName: refName, OldCommitID: rel.Sha1, - NewCommitID: git.EmptySHA, + NewCommitID: objectFormat.Empty().String(), }, repository.NewPushCommits()) notify_service.DeleteRef(ctx, doer, repo, refName) diff --git a/services/repository/archiver/archiver.go b/services/repository/archiver/archiver.go index 9f1ea48dca400..f700e3af5decd 100644 --- a/services/repository/archiver/archiver.go +++ b/services/repository/archiver/archiver.go @@ -9,7 +9,6 @@ import ( "fmt" "io" "os" - "regexp" "strings" "time" @@ -36,10 +35,6 @@ type ArchiveRequest struct { CommitID string } -// SHA1 hashes will only go up to 40 characters, but SHA256 hashes will go all -// the way to 64. -var shaRegex = regexp.MustCompile(`^[0-9a-f]{4,64}$`) - // ErrUnknownArchiveFormat request archive format is not supported type ErrUnknownArchiveFormat struct { RequestFormat string @@ -96,30 +91,13 @@ func NewRequest(repoID int64, repo *git.Repository, uri string) (*ArchiveRequest r.refName = strings.TrimSuffix(uri, ext) - var err error // Get corresponding commit. - if repo.IsBranchExist(r.refName) { - r.CommitID, err = repo.GetBranchCommitID(r.refName) - if err != nil { - return nil, err - } - } else if repo.IsTagExist(r.refName) { - r.CommitID, err = repo.GetTagCommitID(r.refName) - if err != nil { - return nil, err - } - } else if shaRegex.MatchString(r.refName) { - if repo.IsCommitExist(r.refName) { - r.CommitID = r.refName - } else { - return nil, git.ErrNotExist{ - ID: r.refName, - } - } - } else { + commitID, err := repo.ConvertToGitID(r.refName) + if err != nil { return nil, RepoRefNotFoundError{RefName: r.refName} } + r.CommitID = commitID.String() return r, nil } diff --git a/services/repository/branch.go b/services/repository/branch.go index b3dbb252ca34e..b797917757ede 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -377,6 +377,11 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R return fmt.Errorf("GetBranch: %vc", err) } + objectFormat, err := gitRepo.GetObjectFormat() + if err != nil { + return err + } + if rawBranch.IsDeleted { return nil } @@ -403,7 +408,7 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R &repo_module.PushUpdateOptions{ RefFullName: git.RefNameFromBranch(branchName), OldCommitID: commit.ID.String(), - NewCommitID: git.EmptySHA, + NewCommitID: objectFormat.Empty().String(), PusherID: doer.ID, PusherName: doer.Name, RepoUserName: repo.OwnerName, diff --git a/services/repository/check.go b/services/repository/check.go index 2f26d030c33a2..23c4f79bf2045 100644 --- a/services/repository/check.go +++ b/services/repository/check.go @@ -192,7 +192,7 @@ func ReinitMissingRepositories(ctx context.Context) error { default: } log.Trace("Initializing %d/%d...", repo.OwnerID, repo.ID) - if err := git.InitRepository(ctx, repo.RepoPath(), true); err != nil { + if err := git.InitRepository(ctx, repo.RepoPath(), true, repo.ObjectFormat); err != nil { log.Error("Unable (re)initialize repository %d at %s. Error: %v", repo.ID, repo.RepoPath(), err) if err2 := system_model.CreateRepositoryNotice("InitRepository [%d]: %v", repo.ID, err); err2 != nil { log.Error("CreateRepositoryNotice: %v", err2) diff --git a/services/repository/create.go b/services/repository/create.go index b6b6454c44178..a41904eb7cdf0 100644 --- a/services/repository/create.go +++ b/services/repository/create.go @@ -43,6 +43,7 @@ type CreateRepoOptions struct { Status repo_model.RepositoryStatus TrustModel repo_model.TrustModelType MirrorInterval string + ObjectFormat git.ObjectFormat } func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, repoPath string, opts CreateRepoOptions) error { @@ -134,7 +135,7 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, // InitRepository initializes README and .gitignore if needed. func initRepository(ctx context.Context, repoPath string, u *user_model.User, repo *repo_model.Repository, opts CreateRepoOptions) (err error) { - if err = repo_module.CheckInitRepository(ctx, repo.OwnerName, repo.Name); err != nil { + if err = repo_module.CheckInitRepository(ctx, repo.OwnerName, repo.Name, opts.ObjectFormat); err != nil { return err } @@ -209,6 +210,10 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt opts.DefaultBranch = setting.Repository.DefaultBranch } + if opts.ObjectFormat == nil { + opts.ObjectFormat = git.ObjectFormatFromID(git.Sha1) + } + // Check if label template exist if len(opts.IssueLabels) > 0 { if _, err := repo_module.LoadTemplateLabelsByDisplayName(opts.IssueLabels); err != nil { @@ -234,6 +239,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt TrustModel: opts.TrustModel, IsMirror: opts.IsMirror, DefaultBranch: opts.DefaultBranch, + ObjectFormat: opts.ObjectFormat, } var rollbackRepo *repo_model.Repository diff --git a/services/repository/files/cherry_pick.go b/services/repository/files/cherry_pick.go index c1c5bfb617689..0085e88d55274 100644 --- a/services/repository/files/cherry_pick.go +++ b/services/repository/files/cherry_pick.go @@ -11,7 +11,6 @@ import ( "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/services/pull" @@ -48,7 +47,7 @@ func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_mod if opts.LastCommitID == "" { opts.LastCommitID = commit.ID.String() } else { - lastCommitID, err := t.gitRepo.ConvertToSHA1(opts.LastCommitID) + lastCommitID, err := t.gitRepo.ConvertToGitID(opts.LastCommitID) if err != nil { return nil, fmt.Errorf("CherryPick: Invalid last commit ID: %w", err) } @@ -67,7 +66,7 @@ func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_mod } parent, err := commit.ParentID(0) if err != nil { - parent = git.MustIDFromString(git.EmptyTreeSHA) + parent = repo.ObjectFormat.EmptyTree() } base, right := parent.String(), commit.ID.String() diff --git a/services/repository/files/commit.go b/services/repository/files/commit.go index 3e4627487be88..048e41e6fdd38 100644 --- a/services/repository/files/commit.go +++ b/services/repository/files/commit.go @@ -29,10 +29,15 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creato } defer closer.Close() - if commit, err := gitRepo.GetCommit(sha); err != nil { + objectFormat, err := gitRepo.GetObjectFormat() + if err != nil { + return fmt.Errorf("GetObjectFormat[%s]: %w", repoPath, err) + } + commit, err := gitRepo.GetCommit(sha) + if err != nil { gitRepo.Close() return fmt.Errorf("GetCommit[%s]: %w", sha, err) - } else if len(sha) != git.SHAFullLength { + } else if len(sha) != objectFormat.FullLength() { // use complete commit sha sha = commit.ID.String() } @@ -41,7 +46,7 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creato if err := git_model.NewCommitStatus(ctx, git_model.NewCommitStatusOptions{ Repo: repo, Creator: creator, - SHA: sha, + SHA: commit.ID, CommitStatus: status, }); err != nil { return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", repo.ID, creator.ID, sha, err) diff --git a/services/repository/files/patch.go b/services/repository/files/patch.go index 5ef0619636e77..96899e6e0e9f1 100644 --- a/services/repository/files/patch.go +++ b/services/repository/files/patch.go @@ -130,7 +130,7 @@ func ApplyDiffPatch(ctx context.Context, repo *repo_model.Repository, doer *user if opts.LastCommitID == "" { opts.LastCommitID = commit.ID.String() } else { - lastCommitID, err := t.gitRepo.ConvertToSHA1(opts.LastCommitID) + lastCommitID, err := t.gitRepo.ConvertToGitID(opts.LastCommitID) if err != nil { return nil, fmt.Errorf("ApplyPatch: Invalid last commit ID: %w", err) } diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go index be13b2016a1ec..0b5aaba1544ad 100644 --- a/services/repository/files/temp_repo.go +++ b/services/repository/files/temp_repo.go @@ -77,8 +77,8 @@ func (t *TemporaryUploadRepository) Clone(branch string) error { } // Init the repository -func (t *TemporaryUploadRepository) Init() error { - if err := git.InitRepository(t.ctx, t.basePath, false); err != nil { +func (t *TemporaryUploadRepository) Init(objectFormat git.ObjectFormat) error { + if err := git.InitRepository(t.ctx, t.basePath, false, objectFormat); err != nil { return err } gitRepo, err := git.OpenRepository(t.ctx, t.basePath) diff --git a/services/repository/files/tree.go b/services/repository/files/tree.go index 0b1d304845eb2..9d3185c3fc4c6 100644 --- a/services/repository/files/tree.go +++ b/services/repository/files/tree.go @@ -37,19 +37,21 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git } apiURL := repo.APIURL() apiURLLen := len(apiURL) + objectFormat, _ := gitRepo.GetObjectFormat() + hashLen := objectFormat.FullLength() - // 51 is len(sha1) + len("/git/blobs/"). 40 + 11. - blobURL := make([]byte, apiURLLen+51) + const gitBlobsPath = "/git/blobs/" + blobURL := make([]byte, apiURLLen+hashLen+len(gitBlobsPath)) copy(blobURL, apiURL) - copy(blobURL[apiURLLen:], "/git/blobs/") + copy(blobURL[apiURLLen:], []byte(gitBlobsPath)) - // 51 is len(sha1) + len("/git/trees/"). 40 + 11. - treeURL := make([]byte, apiURLLen+51) + const gitTreePath = "/git/trees/" + treeURL := make([]byte, apiURLLen+hashLen+len(gitTreePath)) copy(treeURL, apiURL) - copy(treeURL[apiURLLen:], "/git/trees/") + copy(treeURL[apiURLLen:], []byte(gitTreePath)) - // 40 is the size of the sha1 hash in hexadecimal format. - copyPos := len(treeURL) - git.SHAFullLength + // copyPos is at the start of the hash + copyPos := len(treeURL) - hashLen if perPage <= 0 || perPage > setting.API.DefaultGitTreesPerPage { perPage = setting.API.DefaultGitTreesPerPage diff --git a/services/repository/files/update.go b/services/repository/files/update.go index 42b98a273948b..d202717ef5706 100644 --- a/services/repository/files/update.go +++ b/services/repository/files/update.go @@ -155,7 +155,8 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use if !git.IsErrBranchNotExist(err) || !repo.IsEmpty { return nil, err } - if err := t.Init(); err != nil { + objectFormat, _ := gitRepo.GetObjectFormat() + if err := t.Init(objectFormat); err != nil { return nil, err } hasOldBranch = false @@ -202,7 +203,7 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use if opts.LastCommitID == "" { opts.LastCommitID = commit.ID.String() } else { - lastCommitID, err := t.gitRepo.ConvertToSHA1(opts.LastCommitID) + lastCommitID, err := t.gitRepo.ConvertToGitID(opts.LastCommitID) if err != nil { return nil, fmt.Errorf("ConvertToSHA1: Invalid last commit ID: %w", err) } diff --git a/services/repository/files/upload.go b/services/repository/files/upload.go index 6a1f2ccd16c96..8be8773544779 100644 --- a/services/repository/files/upload.go +++ b/services/repository/files/upload.go @@ -91,7 +91,7 @@ func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use if !git.IsErrBranchNotExist(err) || !repo.IsEmpty { return err } - if err = t.Init(); err != nil { + if err = t.Init(repo.ObjectFormat); err != nil { return err } hasOldBranch = false diff --git a/services/repository/lfs.go b/services/repository/lfs.go index 8e654b6f13bcd..b437fda15d578 100644 --- a/services/repository/lfs.go +++ b/services/repository/lfs.go @@ -78,13 +78,14 @@ func GarbageCollectLFSMetaObjectsForRepo(ctx context.Context, repo *repo_model.R store := lfs.NewContentStore() errStop := errors.New("STOPERR") + objectFormat, _ := gitRepo.GetObjectFormat() err = git_model.IterateLFSMetaObjectsForRepo(ctx, repo.ID, func(ctx context.Context, metaObject *git_model.LFSMetaObject, count int64) error { if opts.NumberToCheckPerRepo > 0 && total > opts.NumberToCheckPerRepo { return errStop } total++ - pointerSha := git.ComputeBlobHash([]byte(metaObject.Pointer.StringContent())) + pointerSha := git.ComputeBlobHash(objectFormat, []byte(metaObject.Pointer.StringContent())) if gitRepo.IsObjectExist(pointerSha.String()) { return git_model.MarkLFSMetaObject(ctx, metaObject.ID) diff --git a/services/repository/push.go b/services/repository/push.go index b5388834c0bd1..3003933c34bcf 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -65,7 +65,7 @@ func PushUpdates(opts []*repo_module.PushUpdateOptions) error { for _, opt := range opts { if opt.IsNewRef() && opt.IsDelRef() { - return fmt.Errorf("Old and new revisions are both %s", git.EmptySHA) + return fmt.Errorf("Old and new revisions are both NULL") } } @@ -94,6 +94,11 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { } defer gitRepo.Close() + objectFormat, err := gitRepo.GetObjectFormat() + if err != nil { + return fmt.Errorf("unknown repository ObjectFormat [%s]: %w", repoPath, err) + } + if err = repo_module.UpdateRepoSize(ctx, repo); err != nil { return fmt.Errorf("Failed to update size for repository: %v", err) } @@ -106,7 +111,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { log.Trace("pushUpdates: %-v %s %s %s", repo, opts.OldCommitID, opts.NewCommitID, opts.RefFullName) if opts.IsNewRef() && opts.IsDelRef() { - return fmt.Errorf("old and new revisions are both %s", git.EmptySHA) + return fmt.Errorf("old and new revisions are both %s", objectFormat.Empty()) } if opts.RefFullName.IsTag() { if pusher == nil || pusher.ID != opts.PusherID { @@ -126,7 +131,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { &repo_module.PushUpdateOptions{ RefFullName: git.RefNameFromTag(tagName), OldCommitID: opts.OldCommitID, - NewCommitID: git.EmptySHA, + NewCommitID: objectFormat.Empty().String(), }, repo_module.NewPushCommits()) delTags = append(delTags, tagName) @@ -139,13 +144,13 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { commits := repo_module.NewPushCommits() commits.HeadCommit = repo_module.CommitToPushCommit(newCommit) - commits.CompareURL = repo.ComposeCompareURL(git.EmptySHA, opts.NewCommitID) + commits.CompareURL = repo.ComposeCompareURL(objectFormat.Empty().String(), opts.NewCommitID) notify_service.PushCommits( ctx, pusher, repo, &repo_module.PushUpdateOptions{ RefFullName: opts.RefFullName, - OldCommitID: git.EmptySHA, + OldCommitID: objectFormat.Empty().String(), NewCommitID: opts.NewCommitID, }, commits) @@ -229,7 +234,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { } oldCommitID := opts.OldCommitID - if oldCommitID == git.EmptySHA && len(commits.Commits) > 0 { + if oldCommitID == objectFormat.Empty().String() && len(commits.Commits) > 0 { oldCommit, err := gitRepo.GetCommit(commits.Commits[len(commits.Commits)-1].Sha1) if err != nil && !git.IsErrNotExist(err) { log.Error("unable to GetCommit %s from %-v: %v", oldCommitID, repo, err) @@ -245,11 +250,11 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { } } - if oldCommitID == git.EmptySHA && repo.DefaultBranch != branch { + if oldCommitID == objectFormat.Empty().String() && repo.DefaultBranch != branch { oldCommitID = repo.DefaultBranch } - if oldCommitID != git.EmptySHA { + if oldCommitID != objectFormat.Empty().String() { commits.CompareURL = repo.ComposeCompareURL(oldCommitID, opts.NewCommitID) } else { commits.CompareURL = "" diff --git a/services/webhook/slack.go b/services/webhook/slack.go index ac27b5bc71bcd..945b0662d84d3 100644 --- a/services/webhook/slack.go +++ b/services/webhook/slack.go @@ -92,6 +92,7 @@ func SlackLinkFormatter(url, text string) string { // SlackLinkToRef slack-formatter link to a repo ref func SlackLinkToRef(repoURL, ref string) string { + // FIXME: SHA1 hardcoded here url := git.RefURL(repoURL, ref) refName := git.RefName(ref).ShortName() return SlackLinkFormatter(url, refName) diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go index 18371efd0988c..ecda926ec1e2d 100644 --- a/services/wiki/wiki.go +++ b/services/wiki/wiki.go @@ -36,7 +36,7 @@ func InitWiki(ctx context.Context, repo *repo_model.Repository) error { return nil } - if err := git.InitRepository(ctx, repo.WikiPath(), true); err != nil { + if err := git.InitRepository(ctx, repo.WikiPath(), true, git.ObjectFormatFromID(git.Sha1)); err != nil { return fmt.Errorf("InitRepository: %w", err) } else if err = repo_module.CreateDelegateHooks(repo.WikiPath()); err != nil { return fmt.Errorf("createDelegateHooks: %w", err) diff --git a/services/wiki/wiki_test.go b/services/wiki/wiki_test.go index e8da176a08d2c..9981fb42583f3 100644 --- a/services/wiki/wiki_test.go +++ b/services/wiki/wiki_test.go @@ -302,7 +302,7 @@ func TestPrepareWikiFileName_FirstPage(t *testing.T) { // Now create a temporaryDirectory tmpDir := t.TempDir() - err := git.InitRepository(git.DefaultContext, tmpDir, true) + err := git.InitRepository(git.DefaultContext, tmpDir, true, git.ObjectFormatFromID(git.Sha1)) assert.NoError(t, err) gitRepo, err := git.OpenRepository(git.DefaultContext, tmpDir) diff --git a/tests/integration/git_helper_for_declarative_test.go b/tests/integration/git_helper_for_declarative_test.go index 10cf79b9fd8b2..de671dec19e98 100644 --- a/tests/integration/git_helper_for_declarative_test.go +++ b/tests/integration/git_helper_for_declarative_test.go @@ -120,7 +120,7 @@ func doGitCloneFail(u *url.URL) func(*testing.T) { func doGitInitTestRepository(dstPath string) func(*testing.T) { return func(t *testing.T) { // Init repository in dstPath - assert.NoError(t, git.InitRepository(git.DefaultContext, dstPath, false)) + assert.NoError(t, git.InitRepository(git.DefaultContext, dstPath, false, git.ObjectFormatFromID(git.Sha1))) // forcibly set default branch to master _, _, err := git.NewCommand(git.DefaultContext, "symbolic-ref", "HEAD", git.BranchPrefix+"master").RunStdString(&git.RunOpts{Dir: dstPath}) assert.NoError(t, err) From 52046b934dc619665bc51a59ad5ff9092fab118e Mon Sep 17 00:00:00 2001 From: nekrondev Date: Thu, 14 Dec 2023 03:39:32 +0100 Subject: [PATCH 23/60] Retry SSH key verification with additional CRLF if it failed (#28392) Windows-based shells will add a CRLF when piping the token into ssh-keygen command resulting in verification error. This resolves #21527. --------- Co-authored-by: Heiko Besemann Co-authored-by: wxiaoguang --- models/asymkey/ssh_key_verify.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/models/asymkey/ssh_key_verify.go b/models/asymkey/ssh_key_verify.go index e9f433248aaa9..208288c77b689 100644 --- a/models/asymkey/ssh_key_verify.go +++ b/models/asymkey/ssh_key_verify.go @@ -30,10 +30,15 @@ func VerifySSHKey(ctx context.Context, ownerID int64, fingerprint, token, signat return "", ErrKeyNotExist{} } - if err := sshsig.Verify(bytes.NewBuffer([]byte(token)), []byte(signature), []byte(key.Content), "gitea"); err != nil { - log.Error("Unable to validate token signature. Error: %v", err) - return "", ErrSSHInvalidTokenSignature{ - Fingerprint: key.Fingerprint, + err = sshsig.Verify(bytes.NewBuffer([]byte(token)), []byte(signature), []byte(key.Content), "gitea") + if err != nil { + // edge case for Windows based shells that will add CR LF if piped to ssh-keygen command + // see https://github.com/PowerShell/PowerShell/issues/5974 + if sshsig.Verify(bytes.NewBuffer([]byte(token+"\r\n")), []byte(signature), []byte(key.Content), "gitea") != nil { + log.Error("Unable to validate token signature. Error: %v", err) + return "", ErrSSHInvalidTokenSignature{ + Fingerprint: key.Fingerprint, + } } } From 9947af639c24d185ace096d3f25098ff94c0790e Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Thu, 14 Dec 2023 16:51:05 +0800 Subject: [PATCH 24/60] Only use SHA256 feature when git >= 2.42 (#28466) And fix some comments --- modules/git/git.go | 6 +++--- modules/git/object_format.go | 2 -- modules/git/object_id.go | 8 +++----- modules/git/repo.go | 7 +++++-- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/modules/git/git.go b/modules/git/git.go index 12d2f94e514cc..166655eb738f5 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -33,8 +33,8 @@ var ( // DefaultContext is the default context to run git commands in, must be initialized by git.InitXxx DefaultContext context.Context - // SupportProcReceive version >= 2.29.0 - SupportProcReceive bool + SupportProcReceive bool // >= 2.29 + SupportHashSha256 bool // >= 2.42, SHA-256 repositories no longer an ‘experimental curiosity’ gitVersion *version.Version ) @@ -189,7 +189,7 @@ func InitFull(ctx context.Context) (err error) { globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=") } SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil - + SupportHashSha256 = CheckGitVersionAtLeast("2.42") == nil if setting.LFS.StartServer { if CheckGitVersionAtLeast("2.1.2") != nil { return errors.New("LFS server support requires Git >= 2.1.2") diff --git a/modules/git/object_format.go b/modules/git/object_format.go index 7f5d09170c6fb..3c52de772bb37 100644 --- a/modules/git/object_format.go +++ b/modules/git/object_format.go @@ -40,7 +40,6 @@ type ObjectFormat interface { NewHasher() HasherInterface } -/* SHA1 Type */ type Sha1ObjectFormat struct{} func (*Sha1ObjectFormat) ID() ObjectFormatID { return Sha1 } @@ -83,7 +82,6 @@ func (h *Sha1ObjectFormat) NewHasher() HasherInterface { return &Sha1Hasher{sha1.New()} } -// utils func ObjectFormatFromID(id ObjectFormatID) ObjectFormat { switch id { case Sha1: diff --git a/modules/git/object_id.go b/modules/git/object_id.go index 3cba6d4f724db..21e1c67c646c2 100644 --- a/modules/git/object_id.go +++ b/modules/git/object_id.go @@ -20,7 +20,6 @@ type ObjectID interface { Type() ObjectFormat } -/* SHA1 */ type Sha1Hash [20]byte func (h *Sha1Hash) String() string { @@ -38,7 +37,7 @@ func NewSha1() *Sha1Hash { return &Sha1Hash{} } -// generic implementations +// NewHash is for generic implementations func NewHash(hash string) (ObjectID, error) { hash = strings.ToLower(hash) switch hash { @@ -73,7 +72,6 @@ func genericIDFromString(h ObjectFormat, s string) (ObjectID, error) { return h.NewID(b) } -// utils func IDFromString(hexHash string) (ObjectID, error) { switch len(hexHash) { case 40: @@ -101,7 +99,7 @@ func IsEmptyCommitID(commitID string) bool { return id.IsZero() } -// HashInterface is a struct that will generate a Hash +// HasherInterface is a struct that will generate a Hash type HasherInterface interface { hash.Hash @@ -127,7 +125,7 @@ func ComputeHash(hashType ObjectFormat, t ObjectType, content []byte) ObjectID { return h.HashSum() } -// Sum generates a SHA1 for the provided hash +// HashSum generates a SHA1 for the provided hash func (h *Sha1Hasher) HashSum() ObjectID { var sha1 Sha1Hash copy(sha1[:], h.Hash.Sum(nil)) diff --git a/modules/git/repo.go b/modules/git/repo.go index 871d267a5b84c..c036a217eb25c 100644 --- a/modules/git/repo.go +++ b/modules/git/repo.go @@ -63,7 +63,7 @@ func IsRepoURLAccessible(ctx context.Context, url string) bool { return err == nil } -// GetObjectFormatOfRepo returns the hash type of a repository at a given path +// GetObjectFormatOfRepo returns the hash type of repository at a given path func GetObjectFormatOfRepo(ctx context.Context, repoPath string) (ObjectFormat, error) { var stdout, stderr strings.Builder @@ -96,7 +96,10 @@ func InitRepository(ctx context.Context, repoPath string, bare bool, objectForma return err } - cmd := NewCommand(ctx, "init", "--object-format").AddDynamicArguments(objectFormat.String()) + cmd := NewCommand(ctx, "init") + if SupportHashSha256 { + cmd.AddOptionValues("--object-format", objectFormat.String()) + } if bare { cmd.AddArguments("--bare") } From e85db6c8c37bd0643deb704e857d369288a3ca0f Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Thu, 14 Dec 2023 16:52:16 +0800 Subject: [PATCH 25/60] Fix documents for "custom/public/assets/" (#28465) Fix #28463 --- docs/content/administration/adding-legal-pages.en-us.md | 4 ++-- docs/content/administration/adding-legal-pages.zh-cn.md | 4 ++-- docs/content/administration/customizing-gitea.zh-cn.md | 4 ++-- docs/content/administration/external-renderers.zh-cn.md | 2 +- docs/content/help/faq.zh-cn.md | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/content/administration/adding-legal-pages.en-us.md b/docs/content/administration/adding-legal-pages.en-us.md index c6f68edcd0e5e..1ff0c0132d296 100644 --- a/docs/content/administration/adding-legal-pages.en-us.md +++ b/docs/content/administration/adding-legal-pages.en-us.md @@ -19,10 +19,10 @@ Some jurisdictions (such as EU), requires certain legal pages (e.g. Privacy Poli ## Getting Pages -Gitea source code ships with sample pages, available in `contrib/legal` directory. Copy them to `custom/public/`. For example, to add Privacy Policy: +Gitea source code ships with sample pages, available in `contrib/legal` directory. Copy them to `custom/public/assets/`. For example, to add Privacy Policy: ``` -wget -O /path/to/custom/public/privacy.html https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/legal/privacy.html.sample +wget -O /path/to/custom/public/assets/privacy.html https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/legal/privacy.html.sample ``` Now you need to edit the page to meet your requirements. In particular you must change the email addresses, web addresses and references to "Your Gitea Instance" to match your situation. diff --git a/docs/content/administration/adding-legal-pages.zh-cn.md b/docs/content/administration/adding-legal-pages.zh-cn.md index 5d582e871de56..3e18c6e6b03b1 100644 --- a/docs/content/administration/adding-legal-pages.zh-cn.md +++ b/docs/content/administration/adding-legal-pages.zh-cn.md @@ -19,10 +19,10 @@ menu: ## 获取页面 -Gitea 源代码附带了示例页面,位于 `contrib/legal` 目录中。将它们复制到 `custom/public/` 目录下。例如,如果要添加隐私政策: +Gitea 源代码附带了示例页面,位于 `contrib/legal` 目录中。将它们复制到 `custom/public/assets/` 目录下。例如,如果要添加隐私政策: ``` -wget -O /path/to/custom/public/privacy.html https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/legal/privacy.html.sample +wget -O /path/to/custom/public/assets/privacy.html https://raw.githubusercontent.com/go-gitea/gitea/main/contrib/legal/privacy.html.sample ``` 现在,你需要编辑该页面以满足你的需求。特别是,你必须更改电子邮件地址、网址以及与 "Your Gitea Instance" 相关的引用,以匹配你的情况。 diff --git a/docs/content/administration/customizing-gitea.zh-cn.md b/docs/content/administration/customizing-gitea.zh-cn.md index d828704557cfa..f41533c69cb75 100644 --- a/docs/content/administration/customizing-gitea.zh-cn.md +++ b/docs/content/administration/customizing-gitea.zh-cn.md @@ -42,11 +42,11 @@ Gitea 引用 `custom` 目录中的自定义配置文件来覆盖配置、模板 将自定义的公共文件(比如页面和图片)作为 webroot 放在 `custom/public/` 中来让 Gitea 提供这些自定义内容(符号链接将被追踪)。 -举例说明:`image.png` 存放在 `custom/public/`中,那么它可以通过链接 http://gitea.domain.tld/assets/image.png 访问。 +举例说明:`image.png` 存放在 `custom/public/assets/`中,那么它可以通过链接 http://gitea.domain.tld/assets/image.png 访问。 ## 修改默认头像 -替换以下目录中的 png 图片: `custom/public/img/avatar\_default.png` +替换以下目录中的 png 图片: `custom/public/assets/img/avatar\_default.png` ## 自定义 Gitea 页面 diff --git a/docs/content/administration/external-renderers.zh-cn.md b/docs/content/administration/external-renderers.zh-cn.md index 0b53b452776a2..fdf7315d7b7b2 100644 --- a/docs/content/administration/external-renderers.zh-cn.md +++ b/docs/content/administration/external-renderers.zh-cn.md @@ -194,7 +194,7 @@ ALLOW_DATA_URI_IMAGES = true } ``` -将您的样式表添加到自定义目录中,例如 `custom/public/css/my-style-XXXXX.css`,并使用自定义的头文件 `custom/templates/custom/header.tmpl` 进行导入: +将您的样式表添加到自定义目录中,例如 `custom/public/assets/css/my-style-XXXXX.css`,并使用自定义的头文件 `custom/templates/custom/header.tmpl` 进行导入: ```html diff --git a/docs/content/help/faq.zh-cn.md b/docs/content/help/faq.zh-cn.md index 096ac05f48beb..d7847a148de70 100644 --- a/docs/content/help/faq.zh-cn.md +++ b/docs/content/help/faq.zh-cn.md @@ -189,7 +189,7 @@ Gitea 目前支持三个官方主题,分别是 `gitea-light`、`gitea-dark` 假设我们的主题是 `arc-blue`(这是一个真实的主题,可以在[此问题](https://github.com/go-gitea/gitea/issues/6011)中找到) -将`.css`文件命名为`theme-arc-blue.css`并将其添加到`custom/public/css`文件夹中 +将`.css`文件命名为`theme-arc-blue.css`并将其添加到`custom/public/assets/css`文件夹中 通过将`arc-blue`添加到`app.ini`中的`THEMES`列表中,允许用户使用该主题 From e08f1a9cbd582c73918e401eeba36261627f44a7 Mon Sep 17 00:00:00 2001 From: sebastian-sauer Date: Thu, 14 Dec 2023 10:26:59 +0100 Subject: [PATCH 26/60] Add combined index for issue_user.uid and issue_id (#28080) fixes #27877 --------- Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Lunny Xiao --- models/issues/issue_user.go | 4 +-- .../issue_user.yml | 20 +++++++++++ models/migrations/migrations.go | 2 ++ models/migrations/v1_22/main_test.go | 14 ++++++++ models/migrations/v1_22/v283.go | 34 +++++++++++++++++++ models/migrations/v1_22/v283_test.go | 28 +++++++++++++++ 6 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 models/migrations/fixtures/Test_AddCombinedIndexToIssueUser/issue_user.yml create mode 100644 models/migrations/v1_22/main_test.go create mode 100644 models/migrations/v1_22/v283.go create mode 100644 models/migrations/v1_22/v283_test.go diff --git a/models/issues/issue_user.go b/models/issues/issue_user.go index 24bb74648d9ce..6b59e0725edeb 100644 --- a/models/issues/issue_user.go +++ b/models/issues/issue_user.go @@ -14,8 +14,8 @@ import ( // IssueUser represents an issue-user relation. type IssueUser struct { ID int64 `xorm:"pk autoincr"` - UID int64 `xorm:"INDEX"` // User ID. - IssueID int64 `xorm:"INDEX"` + UID int64 `xorm:"INDEX unique(uid_to_issue)"` // User ID. + IssueID int64 `xorm:"INDEX unique(uid_to_issue)"` IsRead bool IsMentioned bool } diff --git a/models/migrations/fixtures/Test_AddCombinedIndexToIssueUser/issue_user.yml b/models/migrations/fixtures/Test_AddCombinedIndexToIssueUser/issue_user.yml new file mode 100644 index 0000000000000..7bbb6f2f307f4 --- /dev/null +++ b/models/migrations/fixtures/Test_AddCombinedIndexToIssueUser/issue_user.yml @@ -0,0 +1,20 @@ +- + id: 1 + uid: 1 + issue_id: 1 + is_read: true + is_mentioned: false + +- + id: 2 + uid: 2 + issue_id: 1 + is_read: true + is_mentioned: false + +- + id: 3 + uid: 2 + issue_id: 1 # duplicated with id 2 + is_read: false + is_mentioned: true diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 28e3be503b299..578cbca035d85 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -550,6 +550,8 @@ var migrations = []Migration{ NewMigration("Add auth_token table", v1_22.CreateAuthTokenTable), // v282 -> v283 NewMigration("Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID), + // v283 -> v284 + NewMigration("Add combined Index to issue_user.uid and issue_id", v1_22.AddCombinedIndexToIssueUser), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v1_22/main_test.go b/models/migrations/v1_22/main_test.go new file mode 100644 index 0000000000000..efd8dbaa8c6b5 --- /dev/null +++ b/models/migrations/v1_22/main_test.go @@ -0,0 +1,14 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_22 //nolint + +import ( + "testing" + + "code.gitea.io/gitea/models/migrations/base" +) + +func TestMain(m *testing.M) { + base.MainTest(m) +} diff --git a/models/migrations/v1_22/v283.go b/models/migrations/v1_22/v283.go new file mode 100644 index 0000000000000..b2b94845d905e --- /dev/null +++ b/models/migrations/v1_22/v283.go @@ -0,0 +1,34 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_22 //nolint + +import ( + "xorm.io/xorm" +) + +func AddCombinedIndexToIssueUser(x *xorm.Engine) error { + type OldIssueUser struct { + IssueID int64 + UID int64 + Cnt int64 + } + + var duplicatedIssueUsers []OldIssueUser + if err := x.SQL("select * from (select issue_id, uid, count(1) as cnt from issue_user group by issue_id, uid) a where a.cnt > 1"). + Find(&duplicatedIssueUsers); err != nil { + return err + } + for _, issueUser := range duplicatedIssueUsers { + if _, err := x.Exec("delete from issue_user where id in (SELECT id FROM issue_user WHERE issue_id = ? and uid = ? limit ?)", issueUser.IssueID, issueUser.UID, issueUser.Cnt-1); err != nil { + return err + } + } + + type IssueUser struct { + UID int64 `xorm:"INDEX unique(uid_to_issue)"` // User ID. + IssueID int64 `xorm:"INDEX unique(uid_to_issue)"` + } + + return x.Sync(&IssueUser{}) +} diff --git a/models/migrations/v1_22/v283_test.go b/models/migrations/v1_22/v283_test.go new file mode 100644 index 0000000000000..864f47f840c01 --- /dev/null +++ b/models/migrations/v1_22/v283_test.go @@ -0,0 +1,28 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_22 //nolint + +import ( + "testing" + + "code.gitea.io/gitea/models/migrations/base" +) + +func Test_AddCombinedIndexToIssueUser(t *testing.T) { + type IssueUser struct { + UID int64 `xorm:"INDEX unique(uid_to_issue)"` // User ID. + IssueID int64 `xorm:"INDEX unique(uid_to_issue)"` + } + + // Prepare and load the testing database + x, deferable := base.PrepareTestEnv(t, 0, new(IssueUser)) + defer deferable() + if x == nil || t.Failed() { + return + } + + if err := AddCombinedIndexToIssueUser(x); err != nil { + t.Fatal(err) + } +} From 8c91e315406730937322fcbeea5115c6ac3f82c2 Mon Sep 17 00:00:00 2001 From: CaiCandong <50507092+CaiCandong@users.noreply.github.com> Date: Fri, 15 Dec 2023 00:00:04 +0800 Subject: [PATCH 27/60] Fix Chinese translation of config cheat sheet[API] (#28472) --- docs/content/administration/config-cheat-sheet.zh-cn.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/content/administration/config-cheat-sheet.zh-cn.md b/docs/content/administration/config-cheat-sheet.zh-cn.md index c4e3876c1fedc..eed752c1cbd7d 100644 --- a/docs/content/administration/config-cheat-sheet.zh-cn.md +++ b/docs/content/administration/config-cheat-sheet.zh-cn.md @@ -1039,10 +1039,11 @@ Gitea 创建以下非唯一队列: ## API (`api`) -- `ENABLE_SWAGGER`: **true**: 是否启用swagger路由 (`/api/swagger`, `/api/v1/swagger`, …)。 -- `MAX_RESPONSE_ITEMS`: **50**: 单个页面的最大 Feed. -- `ENABLE_OPENID_SIGNIN`: **false**: 允许使用OpenID登录,当设置为`true`时可以通过 `/user/login` 页面进行OpenID登录。 -- `DISABLE_REGISTRATION`: **false**: 关闭用户注册。 +- `ENABLE_SWAGGER`: **true**: 启用API文档接口 (`/api/swagger`, `/api/v1/swagger`, …). True or false。 +- `MAX_RESPONSE_ITEMS`: **50**: API分页的最大单页项目数。 +- `DEFAULT_PAGING_NUM`: **30**: API分页的默认分页数。 +- `DEFAULT_GIT_TREES_PER_PAGE`: **1000**: Git trees API的默认单页项目数。 +- `DEFAULT_MAX_BLOB_SIZE`: **10485760** (10MiB): blobs API的默认最大文件大小。 ## OAuth2 (`oauth2`) From 6632d1497c9fc644c696e9a1239cd62baa5dc29e Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 15 Dec 2023 07:26:36 +0800 Subject: [PATCH 28/60] Polyfill SubmitEvent for PaleMoon (#28441) --- web_src/js/features/common-global.js | 6 ++++-- web_src/js/features/common-issue-list.js | 4 ++-- web_src/js/features/repo-diff.js | 3 ++- web_src/js/modules/tippy.js | 2 +- web_src/js/utils/dom.js | 21 +++++++++++++++++++++ web_src/js/webcomponents/webcomponents.js | 2 +- 6 files changed, 31 insertions(+), 7 deletions(-) diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js index c2e0111849b08..0b00eb8e8ea74 100644 --- a/web_src/js/features/common-global.js +++ b/web_src/js/features/common-global.js @@ -6,7 +6,7 @@ import {initCompColorPicker} from './comp/ColorPicker.js'; import {showGlobalErrorMessage} from '../bootstrap.js'; import {handleGlobalEnterQuickSubmit} from './comp/QuickSubmit.js'; import {svg} from '../svg.js'; -import {hideElem, showElem, toggleElem} from '../utils/dom.js'; +import {hideElem, showElem, toggleElem, initSubmitEventPolyfill, submitEventSubmitter} from '../utils/dom.js'; import {htmlEscape} from 'escape-goat'; import {showTemporaryTooltip} from '../modules/tippy.js'; import {confirmModal} from './comp/ConfirmModal.js'; @@ -121,7 +121,8 @@ async function formFetchAction(e) { const formMethod = formEl.getAttribute('method') || 'get'; const formActionUrl = formEl.getAttribute('action'); const formData = new FormData(formEl); - const [submitterName, submitterValue] = [e.submitter?.getAttribute('name'), e.submitter?.getAttribute('value')]; + const formSubmitter = submitEventSubmitter(e); + const [submitterName, submitterValue] = [formSubmitter?.getAttribute('name'), formSubmitter?.getAttribute('value')]; if (submitterName) { formData.append(submitterName, submitterValue || ''); } @@ -192,6 +193,7 @@ export function initGlobalCommon() { $('.tabular.menu .item').tab(); + initSubmitEventPolyfill(); document.addEventListener('submit', formFetchAction); document.addEventListener('click', linkAction); } diff --git a/web_src/js/features/common-issue-list.js b/web_src/js/features/common-issue-list.js index 3a28cf900ca5c..317c11219bd27 100644 --- a/web_src/js/features/common-issue-list.js +++ b/web_src/js/features/common-issue-list.js @@ -1,5 +1,5 @@ import $ from 'jquery'; -import {isElemHidden, onInputDebounce, toggleElem} from '../utils/dom.js'; +import {isElemHidden, onInputDebounce, submitEventSubmitter, toggleElem} from '../utils/dom.js'; import {GET} from '../modules/fetch.js'; const {appSubUrl} = window.config; @@ -40,7 +40,7 @@ export function initCommonIssueListQuickGoto() { $form.on('submit', (e) => { // if there is no goto button, or the form is submitted by non-quick-goto elements, submit the form directly let doQuickGoto = !isElemHidden($goto); - const submitter = e.originalEvent.submitter; + const submitter = submitEventSubmitter(e.originalEvent); if (submitter !== $form[0] && submitter !== $input[0] && submitter !== $goto[0]) doQuickGoto = false; if (!doQuickGoto) return; diff --git a/web_src/js/features/repo-diff.js b/web_src/js/features/repo-diff.js index e74db04d08ff3..eeb80e91b2cc5 100644 --- a/web_src/js/features/repo-diff.js +++ b/web_src/js/features/repo-diff.js @@ -7,6 +7,7 @@ import {validateTextareaNonEmpty} from './comp/ComboMarkdownEditor.js'; import {initViewedCheckboxListenerFor, countAndUpdateViewedFiles, initExpandAndCollapseFilesButton} from './pull-view-file.js'; import {initImageDiff} from './imagediff.js'; import {showErrorToast} from '../modules/toast.js'; +import {submitEventSubmitter} from '../utils/dom.js'; const {csrfToken, pageData, i18n} = window.config; @@ -57,7 +58,7 @@ function initRepoDiffConversationForm() { const formData = new FormData($form[0]); // if the form is submitted by a button, append the button's name and value to the form data - const submitter = e.originalEvent?.submitter; + const submitter = submitEventSubmitter(e.originalEvent); const isSubmittedByButton = (submitter?.nodeName === 'BUTTON') || (submitter?.nodeName === 'INPUT' && submitter.type === 'submit'); if (isSubmittedByButton && submitter.name) { formData.append(submitter.name, submitter.value); diff --git a/web_src/js/modules/tippy.js b/web_src/js/modules/tippy.js index d27908962f53a..7f8423e3191cf 100644 --- a/web_src/js/modules/tippy.js +++ b/web_src/js/modules/tippy.js @@ -106,7 +106,7 @@ function switchTitleToTooltip(target) { /** * Creating tooltip tippy instance is expensive, so we only create it when the user hovers over the element * According to https://www.w3.org/TR/DOM-Level-3-Events/#events-mouseevent-event-order , mouseover event is fired before mouseenter event - * Some old browsers like Pale Moon doesn't support "mouseenter(capture)" + * Some browsers like PaleMoon don't support "addEventListener('mouseenter', capture)" * The tippy by default uses "mouseenter" event to show, so we use "mouseover" event to switch to tippy * @param e {Event} */ diff --git a/web_src/js/utils/dom.js b/web_src/js/utils/dom.js index 403933883ad23..64a6a5affc482 100644 --- a/web_src/js/utils/dom.js +++ b/web_src/js/utils/dom.js @@ -194,3 +194,24 @@ export function loadElem(el, src) { el.src = src; }); } + +// some browsers like PaleMoon don't have "SubmitEvent" support, so polyfill it by a tricky method: use the last clicked button as submitter +// it can't use other transparent polyfill patches because PaleMoon also doesn't support "addEventListener(capture)" +const needSubmitEventPolyfill = typeof SubmitEvent === 'undefined'; + +export function submitEventSubmitter(e) { + return needSubmitEventPolyfill ? (e.target._submitter || null) : e.submitter; +} + +function submitEventPolyfillListener(e) { + const form = e.target.closest('form'); + if (!form) return; + form._submitter = e.target.closest('button:not([type]), button[type="submit"], input[type="submit"]'); +} + +export function initSubmitEventPolyfill() { + if (!needSubmitEventPolyfill) return; + console.warn(`This browser doesn't have "SubmitEvent" support, use a tricky method to polyfill`); + document.body.addEventListener('click', submitEventPolyfillListener); + document.body.addEventListener('focus', submitEventPolyfillListener); +} diff --git a/web_src/js/webcomponents/webcomponents.js b/web_src/js/webcomponents/webcomponents.js index b17a4a832f704..916a588db64bf 100644 --- a/web_src/js/webcomponents/webcomponents.js +++ b/web_src/js/webcomponents/webcomponents.js @@ -1,4 +1,4 @@ -import '@webcomponents/custom-elements'; // polyfill for some browsers like Pale Moon +import '@webcomponents/custom-elements'; // polyfill for some browsers like PaleMoon import './polyfill.js'; import '@github/relative-time-element'; From 4f04ab25867ee1b4f20241798bf90a588083ec6b Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 15 Dec 2023 14:18:12 +0800 Subject: [PATCH 29/60] Refactor SSH clone URL generation code (#28421) Refactor the code and add tests, keep the old logic. --- models/repo/repo.go | 24 +++++++++++------------- models/repo/repo_test.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/models/repo/repo.go b/models/repo/repo.go index 59f68df996a46..f739ada307797 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -606,25 +606,23 @@ func ComposeHTTPSCloneURL(owner, repo string) string { func ComposeSSHCloneURL(ownerName, repoName string) string { sshUser := setting.SSH.User - - // if we have a ipv6 literal we need to put brackets around it - // for the git cloning to work. sshDomain := setting.SSH.Domain - ip := net.ParseIP(setting.SSH.Domain) - if ip != nil && ip.To4() == nil { - sshDomain = "[" + setting.SSH.Domain + "]" - } + // non-standard port, it must use full URI if setting.SSH.Port != 22 { - return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, - net.JoinHostPort(setting.SSH.Domain, strconv.Itoa(setting.SSH.Port)), - url.PathEscape(ownerName), - url.PathEscape(repoName)) + sshHost := net.JoinHostPort(sshDomain, strconv.Itoa(setting.SSH.Port)) + return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName)) + } + + // for standard port, it can use a shorter URI (without the port) + sshHost := sshDomain + if ip := net.ParseIP(sshHost); ip != nil && ip.To4() == nil { + sshHost = "[" + sshHost + "]" // for IPv6 address, wrap it with brackets } if setting.Repository.UseCompatSSHURI { - return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshDomain, url.PathEscape(ownerName), url.PathEscape(repoName)) + return fmt.Sprintf("ssh://%s@%s/%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName)) } - return fmt.Sprintf("%s@%s:%s/%s.git", sshUser, sshDomain, url.PathEscape(ownerName), url.PathEscape(repoName)) + return fmt.Sprintf("%s@%s:%s/%s.git", sshUser, sshHost, url.PathEscape(ownerName), url.PathEscape(repoName)) } func (repo *Repository) cloneLink(isWiki bool) *CloneLink { diff --git a/models/repo/repo_test.go b/models/repo/repo_test.go index 4bbfeb634a798..ca9209d75153d 100644 --- a/models/repo/repo_test.go +++ b/models/repo/repo_test.go @@ -12,6 +12,8 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/markup" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" @@ -186,3 +188,32 @@ func TestGetRepositoryByURL(t *testing.T) { test(t, "try.gitea.io:user2/repo2.git") }) } + +func TestComposeSSHCloneURL(t *testing.T) { + defer test.MockVariableValue(&setting.SSH, setting.SSH)() + defer test.MockVariableValue(&setting.Repository, setting.Repository)() + + setting.SSH.User = "git" + + // test SSH_DOMAIN + setting.SSH.Domain = "domain" + setting.SSH.Port = 22 + setting.Repository.UseCompatSSHURI = false + assert.Equal(t, "git@domain:user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + setting.Repository.UseCompatSSHURI = true + assert.Equal(t, "ssh://git@domain/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + // test SSH_DOMAIN while use non-standard SSH port + setting.SSH.Port = 123 + setting.Repository.UseCompatSSHURI = false + assert.Equal(t, "ssh://git@domain:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + setting.Repository.UseCompatSSHURI = true + assert.Equal(t, "ssh://git@domain:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + + // test IPv6 SSH_DOMAIN + setting.Repository.UseCompatSSHURI = false + setting.SSH.Domain = "::1" + setting.SSH.Port = 22 + assert.Equal(t, "git@[::1]:user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) + setting.SSH.Port = 123 + assert.Equal(t, "ssh://git@[::1]:123/user/repo.git", repo_model.ComposeSSHCloneURL("user", "repo")) +} From 3849fd2ac2163b109f9dc1e873ffb9bc8f53c63b Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Fri, 15 Dec 2023 23:13:55 +0900 Subject: [PATCH 30/60] Remove unnecessary forgot password link in delete user section (#28355) Before: image After: ![image](https://github.com/go-gitea/gitea/assets/18380374/d96ed908-47ad-44cc-a624-4c10fa8c8c86) --- templates/user/settings/account.tmpl | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/user/settings/account.tmpl b/templates/user/settings/account.tmpl index 6e8386988ab80..7c6fd49a08cba 100644 --- a/templates/user/settings/account.tmpl +++ b/templates/user/settings/account.tmpl @@ -149,7 +149,6 @@ - {{ctx.Locale.Tr "auth.forgot_password"}}
From 047c69bd85bc5579ce6f352d7edf7fb950d84b80 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 15 Dec 2023 23:49:01 +0800 Subject: [PATCH 31/60] Improve CLI code and descriptions (#28482) * Close #28444 * Actually, it doesn't need to use that trick because it looks like it is not necessary, no user really needs it * Remove the hidden (legacy) "doctor" subcommand and update documents * Fix "actions" usage ![image](https://github.com/go-gitea/gitea/assets/2114189/3c2b34a7-4f92-4a6c-96fd-9505e413d4ec) --- cmd/actions.go | 5 ++--- cmd/admin.go | 2 +- cmd/doctor.go | 2 +- cmd/generate.go | 2 +- cmd/hook.go | 4 ++-- cmd/keys.go | 9 +++++---- cmd/main.go | 21 ++++++--------------- cmd/serv.go | 2 +- docs/content/help/faq.en-us.md | 4 ++-- docs/content/help/faq.zh-cn.md | 7 +++---- go.mod | 2 +- go.sum | 4 ++-- 12 files changed, 27 insertions(+), 37 deletions(-) diff --git a/cmd/actions.go b/cmd/actions.go index 052afb9ebc3f5..275fd7904eaec 100644 --- a/cmd/actions.go +++ b/cmd/actions.go @@ -15,9 +15,8 @@ import ( var ( // CmdActions represents the available actions sub-commands. CmdActions = &cli.Command{ - Name: "actions", - Usage: "", - Description: "Commands for managing Gitea Actions", + Name: "actions", + Usage: "Manage Gitea Actions", Subcommands: []*cli.Command{ subcmdActionsGenRunnerToken, }, diff --git a/cmd/admin.go b/cmd/admin.go index 49d0e4ef74aca..b5903cd4fd759 100644 --- a/cmd/admin.go +++ b/cmd/admin.go @@ -21,7 +21,7 @@ var ( // CmdAdmin represents the available admin sub-command. CmdAdmin = &cli.Command{ Name: "admin", - Usage: "Command line interface to perform common administrative operations", + Usage: "Perform common administrative operations", Subcommands: []*cli.Command{ subcmdUser, subcmdRepoSyncReleases, diff --git a/cmd/doctor.go b/cmd/doctor.go index 4085d37332478..f891b126082df 100644 --- a/cmd/doctor.go +++ b/cmd/doctor.go @@ -26,7 +26,7 @@ import ( // CmdDoctor represents the available doctor sub-command. var CmdDoctor = &cli.Command{ Name: "doctor", - Usage: "Diagnose and optionally fix problems", + Usage: "Diagnose and optionally fix problems, convert or re-create database tables", Description: "A command to diagnose problems with the current Gitea instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.", Subcommands: []*cli.Command{ diff --git a/cmd/generate.go b/cmd/generate.go index 5922617217af6..4ab10da22afaf 100644 --- a/cmd/generate.go +++ b/cmd/generate.go @@ -18,7 +18,7 @@ var ( // CmdGenerate represents the available generate sub-command. CmdGenerate = &cli.Command{ Name: "generate", - Usage: "Command line interface for running generators", + Usage: "Generate Gitea's secrets/keys/tokens", Subcommands: []*cli.Command{ subcmdSecret, }, diff --git a/cmd/hook.go b/cmd/hook.go index 624569cdfa7ea..6f31c326fd066 100644 --- a/cmd/hook.go +++ b/cmd/hook.go @@ -31,8 +31,8 @@ var ( // CmdHook represents the available hooks sub-command. CmdHook = &cli.Command{ Name: "hook", - Usage: "Delegate commands to corresponding Git hooks", - Description: "This should only be called by Git", + Usage: "(internal) Should only be called by Git", + Description: "Delegate commands to corresponding Git hooks", Before: PrepareConsoleLoggerLevel(log.FATAL), Subcommands: []*cli.Command{ subcmdHookPreReceive, diff --git a/cmd/keys.go b/cmd/keys.go index b8467825293f1..9d5278f1099ed 100644 --- a/cmd/keys.go +++ b/cmd/keys.go @@ -16,10 +16,11 @@ import ( // CmdKeys represents the available keys sub-command var CmdKeys = &cli.Command{ - Name: "keys", - Usage: "This command queries the Gitea database to get the authorized command for a given ssh key fingerprint", - Before: PrepareConsoleLoggerLevel(log.FATAL), - Action: runKeys, + Name: "keys", + Usage: "(internal) Should only be called by SSH server", + Description: "Queries the Gitea database to get the authorized command for a given ssh key fingerprint", + Before: PrepareConsoleLoggerLevel(log.FATAL), + Action: runKeys, Flags: []cli.Flag{ &cli.StringFlag{ Name: "expected", diff --git a/cmd/main.go b/cmd/main.go index feda41e68b24a..02dd660e9eec4 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -10,12 +10,12 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/util" "github.com/urfave/cli/v2" ) // cmdHelp is our own help subcommand with more information +// Keep in mind that the "./gitea help"(subcommand) is different from "./gitea --help"(flag), the flag doesn't parse the config or output "DEFAULT CONFIGURATION:" information func cmdHelp() *cli.Command { c := &cli.Command{ Name: "help", @@ -47,16 +47,10 @@ DEFAULT CONFIGURATION: return c } -var helpFlag = cli.HelpFlag - -func init() { - // cli.HelpFlag = nil TODO: after https://github.com/urfave/cli/issues/1794 we can use this -} - func appGlobalFlags() []cli.Flag { return []cli.Flag{ // make the builtin flags at the top - helpFlag, + cli.HelpFlag, // shared configuration flags, they are for global and for each sub-command at the same time // eg: such command is valid: "./gitea --config /tmp/app.ini web --config /tmp/app.ini", while it's discouraged indeed @@ -121,20 +115,22 @@ func prepareWorkPathAndCustomConf(action cli.ActionFunc) func(ctx *cli.Context) func NewMainApp(version, versionExtra string) *cli.App { app := cli.NewApp() app.Name = "Gitea" + app.HelpName = "gitea" app.Usage = "A painless self-hosted Git service" - app.Description = `By default, Gitea will start serving using the web-server with no argument, which can alternatively be run by running the subcommand "web".` + app.Description = `Gitea program contains "web" and other subcommands. If no subcommand is given, it starts the web server by default. Use "web" subcommand for more web server arguments, use other subcommands for other purposes.` app.Version = version + versionExtra app.EnableBashCompletion = true // these sub-commands need to use config file subCmdWithConfig := []*cli.Command{ + cmdHelp(), // the "help" sub-command was used to show the more information for "work path" and "custom config" CmdWeb, CmdServ, CmdHook, + CmdKeys, CmdDump, CmdAdmin, CmdMigrate, - CmdKeys, CmdDoctor, CmdManager, CmdEmbedded, @@ -142,13 +138,8 @@ func NewMainApp(version, versionExtra string) *cli.App { CmdDumpRepository, CmdRestoreRepository, CmdActions, - cmdHelp(), // the "help" sub-command was used to show the more information for "work path" and "custom config" } - cmdConvert := util.ToPointer(*cmdDoctorConvert) - cmdConvert.Hidden = true // still support the legacy "./gitea doctor" by the hidden sub-command, remove it in next release - subCmdWithConfig = append(subCmdWithConfig, cmdConvert) - // these sub-commands do not need the config file, and they do not depend on any path or environment variable. subCmdStandalone := []*cli.Command{ CmdCert, diff --git a/cmd/serv.go b/cmd/serv.go index 26fc91a3b7a30..726663660b08e 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -42,7 +42,7 @@ const ( // CmdServ represents the available serv sub-command. var CmdServ = &cli.Command{ Name: "serv", - Usage: "This command should only be called by SSH shell", + Usage: "(internal) Should only be called by SSH shell", Description: "Serv provides access auth for repositories", Before: PrepareConsoleLoggerLevel(log.FATAL), Action: runServ, diff --git a/docs/content/help/faq.en-us.md b/docs/content/help/faq.en-us.md index 93b3434f476a8..e6350936ef816 100644 --- a/docs/content/help/faq.en-us.md +++ b/docs/content/help/faq.en-us.md @@ -362,7 +362,7 @@ If you are receiving errors on upgrade of Gitea using MySQL that read: > `ORM engine initialization failed: migrate: do migrate: Error: 1118: Row size too large...` -Please run `gitea convert` or run `ALTER TABLE table_name ROW_FORMAT=dynamic;` for each table in the database. +Please run `gitea doctor convert` or run `ALTER TABLE table_name ROW_FORMAT=dynamic;` for each table in the database. The underlying problem is that the space allocated for indices by the default row format is too small. Gitea requires that the `ROWFORMAT` for its tables is `DYNAMIC`. @@ -385,7 +385,7 @@ Unfortunately MySQL's `utf8` charset does not completely allow all possible UTF- They created a new charset and collation called `utf8mb4` that allows for emoji to be stored but tables which use the `utf8` charset, and connections which use the `utf8` charset will not use this. -Please run `gitea convert`, or run `ALTER DATABASE database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;` +Please run `gitea doctor convert`, or run `ALTER DATABASE database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;` for the database_name and run `ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;` for each table in the database. diff --git a/docs/content/help/faq.zh-cn.md b/docs/content/help/faq.zh-cn.md index d7847a148de70..909ca7e5e2138 100644 --- a/docs/content/help/faq.zh-cn.md +++ b/docs/content/help/faq.zh-cn.md @@ -366,7 +366,7 @@ Gitea 提供了一个子命令`gitea migrate`来初始化数据库,然后您 > `ORM engine initialization failed: migrate: do migrate: Error: 1118: Row size too large...` -请运行`gitea convert`或对数据库中的每个表运行`ALTER TABLE table_name ROW_FORMAT=dynamic;`。 +请运行 `gitea doctor convert` 或对数据库中的每个表运行 `ALTER TABLE table_name ROW_FORMAT=dynamic;`。 潜在问题是默认行格式分配给每个表的索引空间 太小。Gitea 要求其表的`ROWFORMAT`为`DYNAMIC`。 @@ -389,9 +389,8 @@ SET GLOBAL innodb_large_prefix=1; 他们创建了一个名为 `utf8mb4`的字符集和校对规则,允许存储 Emoji,但使用 utf8 字符集的表和连接将不会使用它。 -请运行 `gitea convert` 或对数据库运行`ALTER DATABASE database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;` -并对每个表运行 -`ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;`。 +请运行 `gitea doctor convert` 或对数据库运行 `ALTER DATABASE database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;` +并对每个表运行 `ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;`。 您还需要将`app.ini`文件中的数据库字符集设置为`CHARSET=utf8mb4`。 diff --git a/go.mod b/go.mod index 97997cad6d566..569f8cd359156 100644 --- a/go.mod +++ b/go.mod @@ -99,7 +99,7 @@ require ( github.com/syndtr/goleveldb v1.0.0 github.com/tstranex/u2f v1.0.0 github.com/ulikunitz/xz v0.5.11 - github.com/urfave/cli/v2 v2.25.7 + github.com/urfave/cli/v2 v2.26.0 github.com/xanzy/go-gitlab v0.93.1 github.com/xeipuuv/gojsonschema v1.2.0 github.com/yohcop/openid-go v1.0.1 diff --git a/go.sum b/go.sum index fbe4fe06e568e..9c9defb12aef7 100644 --- a/go.sum +++ b/go.sum @@ -1023,8 +1023,8 @@ github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs= github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= -github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= -github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/cli/v2 v2.26.0 h1:3f3AMg3HpThFNT4I++TKOejZO8yU55t3JnnSr4S4QEI= +github.com/urfave/cli/v2 v2.26.0/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= From b8490d59deeb25aa6f03e77863c0c7ed7abdbb98 Mon Sep 17 00:00:00 2001 From: Kyle D Date: Fri, 15 Dec 2023 21:54:35 -0500 Subject: [PATCH 32/60] Update docs for DISABLE_QUERY_AUTH_TOKEN (#28485) As described [here](https://github.com/go-gitea/gitea/pull/28390#issuecomment-1857553331). --- docs/content/administration/config-cheat-sheet.en-us.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index c9e6a937c3482..1fa8dacb67e25 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -572,6 +572,7 @@ And the following unique queues: - off - do not check password complexity - `PASSWORD_CHECK_PWN`: **false**: Check [HaveIBeenPwned](https://haveibeenpwned.com/Passwords) to see if a password has been exposed. - `SUCCESSFUL_TOKENS_CACHE_SIZE`: **20**: Cache successful token hashes. API tokens are stored in the DB as pbkdf2 hashes however, this means that there is a potentially significant hashing load when there are multiple API operations. This cache will store the successfully hashed tokens in a LRU cache as a balance between performance and security. +- `DISABLE_QUERY_AUTH_TOKEN`: **false**: Reject API tokens sent in URL query string (Accept Header-based API tokens only). This setting will default to `true` in Gitea 1.23 and be deprecated in Gitea 1.24. ## Camo (`camo`) From 9a15267871dcb1f1f8b39115b8e68ed1f42bf21d Mon Sep 17 00:00:00 2001 From: Earl Warren <109468362+earl-warren@users.noreply.github.com> Date: Sat, 16 Dec 2023 13:17:39 +0100 Subject: [PATCH 33/60] Initalize stroage for orphaned repository doctor (#28487) - When a repository is orphaned and has objects stored in any of the storages such as repository avatar or attachments the delete function would error, because the storage module wasn't initalized. - Add code to initialize the storage module. Refs: https://codeberg.org/forgejo/forgejo/pulls/1954 Co-authored-by: Gusted --- modules/doctor/repository.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/doctor/repository.go b/modules/doctor/repository.go index b3a03aa422d22..6c33426636e7b 100644 --- a/modules/doctor/repository.go +++ b/modules/doctor/repository.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/storage" repo_service "code.gitea.io/gitea/services/repository" "xorm.io/builder" @@ -31,6 +32,10 @@ func countOrphanedRepos(ctx context.Context) (int64, error) { // deleteOrphanedRepos delete repository where user of owner_id do not exist func deleteOrphanedRepos(ctx context.Context) (int64, error) { + if err := storage.Init(); err != nil { + return 0, err + } + batchSize := db.MaxBatchInsertSize("repository") e := db.GetEngine(ctx) var deleted int64 From 72529d6e64636fd83e24e709fb8bb0d383509f7f Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sun, 17 Dec 2023 00:26:56 +0000 Subject: [PATCH 34/60] [skip ci] Updated translations via Crowdin --- options/locale/locale_ja-JP.ini | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index bd2a2ea4794d7..7a7dcea8f8988 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -17,6 +17,7 @@ template=テンプレート language=言語 notifications=通知 active_stopwatch=進行中のタイムトラッカー +tracked_time_summary=イシューリストのフィルタに基づき集計したトラッキング時間 create_new=作成… user_profile_and_more=プロフィールと設定… signed_in_as=サインイン済み @@ -359,6 +360,7 @@ disable_register_prompt=登録は無効になっています。 サイト管理 disable_register_mail=登録でのメール確認は無効になっています。 manual_activation_only=アクティベーションを完了するにはサイト管理者に連絡してください。 remember_me=このデバイスで自動サインイン +remember_me.compromised=ログイントークンはもう有効ではなく、アカウントが侵害されたことを示している可能性があります。 異常なアクティビティがないかアカウントを確認してください。 forgot_password_title=パスワードを忘れた forgot_password=パスワードをお忘れですか? sign_up_now=アカウントが必要ですか? 今すぐ登録しましょう。 @@ -623,11 +625,11 @@ applications=アプリケーション orgs=組織の管理 repos=リポジトリ delete=アカウントを削除 -twofa=2要素認証 +twofa=2要素認証 (TOTP) account_link=連携アカウント organization=組織 uid=UID -webauthn=セキュリティキー +webauthn=2要素認証 (セキュリティキー) public_profile=公開プロフィール biography_placeholder=自己紹介してください!(Markdownを使うことができます) @@ -861,22 +863,23 @@ revoke_oauth2_grant=アクセス権の取り消し revoke_oauth2_grant_description=このサードパーティ アプリケーションのアクセス権を取り消し、アプリケーションがあなたのデータへアクセスすることを防ぎます。 続行しますか? revoke_oauth2_grant_success=アクセス権を取り消しました。 -twofa_desc=2要素認証はアカウントのセキュリティを強化します。 +twofa_desc=パスワードの盗難からアカウントを守るために、スマートフォンや他のデバイスを使用して、時間ベースのワンタイムパスワード("TOTP")を受け取ることができます。 +twofa_recovery_tip=デバイスを紛失した場合は、一回限りのリカバリキーを使用してアカウントへのアクセスを回復することができます。 twofa_is_enrolled=このアカウントは2要素認証が有効になっています。 twofa_not_enrolled=このアカウントは2要素認証が設定されていません。 twofa_disable=2要素認証を無効にする -twofa_scratch_token_regenerate=スクラッチトークンを再生成 -twofa_scratch_token_regenerated=あなたのスクラッチトークンは %s になりました。 安全な場所に保管してください。 二度と表示されません。 +twofa_scratch_token_regenerate=一回限りのリカバリキーを再生成 +twofa_scratch_token_regenerated=あなたの一回限りのリカバリキーは %s になりました。 安全な場所に保管してください。 これは二度と表示されません。 twofa_enroll=2要素認証の開始 twofa_disable_note=2要素認証は必要に応じて無効にできます。 twofa_disable_desc=2要素認証を無効にするとアカウントのセキュリティが低下します。 続行しますか? -regenerate_scratch_token_desc=スクラッチトークンを紛失した場合やサインインで使用済みとなった場合は、ここでリセットできます。 +regenerate_scratch_token_desc=リカバリキーを紛失した場合や、すでにサインインに使用済みの場合は、ここでリセットできます。 twofa_disabled=2要素認証を無効にしました。 scan_this_image=この画像を認証アプリケーションで読み取ってください。 or_enter_secret=またはシークレット文字列を入力: %s then_enter_passcode=次に、アプリケーションに表示されているパスコードを入力します。 passcode_invalid=パスコードが間違っています。 再度お試しください。 -twofa_enrolled=あなたのアカウントに2要素認証が設定されました。 スクラッチトークン (%s) は一度しか表示しませんので安全な場所に保存してください! +twofa_enrolled=あなたのアカウントは正常に登録されました。 一回限りのリカバリキー (%s) は安全な場所に保存してください。 これは二度と表示されません。 twofa_failed_get_secret=シークレットが取得できません。 webauthn_desc=セキュリティキーは暗号化キーを内蔵するハードウェア ・ デバイスです。 2要素認証に使用できます。 セキュリティキーはWebAuthn Authenticator規格をサポートしている必要があります。 @@ -884,6 +887,8 @@ webauthn_register_key=セキュリティキーを追加 webauthn_nickname=ニックネーム webauthn_delete_key=セキュリティキーの登録解除 webauthn_delete_key_desc=セキュリティキーの登録を解除すると、今後そのセキュリティキーでサインインすることはできなくなります。 続行しますか? +webauthn_key_loss_warning=セキュリティキーを紛失すると、アカウントへのアクセスを失います。 +webauthn_alternative_tip=もうひとつ別の認証方法も設定すると良いかもしれません。 manage_account_links=連携アカウントの管理 manage_account_links_desc=これらの外部アカウントがGiteaアカウントと連携されています。 @@ -920,6 +925,7 @@ visibility.private=プライベート visibility.private_tooltip=あなたが参加した組織のメンバーのみに表示されます [repo] +new_repo_helper=リポジトリには、プロジェクトのすべてのファイルとリビジョン履歴が入ります。 すでにほかの場所でホストしていますか? リポジトリを移行 もどうぞ。 owner=オーナー owner_helper=リポジトリ数の上限により、一部の組織はドロップダウンに表示されない場合があります。 repo_name=リポジトリ名 @@ -1782,6 +1788,8 @@ pulls.status_checks_failure=失敗したステータスチェックがありま pulls.status_checks_error=ステータスチェックによりエラーが出ています pulls.status_checks_requested=必須 pulls.status_checks_details=詳細 +pulls.status_checks_hide_all=すべてのチェックを隠す +pulls.status_checks_show_all=すべてのチェックを表示 pulls.update_branch=マージでブランチを更新 pulls.update_branch_rebase=リベースでブランチを更新 pulls.update_branch_success=ブランチの更新が成功しました @@ -1790,6 +1798,11 @@ pulls.outdated_with_base_branch=このブランチはベースブランチに対 pulls.close=プルリクエストをクローズ pulls.closed_at=`がプルリクエストをクローズ %[2]s` pulls.reopened_at=`がプルリクエストを再オープン %[2]s` +pulls.cmd_instruction_hint=`コマンドラインの手順を表示します。` +pulls.cmd_instruction_checkout_title=チェックアウト +pulls.cmd_instruction_checkout_desc=プロジェクトリポジトリから新しいブランチをチェックアウトし、変更内容をテストします。 +pulls.cmd_instruction_merge_title=マージ +pulls.cmd_instruction_merge_desc=変更内容をマージして、Giteaに反映します。 pulls.clear_merge_message=マージメッセージをクリア pulls.clear_merge_message_hint=マージメッセージのクリアは、コミットメッセージの除去だけを行います。 生成されたGitトレーラー("Co-Authored-By …" 等)はそのまま残ります。 @@ -2301,6 +2314,7 @@ settings.dismiss_stale_approvals_desc=プルリクエストの内容を変える settings.require_signed_commits=コミット署名必須 settings.require_signed_commits_desc=署名されていない場合、または署名が検証できなかった場合は、このブランチへのプッシュを拒否します。 settings.protect_branch_name_pattern=保護ブランチ名のパターン +settings.protect_branch_name_pattern_desc=保護ブランチ名のパターン。書き方については ドキュメント を参照してください。例: main, release/** settings.protect_patterns=パターン settings.protect_protected_file_patterns=保護されるファイルのパターン (セミコロン';'で区切る): settings.protect_protected_file_patterns_desc=保護されたファイルは、このブランチにファイルを追加・編集・削除する権限を持つユーザーであっても、直接変更することができなくなります。 セミコロン(';')で区切って複数のパターンを指定できます。 パターンの文法については github.com/gobwas/glob を参照してください。 例: .drone.yml, /docs/**/*.txt @@ -2846,6 +2860,7 @@ emails.updated=メール設定を更新しました emails.not_updated=メール設定の更新に失敗しました: %v emails.duplicate_active=メールアドレスは別のユーザーが既に使用中です。 emails.change_email_header=メール設定の更新 +emails.change_email_text=このメールアドレスで更新してもよろしいですか? orgs.org_manage_panel=組織の管理 orgs.name=名称 @@ -2870,6 +2885,7 @@ packages.package_manage_panel=パッケージ管理 packages.total_size=合計サイズ: %s packages.unreferenced_size=非参照サイズ: %s packages.cleanup=期限切れデータを掃除する +packages.cleanup.success=期限切れのデータを正常にクリーンアップしました packages.owner=オーナー packages.creator=作成者 packages.name=名前 @@ -3516,6 +3532,7 @@ runs.actors_no_select=すべてのアクター runs.status_no_select=すべてのステータス runs.no_results=一致する結果はありません。 runs.no_runs=ワークフローはまだ実行されていません。 +runs.empty_commit_message=(空のコミットメッセージ) workflow.disable=ワークフローを無効にする workflow.disable_success=ワークフロー '%s' が無効になりました。 From 7fb6b5147038649bfaa26147a6173cf99b322a30 Mon Sep 17 00:00:00 2001 From: The Magician <142242365+TheMagician23@users.noreply.github.com> Date: Sun, 17 Dec 2023 04:33:37 +0000 Subject: [PATCH 35/60] Remove duplicate option in admin screen and now-unused translation keys (#28492) Resolves https://github.com/go-gitea/gitea/issues/28451. This change follows the recommendation by wxiaoguang to remove the "Disable Minimum Key Size Check" from the "Service Configuration" section of the UI, because this option belongs to the "SSH Configuration" section of the administration menu and already has a functioning indicator in that section of the UI. --------- Co-authored-by: wxiaoguang --- options/locale/locale_en-US.ini | 1 - templates/admin/config.tmpl | 2 -- 2 files changed, 3 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 4f18606a45267..e57dd7794e4db 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3080,7 +3080,6 @@ config.enable_openid_signin = Enable OpenID Sign-In config.show_registration_button = Show Register Button config.require_sign_in_view = Require Sign-In to View Pages config.mail_notify = Enable Email Notifications -config.disable_key_size_check = Disable Minimum Key Size Check config.enable_captcha = Enable CAPTCHA config.active_code_lives = Active Code Lives config.reset_password_code_lives = Recover Account Code Expiry Time diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl index 7eb9d086e61cc..1cc4b7bb09ae5 100644 --- a/templates/admin/config.tmpl +++ b/templates/admin/config.tmpl @@ -151,8 +151,6 @@
{{if .Service.RequireSignInView}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
{{ctx.Locale.Tr "admin.config.mail_notify"}}
{{if .Service.EnableNotifyMail}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
-
{{ctx.Locale.Tr "admin.config.disable_key_size_check"}}
-
{{if .SSH.MinimumKeySizeCheck}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
{{ctx.Locale.Tr "admin.config.enable_captcha"}}
{{if .Service.EnableCaptcha}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
{{ctx.Locale.Tr "admin.config.default_keep_email_private"}}
From 408a4842240e7dd906e682196bd4254d6c76fcb9 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 17 Dec 2023 19:56:08 +0800 Subject: [PATCH 36/60] Adjust object format interface (#28469) - Remove `ObjectFormatID` - Remove function `ObjectFormatFromID`. - Use `Sha1ObjectFormat` directly but not a pointer because it's an empty struct. - Store `ObjectFormatName` in `repository` struct --- models/git/branch_test.go | 4 +- models/repo/repo.go | 6 +- modules/git/blame_test.go | 2 +- modules/git/commit.go | 2 +- modules/git/object_format.go | 79 +++++++++---------- modules/git/object_id.go | 33 +++----- modules/git/object_id_gogit.go | 2 +- modules/git/object_id_test.go | 2 +- modules/git/parse_gogit_test.go | 14 ++-- modules/git/parse_nogogit_test.go | 6 +- modules/git/ref.go | 2 +- modules/git/repo.go | 10 ++- modules/git/repo_commit_gogit.go | 4 +- modules/git/repo_compare.go | 2 +- modules/git/repo_compare_test.go | 4 +- modules/git/repo_index.go | 2 +- modules/git/repo_tag_test.go | 2 +- modules/git/tag.go | 4 +- modules/git/tag_test.go | 6 +- modules/repository/commits_test.go | 2 +- modules/repository/generate.go | 4 +- modules/repository/init.go | 4 +- routers/api/v1/repo/repo.go | 24 +++--- routers/api/v1/utils/git.go | 2 +- routers/private/hook_pre_receive.go | 6 +- routers/private/hook_verification.go | 2 +- routers/private/hook_verification_test.go | 4 +- routers/web/repo/branch.go | 2 +- routers/web/repo/compare.go | 2 +- routers/web/repo/githttp.go | 2 +- routers/web/repo/repo.go | 24 +++--- routers/web/repo/setting/webhook.go | 2 +- services/agit/agit.go | 4 +- services/convert/git_commit_test.go | 10 +-- services/forms/repo_form.go | 3 +- services/gitdiff/gitdiff.go | 6 +- services/migrations/common.go | 2 +- services/migrations/gitea_uploader_test.go | 2 +- services/mirror/mirror_pull.go | 2 +- services/packages/cargo/index.go | 2 +- services/pull/pull.go | 2 +- services/pull/temp_repo.go | 9 +-- services/release/release.go | 6 +- services/repository/branch.go | 2 +- services/repository/check.go | 2 +- services/repository/create.go | 42 +++++----- services/repository/files/cherry_pick.go | 3 +- services/repository/files/temp_repo.go | 4 +- services/repository/files/update.go | 3 +- services/repository/files/upload.go | 2 +- services/repository/push.go | 14 ++-- services/wiki/wiki.go | 2 +- services/wiki/wiki_test.go | 2 +- .../git_helper_for_declarative_test.go | 2 +- 54 files changed, 190 insertions(+), 202 deletions(-) diff --git a/models/git/branch_test.go b/models/git/branch_test.go index adcf9fd305ae8..8febc80f14747 100644 --- a/models/git/branch_test.go +++ b/models/git/branch_test.go @@ -20,6 +20,7 @@ import ( func TestAddDeletedBranch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + assert.EqualValues(t, git.Sha1ObjectFormat.Name(), repo.ObjectFormatName) firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{ID: 1}) assert.True(t, firstBranch.IsDeleted) @@ -29,8 +30,9 @@ func TestAddDeletedBranch(t *testing.T) { secondBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{RepoID: repo.ID, Name: "branch2"}) assert.True(t, secondBranch.IsDeleted) + objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName) commit := &git.Commit{ - ID: repo.ObjectFormat.MustIDFromString(secondBranch.CommitID), + ID: objectFormat.MustIDFromString(secondBranch.CommitID), CommitMessage: secondBranch.CommitMessage, Committer: &git.Signature{ When: secondBranch.CommitTime.AsLocalTime(), diff --git a/models/repo/repo.go b/models/repo/repo.go index f739ada307797..fb1849a4bb7fa 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -180,7 +180,7 @@ type Repository struct { IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"` CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"` Topics []string `xorm:"TEXT JSON"` - ObjectFormat git.ObjectFormat `xorm:"-"` + ObjectFormatName string `xorm:"-"` TrustModel TrustModelType @@ -277,7 +277,9 @@ func (repo *Repository) AfterLoad() { repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects repo.NumOpenActionRuns = repo.NumActionRuns - repo.NumClosedActionRuns - repo.ObjectFormat = git.ObjectFormatFromID(git.Sha1) + // this is a temporary behaviour to support old repos, next step is to store the object format in the database + // and read from database so this line could be removed. To not depend on git module, we use a constant variable here + repo.ObjectFormatName = "sha1" } // LoadAttributes loads attributes of the repository. diff --git a/modules/git/blame_test.go b/modules/git/blame_test.go index 0afc6d2a1f0f7..327edab767089 100644 --- a/modules/git/blame_test.go +++ b/modules/git/blame_test.go @@ -39,7 +39,7 @@ func TestReadingBlameOutput(t *testing.T) { } for _, bypass := range []bool{false, true} { - blameReader, err := CreateBlameReader(ctx, &Sha1ObjectFormat{}, "./tests/repos/repo5_pulls", commit, "README.md", bypass) + blameReader, err := CreateBlameReader(ctx, Sha1ObjectFormat, "./tests/repos/repo5_pulls", commit, "README.md", bypass) assert.NoError(t, err) assert.NotNil(t, blameReader) defer blameReader.Close() diff --git a/modules/git/commit.go b/modules/git/commit.go index a8b6c0e8f793e..5d960e92f3384 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -236,7 +236,7 @@ func (c *Commit) IsForcePush(oldCommitID string) (bool, error) { if err != nil { return false, err } - if oldCommitID == objectFormat.Empty().String() { + if oldCommitID == objectFormat.EmptyObjectID().String() { return false, nil } diff --git a/modules/git/object_format.go b/modules/git/object_format.go index 3c52de772bb37..ee7e659ed04dd 100644 --- a/modules/git/object_format.go +++ b/modules/git/object_format.go @@ -5,26 +5,17 @@ package git import ( "crypto/sha1" - "fmt" "regexp" - "strings" -) - -type ObjectFormatID int - -const ( - Sha1 ObjectFormatID = iota ) // sha1Pattern can be used to determine if a string is an valid sha var sha1Pattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`) type ObjectFormat interface { - ID() ObjectFormatID - String() string - - // Empty is the hash of empty git - Empty() ObjectID + // Name returns the name of the object format + Name() string + // EmptyObjectID creates a new empty ObjectID from an object format hash name + EmptyObjectID() ObjectID // EmptyTree is the hash of an empty tree EmptyTree() ObjectID // FullLength is the length of the hash's hex string @@ -35,67 +26,71 @@ type ObjectFormat interface { MustIDFromString(s string) ObjectID NewID(b []byte) (ObjectID, error) NewIDFromString(s string) (ObjectID, error) - NewEmptyID() ObjectID NewHasher() HasherInterface } -type Sha1ObjectFormat struct{} +type Sha1ObjectFormatImpl struct{} -func (*Sha1ObjectFormat) ID() ObjectFormatID { return Sha1 } -func (*Sha1ObjectFormat) String() string { return "sha1" } -func (*Sha1ObjectFormat) Empty() ObjectID { return &Sha1Hash{} } -func (*Sha1ObjectFormat) EmptyTree() ObjectID { - return &Sha1Hash{ +var ( + emptyObjectID = &Sha1Hash{} + emptyTree = &Sha1Hash{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04, } +) + +func (Sha1ObjectFormatImpl) Name() string { return "sha1" } +func (Sha1ObjectFormatImpl) EmptyObjectID() ObjectID { + return emptyObjectID +} + +func (Sha1ObjectFormatImpl) EmptyTree() ObjectID { + return emptyTree } -func (*Sha1ObjectFormat) FullLength() int { return 40 } -func (*Sha1ObjectFormat) IsValid(input string) bool { +func (Sha1ObjectFormatImpl) FullLength() int { return 40 } +func (Sha1ObjectFormatImpl) IsValid(input string) bool { return sha1Pattern.MatchString(input) } -func (*Sha1ObjectFormat) MustID(b []byte) ObjectID { +func (Sha1ObjectFormatImpl) MustID(b []byte) ObjectID { var id Sha1Hash copy(id[0:20], b) return &id } -func (h *Sha1ObjectFormat) MustIDFromString(s string) ObjectID { +func (h Sha1ObjectFormatImpl) MustIDFromString(s string) ObjectID { return MustIDFromString(h, s) } -func (h *Sha1ObjectFormat) NewID(b []byte) (ObjectID, error) { +func (h Sha1ObjectFormatImpl) NewID(b []byte) (ObjectID, error) { return IDFromRaw(h, b) } -func (h *Sha1ObjectFormat) NewIDFromString(s string) (ObjectID, error) { +func (h Sha1ObjectFormatImpl) NewIDFromString(s string) (ObjectID, error) { return genericIDFromString(h, s) } -func (*Sha1ObjectFormat) NewEmptyID() ObjectID { - return NewSha1() -} - -func (h *Sha1ObjectFormat) NewHasher() HasherInterface { +func (h Sha1ObjectFormatImpl) NewHasher() HasherInterface { return &Sha1Hasher{sha1.New()} } -func ObjectFormatFromID(id ObjectFormatID) ObjectFormat { - switch id { - case Sha1: - return &Sha1ObjectFormat{} - } +var Sha1ObjectFormat ObjectFormat = Sha1ObjectFormatImpl{} - return nil +var SupportedObjectFormats = []ObjectFormat{ + Sha1ObjectFormat, + // TODO: add sha256 } -func ObjectFormatFromString(hash string) (ObjectFormat, error) { - switch strings.ToLower(hash) { - case "sha1": - return &Sha1ObjectFormat{}, nil +func ObjectFormatFromName(name string) ObjectFormat { + for _, objectFormat := range SupportedObjectFormats { + if name == objectFormat.Name() { + return objectFormat + } } + return nil +} - return nil, fmt.Errorf("unknown hash type: %s", hash) +func IsValidObjectFormat(name string) bool { + return ObjectFormatFromName(name) != nil } diff --git a/modules/git/object_id.go b/modules/git/object_id.go index 21e1c67c646c2..a90683678a817 100644 --- a/modules/git/object_id.go +++ b/modules/git/object_id.go @@ -31,18 +31,15 @@ func (h *Sha1Hash) IsZero() bool { return bytes.Equal(empty[:], h[:]) } func (h *Sha1Hash) RawValue() []byte { return h[:] } -func (*Sha1Hash) Type() ObjectFormat { return &Sha1ObjectFormat{} } +func (*Sha1Hash) Type() ObjectFormat { return Sha1ObjectFormat } -func NewSha1() *Sha1Hash { - return &Sha1Hash{} -} +var _ ObjectID = &Sha1Hash{} -// NewHash is for generic implementations -func NewHash(hash string) (ObjectID, error) { - hash = strings.ToLower(hash) - switch hash { - case "sha1": - return &Sha1Hash{}, nil +// EmptyObjectID creates a new ObjectID from an object format hash name +func EmptyObjectID(objectFormatName string) (ObjectID, error) { + objectFormat := ObjectFormatFromName(objectFormatName) + if objectFormat != nil { + return objectFormat.EmptyObjectID(), nil } return nil, errors.New("unsupported hash type") @@ -50,7 +47,7 @@ func NewHash(hash string) (ObjectID, error) { func IDFromRaw(h ObjectFormat, b []byte) (ObjectID, error) { if len(b) != h.FullLength()/2 { - return h.Empty(), fmt.Errorf("length must be %d: %v", h.FullLength(), b) + return h.EmptyObjectID(), fmt.Errorf("length must be %d: %v", h.FullLength(), b) } return h.MustID(b), nil } @@ -63,24 +60,20 @@ func MustIDFromString(h ObjectFormat, s string) ObjectID { func genericIDFromString(h ObjectFormat, s string) (ObjectID, error) { s = strings.TrimSpace(s) if len(s) != h.FullLength() { - return h.Empty(), fmt.Errorf("length must be %d: %s", h.FullLength(), s) + return h.EmptyObjectID(), fmt.Errorf("length must be %d: %s", h.FullLength(), s) } b, err := hex.DecodeString(s) if err != nil { - return h.Empty(), err + return h.EmptyObjectID(), err } return h.NewID(b) } func IDFromString(hexHash string) (ObjectID, error) { - switch len(hexHash) { - case 40: - hashType := Sha1ObjectFormat{} - h, err := hashType.NewIDFromString(hexHash) - if err != nil { - return nil, err + for _, objectFormat := range SupportedObjectFormats { + if len(hexHash) == objectFormat.FullLength() { + return objectFormat.NewIDFromString(hexHash) } - return h, nil } return nil, fmt.Errorf("invalid hash hex string: '%s' len: %d", hexHash, len(hexHash)) diff --git a/modules/git/object_id_gogit.go b/modules/git/object_id_gogit.go index 50917f0552d54..0cebb0d50b5ff 100644 --- a/modules/git/object_id_gogit.go +++ b/modules/git/object_id_gogit.go @@ -12,7 +12,7 @@ import ( func ParseGogitHash(h plumbing.Hash) ObjectID { switch hash.Size { case 20: - return ObjectFormatFromID(Sha1).MustID(h[:]) + return Sha1ObjectFormat.MustID(h[:]) } return nil diff --git a/modules/git/object_id_test.go b/modules/git/object_id_test.go index c78a215755396..1ad40096a07b1 100644 --- a/modules/git/object_id_test.go +++ b/modules/git/object_id_test.go @@ -10,7 +10,7 @@ import ( ) func TestIsValidSHAPattern(t *testing.T) { - h := NewSha1().Type() + h := Sha1ObjectFormat assert.True(t, h.IsValid("fee1")) assert.True(t, h.IsValid("abc000")) assert.True(t, h.IsValid("9023902390239023902390239023902390239023")) diff --git a/modules/git/parse_gogit_test.go b/modules/git/parse_gogit_test.go index 7ba50cbff90d4..9755f81cce617 100644 --- a/modules/git/parse_gogit_test.go +++ b/modules/git/parse_gogit_test.go @@ -28,9 +28,9 @@ func TestParseTreeEntries(t *testing.T) { Input: "100644 blob 61ab7345a1a3bbc590068ccae37b8515cfc5843c 1022\texample/file2.txt\n", Expected: []*TreeEntry{ { - ID: ObjectFormatFromID(Sha1).MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), + ID: Sha1ObjectFormat.MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), gogitTreeEntry: &object.TreeEntry{ - Hash: plumbing.Hash(ObjectFormatFromID(Sha1).MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c").RawValue()), + Hash: plumbing.Hash(Sha1ObjectFormat.MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c").RawValue()), Name: "example/file2.txt", Mode: filemode.Regular, }, @@ -44,9 +44,9 @@ func TestParseTreeEntries(t *testing.T) { "040000 tree 1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8 -\texample\n", Expected: []*TreeEntry{ { - ID: ObjectFormatFromID(Sha1).MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), + ID: Sha1ObjectFormat.MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), gogitTreeEntry: &object.TreeEntry{ - Hash: plumbing.Hash(ObjectFormatFromID(Sha1).MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c").RawValue()), + Hash: plumbing.Hash(Sha1ObjectFormat.MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c").RawValue()), Name: "example/\n.txt", Mode: filemode.Symlink, }, @@ -54,10 +54,10 @@ func TestParseTreeEntries(t *testing.T) { sized: true, }, { - ID: ObjectFormatFromID(Sha1).MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8"), + ID: Sha1ObjectFormat.MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8"), sized: true, gogitTreeEntry: &object.TreeEntry{ - Hash: plumbing.Hash(ObjectFormatFromID(Sha1).MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8").RawValue()), + Hash: plumbing.Hash(Sha1ObjectFormat.MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8").RawValue()), Name: "example", Mode: filemode.Dir, }, @@ -67,7 +67,7 @@ func TestParseTreeEntries(t *testing.T) { } for _, testCase := range testCases { - entries, err := ParseTreeEntries(ObjectFormatFromID(Sha1), []byte(testCase.Input)) + entries, err := ParseTreeEntries(Sha1ObjectFormat, []byte(testCase.Input)) assert.NoError(t, err) if len(entries) > 1 { fmt.Println(testCase.Expected[0].ID) diff --git a/modules/git/parse_nogogit_test.go b/modules/git/parse_nogogit_test.go index 0b78c081cd6f7..36313e00f331c 100644 --- a/modules/git/parse_nogogit_test.go +++ b/modules/git/parse_nogogit_test.go @@ -12,7 +12,7 @@ import ( ) func TestParseTreeEntriesLong(t *testing.T) { - objectFormat := ObjectFormatFromID(Sha1) + objectFormat := Sha1ObjectFormat testCases := []struct { Input string @@ -66,7 +66,7 @@ func TestParseTreeEntriesLong(t *testing.T) { } func TestParseTreeEntriesShort(t *testing.T) { - objectFormat := ObjectFormatFromID(Sha1) + objectFormat := Sha1ObjectFormat testCases := []struct { Input string @@ -102,7 +102,7 @@ func TestParseTreeEntriesShort(t *testing.T) { func TestParseTreeEntriesInvalid(t *testing.T) { // there was a panic: "runtime error: slice bounds out of range" when the input was invalid: #20315 - entries, err := ParseTreeEntries(ObjectFormatFromID(Sha1), []byte("100644 blob ea0d83c9081af9500ac9f804101b3fd0a5c293af")) + entries, err := ParseTreeEntries(Sha1ObjectFormat, []byte("100644 blob ea0d83c9081af9500ac9f804101b3fd0a5c293af")) assert.Error(t, err) assert.Len(t, entries, 0) } diff --git a/modules/git/ref.go b/modules/git/ref.go index b96b4ababb412..ed801f20d5c34 100644 --- a/modules/git/ref.go +++ b/modules/git/ref.go @@ -205,7 +205,7 @@ func RefURL(repoURL, ref string) string { return repoURL + "/src/branch/" + refName case refFullName.IsTag(): return repoURL + "/src/tag/" + refName - case !ObjectFormatFromID(Sha1).IsValid(ref): + case !Sha1ObjectFormat.IsValid(ref): // assume they mean a branch return repoURL + "/src/branch/" + refName default: diff --git a/modules/git/repo.go b/modules/git/repo.go index c036a217eb25c..52e54715d6532 100644 --- a/modules/git/repo.go +++ b/modules/git/repo.go @@ -90,7 +90,7 @@ func GetObjectFormatOfRepo(ctx context.Context, repoPath string) (ObjectFormat, } // InitRepository initializes a new Git repository. -func InitRepository(ctx context.Context, repoPath string, bare bool, objectFormat ObjectFormat) error { +func InitRepository(ctx context.Context, repoPath string, bare bool, objectFormatName string) error { err := os.MkdirAll(repoPath, os.ModePerm) if err != nil { return err @@ -98,7 +98,13 @@ func InitRepository(ctx context.Context, repoPath string, bare bool, objectForma cmd := NewCommand(ctx, "init") if SupportHashSha256 { - cmd.AddOptionValues("--object-format", objectFormat.String()) + if objectFormatName == "" { + objectFormatName = Sha1ObjectFormat.Name() + } + if !IsValidObjectFormat(objectFormatName) { + return fmt.Errorf("invalid object format: %s", objectFormatName) + } + cmd.AddOptionValues("--object-format", objectFormatName) } if bare { cmd.AddArguments("--bare") diff --git a/modules/git/repo_commit_gogit.go b/modules/git/repo_commit_gogit.go index 893055bccdf6b..d0992fd385ae0 100644 --- a/modules/git/repo_commit_gogit.go +++ b/modules/git/repo_commit_gogit.go @@ -54,9 +54,9 @@ func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) { if err != nil { if strings.Contains(err.Error(), "unknown revision or path") || strings.Contains(err.Error(), "fatal: Needed a single revision") { - return objectFormat.Empty(), ErrNotExist{commitID, ""} + return objectFormat.EmptyObjectID(), ErrNotExist{commitID, ""} } - return objectFormat.Empty(), err + return objectFormat.EmptyObjectID(), err } return objectFormat.NewIDFromString(actualCommitID) diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go index 8885df4f7088e..0e9a0c70d791b 100644 --- a/modules/git/repo_compare.go +++ b/modules/git/repo_compare.go @@ -284,7 +284,7 @@ func (repo *Repository) GetPatch(base, head string, w io.Writer) error { // If base is the SHA of an empty tree (EmptyTreeSHA), it returns the files changes from the initial commit to the head commit func (repo *Repository) GetFilesChangedBetween(base, head string) ([]string, error) { cmd := NewCommand(repo.Ctx, "diff-tree", "--name-only", "--root", "--no-commit-id", "-r", "-z") - if base == repo.objectFormat.Empty().String() { + if base == repo.objectFormat.EmptyObjectID().String() { cmd.AddDynamicArguments(head) } else { cmd.AddDynamicArguments(base, head) diff --git a/modules/git/repo_compare_test.go b/modules/git/repo_compare_test.go index 9bfaa5c02a564..526b21355075a 100644 --- a/modules/git/repo_compare_test.go +++ b/modules/git/repo_compare_test.go @@ -131,12 +131,12 @@ func TestGetCommitFilesChanged(t *testing.T) { files []string }{ { - repo.objectFormat.Empty().String(), + repo.objectFormat.EmptyObjectID().String(), "95bb4d39648ee7e325106df01a621c530863a653", []string{"file1.txt"}, }, { - repo.objectFormat.Empty().String(), + repo.objectFormat.EmptyObjectID().String(), "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2", []string{"file2.txt"}, }, diff --git a/modules/git/repo_index.go b/modules/git/repo_index.go index 6f43734655f35..e3b19bf036463 100644 --- a/modules/git/repo_index.go +++ b/modules/git/repo_index.go @@ -101,7 +101,7 @@ func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error { for _, file := range filenames { if file != "" { buffer.WriteString("0 ") - buffer.WriteString(repo.objectFormat.Empty().String()) + buffer.WriteString(repo.objectFormat.EmptyObjectID().String()) buffer.WriteByte('\t') buffer.WriteString(file) buffer.WriteByte('\000') diff --git a/modules/git/repo_tag_test.go b/modules/git/repo_tag_test.go index c7699f4a7d2c6..48c1bc41c2375 100644 --- a/modules/git/repo_tag_test.go +++ b/modules/git/repo_tag_test.go @@ -194,7 +194,7 @@ func TestRepository_GetAnnotatedTag(t *testing.T) { } func TestRepository_parseTagRef(t *testing.T) { - sha1 := ObjectFormatFromID(Sha1) + sha1 := Sha1ObjectFormat tests := []struct { name string diff --git a/modules/git/tag.go b/modules/git/tag.go index 27358d74f8db8..c7d0d8aef92b2 100644 --- a/modules/git/tag.go +++ b/modules/git/tag.go @@ -35,8 +35,8 @@ func (tag *Tag) Commit(gitRepo *Repository) (*Commit, error) { // \n\n separate headers from message func parseTagData(objectFormat ObjectFormat, data []byte) (*Tag, error) { tag := new(Tag) - tag.ID = objectFormat.NewEmptyID() - tag.Object = objectFormat.NewEmptyID() + tag.ID = objectFormat.EmptyObjectID() + tag.Object = objectFormat.EmptyObjectID() tag.Tagger = &Signature{} // we now have the contents of the commit object. Let's investigate... nextline := 0 diff --git a/modules/git/tag_test.go b/modules/git/tag_test.go index 129c1e3a02303..f980b0c560c4f 100644 --- a/modules/git/tag_test.go +++ b/modules/git/tag_test.go @@ -22,7 +22,7 @@ tagger Lucas Michot 1484491741 +0100 `), tag: Tag{ Name: "", - ID: NewSha1(), + ID: Sha1ObjectFormat.EmptyObjectID(), Object: &Sha1Hash{0x3b, 0x11, 0x4a, 0xb8, 0x0, 0xc6, 0x43, 0x2a, 0xd4, 0x23, 0x87, 0xcc, 0xf6, 0xbc, 0x8d, 0x43, 0x88, 0xa2, 0x88, 0x5a}, Type: "commit", Tagger: &Signature{Name: "Lucas Michot", Email: "lucas@semalead.com", When: time.Unix(1484491741, 0)}, @@ -39,7 +39,7 @@ o ono`), tag: Tag{ Name: "", - ID: NewSha1(), + ID: Sha1ObjectFormat.EmptyObjectID(), Object: &Sha1Hash{0x7c, 0xdf, 0x42, 0xc0, 0xb1, 0xcc, 0x76, 0x3a, 0xb7, 0xe4, 0xc3, 0x3c, 0x47, 0xa2, 0x4e, 0x27, 0xc6, 0x6b, 0xfc, 0xcc}, Type: "commit", Tagger: &Signature{Name: "Lucas Michot", Email: "lucas@semalead.com", When: time.Unix(1484553735, 0)}, @@ -49,7 +49,7 @@ ono`), tag: Tag{ } for _, test := range testData { - tag, err := parseTagData(ObjectFormatFromID(Sha1), test.data) + tag, err := parseTagData(Sha1ObjectFormat, test.data) assert.NoError(t, err) assert.EqualValues(t, test.tag.ID, tag.ID) assert.EqualValues(t, test.tag.Object, tag.Object) diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go index 57f0c90fc6c6e..afcb183d7237a 100644 --- a/modules/repository/commits_test.go +++ b/modules/repository/commits_test.go @@ -169,7 +169,7 @@ func TestListToPushCommits(t *testing.T) { When: now, } - hashType := git.ObjectFormatFromID(git.Sha1) + hashType := git.Sha1ObjectFormat const hexString1 = "0123456789abcdef0123456789abcdef01234567" hash1, err := hashType.NewIDFromString(hexString1) assert.NoError(t, err) diff --git a/modules/repository/generate.go b/modules/repository/generate.go index c143431b7c6a8..f8478b8c1852a 100644 --- a/modules/repository/generate.go +++ b/modules/repository/generate.go @@ -224,7 +224,7 @@ func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *r } // FIXME: fix the hash - if err := git.InitRepository(ctx, tmpDir, false, git.ObjectFormatFromID(git.Sha1)); err != nil { + if err := git.InitRepository(ctx, tmpDir, false, git.Sha1ObjectFormat.Name()); err != nil { return err } @@ -358,7 +358,7 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ } // FIXME - fix the hash - if err = CheckInitRepository(ctx, owner.Name, generateRepo.Name, git.ObjectFormatFromID(git.Sha1)); err != nil { + if err = CheckInitRepository(ctx, owner.Name, generateRepo.Name, git.Sha1ObjectFormat.Name()); err != nil { return generateRepo, err } diff --git a/modules/repository/init.go b/modules/repository/init.go index a9b5aab16aab5..b90b234a73f80 100644 --- a/modules/repository/init.go +++ b/modules/repository/init.go @@ -188,7 +188,7 @@ func InitRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Reposi return nil } -func CheckInitRepository(ctx context.Context, owner, name string, objectFormat git.ObjectFormat) (err error) { +func CheckInitRepository(ctx context.Context, owner, name, objectFormatName string) (err error) { // Somehow the directory could exist. repoPath := repo_model.RepoPath(owner, name) isExist, err := util.IsExist(repoPath) @@ -204,7 +204,7 @@ func CheckInitRepository(ctx context.Context, owner, name string, objectFormat g } // Init git bare new repository. - if err = git.InitRepository(ctx, repoPath, true, objectFormat); err != nil { + if err = git.InitRepository(ctx, repoPath, true, objectFormatName); err != nil { return fmt.Errorf("git.InitRepository: %w", err) } else if err = CreateDelegateHooks(repoPath); err != nil { return fmt.Errorf("createDelegateHooks: %w", err) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 1767a7fa674d5..6eb2cc4227429 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -242,18 +242,18 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre } repo, err := repo_service.CreateRepository(ctx, ctx.Doer, owner, repo_service.CreateRepoOptions{ - Name: opt.Name, - Description: opt.Description, - IssueLabels: opt.IssueLabels, - Gitignores: opt.Gitignores, - License: opt.License, - Readme: opt.Readme, - IsPrivate: opt.Private, - AutoInit: opt.AutoInit, - DefaultBranch: opt.DefaultBranch, - TrustModel: repo_model.ToTrustModel(opt.TrustModel), - IsTemplate: opt.Template, - ObjectFormat: git.ObjectFormatFromID(git.Sha1), + Name: opt.Name, + Description: opt.Description, + IssueLabels: opt.IssueLabels, + Gitignores: opt.Gitignores, + License: opt.License, + Readme: opt.Readme, + IsPrivate: opt.Private, + AutoInit: opt.AutoInit, + DefaultBranch: opt.DefaultBranch, + TrustModel: repo_model.ToTrustModel(opt.TrustModel), + IsTemplate: opt.Template, + ObjectFormatName: git.Sha1ObjectFormat.Name(), }) if err != nil { if repo_model.IsErrRepoAlreadyExist(err) { diff --git a/routers/api/v1/utils/git.go b/routers/api/v1/utils/git.go index eb82c505440fe..dfb1a130c3711 100644 --- a/routers/api/v1/utils/git.go +++ b/routers/api/v1/utils/git.go @@ -81,7 +81,7 @@ func ConvertToObjectID(ctx gocontext.Context, repo *context.Repository, commitID gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.Repository.RepoPath()) if err != nil { - return objectFormat.Empty(), fmt.Errorf("RepositoryFromContextOrOpen: %w", err) + return objectFormat.EmptyObjectID(), fmt.Errorf("RepositoryFromContextOrOpen: %w", err) } defer closer.Close() diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index 8811809710116..90d8287f06fd2 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -147,7 +147,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r gitRepo := ctx.Repo.GitRepo objectFormat, _ := gitRepo.GetObjectFormat() - if branchName == repo.DefaultBranch && newCommitID == objectFormat.Empty().String() { + if branchName == repo.DefaultBranch && newCommitID == objectFormat.EmptyObjectID().String() { log.Warn("Forbidden: Branch: %s is the default branch in %-v and cannot be deleted", branchName, repo) ctx.JSON(http.StatusForbidden, private.Response{ UserMsg: fmt.Sprintf("branch %s is the default branch and cannot be deleted", branchName), @@ -175,7 +175,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r // First of all we need to enforce absolutely: // // 1. Detect and prevent deletion of the branch - if newCommitID == objectFormat.Empty().String() { + if newCommitID == objectFormat.EmptyObjectID().String() { log.Warn("Forbidden: Branch: %s in %-v is protected from deletion", branchName, repo) ctx.JSON(http.StatusForbidden, private.Response{ UserMsg: fmt.Sprintf("branch %s is protected from deletion", branchName), @@ -184,7 +184,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r } // 2. Disallow force pushes to protected branches - if oldCommitID != objectFormat.Empty().String() { + if oldCommitID != objectFormat.EmptyObjectID().String() { output, _, err := git.NewCommand(ctx, "rev-list", "--max-count=1").AddDynamicArguments(oldCommitID, "^"+newCommitID).RunStdString(&git.RunOpts{Dir: repo.RepoPath(), Env: ctx.env}) if err != nil { log.Error("Unable to detect force push between: %s and %s in %-v Error: %v", oldCommitID, newCommitID, repo, err) diff --git a/routers/private/hook_verification.go b/routers/private/hook_verification.go index 6725205cc6d2c..8b2d0dd848a9d 100644 --- a/routers/private/hook_verification.go +++ b/routers/private/hook_verification.go @@ -30,7 +30,7 @@ func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env [] var command *git.Command objectFormat, _ := repo.GetObjectFormat() - if oldCommitID == objectFormat.Empty().String() { + if oldCommitID == objectFormat.EmptyObjectID().String() { // When creating a new branch, the oldCommitID is empty, by using "newCommitID --not --all": // List commits that are reachable by following the newCommitID, exclude "all" existing heads/tags commits // So, it only lists the new commits received, doesn't list the commits already present in the receiving repository diff --git a/routers/private/hook_verification_test.go b/routers/private/hook_verification_test.go index 7263ebc4235d3..04445b8eaf36c 100644 --- a/routers/private/hook_verification_test.go +++ b/routers/private/hook_verification_test.go @@ -30,9 +30,9 @@ func TestVerifyCommits(t *testing.T) { verified bool }{ {"72920278f2f999e3005801e5d5b8ab8139d3641c", "d766f2917716d45be24bfa968b8409544941be32", true}, - {objectFormat.Empty().String(), "93eac826f6188f34646cea81bf426aa5ba7d3bfe", true}, // New branch with verified commit + {objectFormat.EmptyObjectID().String(), "93eac826f6188f34646cea81bf426aa5ba7d3bfe", true}, // New branch with verified commit {"9779d17a04f1e2640583d35703c62460b2d86e0a", "72920278f2f999e3005801e5d5b8ab8139d3641c", false}, - {objectFormat.Empty().String(), "9ce3f779ae33f31fce17fac3c512047b75d7498b", false}, // New branch with unverified commit + {objectFormat.EmptyObjectID().String(), "9ce3f779ae33f31fce17fac3c512047b75d7498b", false}, // New branch with unverified commit } for _, tc := range testCases { diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index b6de5bf800e2d..c543160f42040 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -158,7 +158,7 @@ func RestoreBranchPost(ctx *context.Context) { if err := repo_service.PushUpdate( &repo_module.PushUpdateOptions{ RefFullName: git.RefNameFromBranch(deletedBranch.Name), - OldCommitID: objectFormat.Empty().String(), + OldCommitID: objectFormat.EmptyObjectID().String(), NewCommitID: deletedBranch.CommitID, PusherID: ctx.Doer.ID, PusherName: ctx.Doer.Name, diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 5b1638d3f5f53..f3b95b68fe5a2 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -317,7 +317,7 @@ func ParseCompareInfo(ctx *context.Context) *CompareInfo { ci.BaseBranch = baseCommit.ID.String() ctx.Data["BaseBranch"] = ci.BaseBranch baseIsCommit = true - } else if ci.BaseBranch == objectFormat.Empty().String() { + } else if ci.BaseBranch == objectFormat.EmptyObjectID().String() { if isSameRepo { ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ci.HeadBranch)) } else { diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go index dd47bd79d94e1..6d3dd5a3fe629 100644 --- a/routers/web/repo/githttp.go +++ b/routers/web/repo/githttp.go @@ -329,7 +329,7 @@ func dummyInfoRefs(ctx *context.Context) { } }() - if err := git.InitRepository(ctx, tmpDir, true, git.ObjectFormatFromID(git.Sha1)); err != nil { + if err := git.InitRepository(ctx, tmpDir, true, git.Sha1ObjectFormat.Name()); err != nil { log.Error("Failed to init bare repo for git-receive-pack cache: %v", err) return } diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 7a2976f8dcaac..b16e28383629e 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -278,18 +278,18 @@ func CreatePost(ctx *context.Context) { } } else { repo, err = repo_service.CreateRepository(ctx, ctx.Doer, ctxUser, repo_service.CreateRepoOptions{ - Name: form.RepoName, - Description: form.Description, - Gitignores: form.Gitignores, - IssueLabels: form.IssueLabels, - License: form.License, - Readme: form.Readme, - IsPrivate: form.Private || setting.Repository.ForcePrivate, - DefaultBranch: form.DefaultBranch, - AutoInit: form.AutoInit, - IsTemplate: form.Template, - TrustModel: repo_model.ToTrustModel(form.TrustModel), - ObjectFormat: form.ObjectFormat, + Name: form.RepoName, + Description: form.Description, + Gitignores: form.Gitignores, + IssueLabels: form.IssueLabels, + License: form.License, + Readme: form.Readme, + IsPrivate: form.Private || setting.Repository.ForcePrivate, + DefaultBranch: form.DefaultBranch, + AutoInit: form.AutoInit, + IsTemplate: form.Template, + TrustModel: repo_model.ToTrustModel(form.TrustModel), + ObjectFormatName: form.ObjectFormatName, }) if err == nil { log.Trace("Repository created [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name) diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go index 8c232a4cb8d43..ab3c70006f795 100644 --- a/routers/web/repo/setting/webhook.go +++ b/routers/web/repo/setting/webhook.go @@ -662,7 +662,7 @@ func TestWebhook(ctx *context.Context) { return } commit = &git.Commit{ - ID: objectFormat.NewEmptyID(), + ID: objectFormat.EmptyObjectID(), Author: ghost.NewGitSig(), Committer: ghost.NewGitSig(), CommitMessage: "This is a fake commit", diff --git a/services/agit/agit.go b/services/agit/agit.go index e354b9169a201..bc68372570402 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -39,7 +39,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. objectFormat, _ := gitRepo.GetObjectFormat() for i := range opts.OldCommitIDs { - if opts.NewCommitIDs[i] == objectFormat.Empty().String() { + if opts.NewCommitIDs[i] == objectFormat.EmptyObjectID().String() { results = append(results, private.HookProcReceiveRefResult{ OriginalRef: opts.RefFullNames[i], OldOID: opts.OldCommitIDs[i], @@ -153,7 +153,7 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. results = append(results, private.HookProcReceiveRefResult{ Ref: pr.GetGitRefName(), OriginalRef: opts.RefFullNames[i], - OldOID: objectFormat.Empty().String(), + OldOID: objectFormat.EmptyObjectID().String(), NewOID: opts.NewCommitIDs[i], }) continue diff --git a/services/convert/git_commit_test.go b/services/convert/git_commit_test.go index d8c1fdfed78a7..73cb5e8c7170b 100644 --- a/services/convert/git_commit_test.go +++ b/services/convert/git_commit_test.go @@ -19,12 +19,12 @@ import ( func TestToCommitMeta(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - sha1 := git.ObjectFormatFromID(git.Sha1) + sha1 := git.Sha1ObjectFormat signature := &git.Signature{Name: "Test Signature", Email: "test@email.com", When: time.Unix(0, 0)} tag := &git.Tag{ Name: "Test Tag", - ID: sha1.Empty(), - Object: sha1.Empty(), + ID: sha1.EmptyObjectID(), + Object: sha1.EmptyObjectID(), Type: "Test Type", Tagger: signature, Message: "Test Message", @@ -34,8 +34,8 @@ func TestToCommitMeta(t *testing.T) { assert.NotNil(t, commitMeta) assert.EqualValues(t, &api.CommitMeta{ - SHA: sha1.Empty().String(), - URL: util.URLJoin(headRepo.APIURL(), "git/commits", sha1.Empty().String()), + SHA: sha1.EmptyObjectID().String(), + URL: util.URLJoin(headRepo.APIURL(), "git/commits", sha1.EmptyObjectID().String()), Created: time.Unix(0, 0), }, commitMeta) } diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index f6ef97dfdc3b6..86599000a5882 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -13,7 +13,6 @@ import ( issues_model "code.gitea.io/gitea/models/issues" project_model "code.gitea.io/gitea/models/project" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web/middleware" @@ -54,7 +53,7 @@ type CreateRepoForm struct { TrustModel string ForkSingleBranch string - ObjectFormat git.ObjectFormat + ObjectFormatName string } // Validate validates the fields diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 05d4a0555fc6c..75fc687c86a52 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -1120,7 +1120,7 @@ func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, fi return nil, err } - if (len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == objectFormat.Empty().String()) && commit.ParentCount() == 0 { + if (len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == objectFormat.EmptyObjectID().String()) && commit.ParentCount() == 0 { cmdDiff.AddArguments("diff", "--src-prefix=\\a/", "--dst-prefix=\\b/", "-M"). AddArguments(opts.WhitespaceBehavior...). AddDynamicArguments(objectFormat.EmptyTree().String()). @@ -1229,7 +1229,7 @@ func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, fi } diffPaths := []string{opts.BeforeCommitID + separator + opts.AfterCommitID} - if len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == objectFormat.Empty().String() { + if len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == objectFormat.EmptyObjectID().String() { diffPaths = []string{objectFormat.EmptyTree().String(), opts.AfterCommitID} } diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...) @@ -1267,7 +1267,7 @@ func GetPullDiffStats(gitRepo *git.Repository, opts *DiffOptions) (*PullDiffStat } diffPaths := []string{opts.BeforeCommitID + separator + opts.AfterCommitID} - if len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == objectFormat.Empty().String() { + if len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == objectFormat.EmptyObjectID().String() { diffPaths = []string{objectFormat.EmptyTree().String(), opts.AfterCommitID} } diff --git a/services/migrations/common.go b/services/migrations/common.go index 278c156b036cb..d88518899d052 100644 --- a/services/migrations/common.go +++ b/services/migrations/common.go @@ -49,7 +49,7 @@ func CheckAndEnsureSafePR(pr *base.PullRequest, commonCloneBaseURL string, g bas // SECURITY: SHAs Must be a SHA // FIXME: hash only a SHA1 - CommitType := git.ObjectFormatFromID(git.Sha1) + CommitType := git.Sha1ObjectFormat if pr.MergeCommitSHA != "" && !CommitType.IsValid(pr.MergeCommitSHA) { WarnAndNotice("PR #%d in %s has invalid MergeCommitSHA: %s", pr.Number, g, pr.MergeCommitSHA) pr.MergeCommitSHA = "" diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index b6c9b814772a5..3dec3a26fc4a9 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -232,7 +232,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { // fromRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) baseRef := "master" - assert.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false, fromRepo.ObjectFormat)) + assert.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false, fromRepo.ObjectFormatName)) err := git.NewCommand(git.DefaultContext, "symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(&git.RunOpts{Dir: fromRepo.RepoPath()}) assert.NoError(t, err) assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", fromRepo.RepoPath())), 0o644)) diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index b3ecf2fc54e1a..6f03e14ab08bd 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -484,7 +484,7 @@ func SyncPullMirror(ctx context.Context, repoID int64) bool { } notify_service.SyncPushCommits(ctx, m.Repo.MustOwner(ctx), m.Repo, &repo_module.PushUpdateOptions{ RefFullName: result.refName, - OldCommitID: objectFormat.Empty().String(), + OldCommitID: objectFormat.EmptyObjectID().String(), NewCommitID: commitID, }, repo_module.NewPushCommits()) notify_service.SyncCreateRef(ctx, m.Repo.MustOwner(ctx), m.Repo, result.refName, commitID) diff --git a/services/packages/cargo/index.go b/services/packages/cargo/index.go index 48bd0a4d80a25..9514e35bedd9a 100644 --- a/services/packages/cargo/index.go +++ b/services/packages/cargo/index.go @@ -271,7 +271,7 @@ func alterRepositoryContent(ctx context.Context, doer *user_model.User, repo *re if !git.IsErrBranchNotExist(err) || !repo.IsEmpty { return err } - if err := t.Init(repo.ObjectFormat); err != nil { + if err := t.Init(repo.ObjectFormatName); err != nil { return err } } else { diff --git a/services/pull/pull.go b/services/pull/pull.go index a16d1be1c1cbd..6094a4ed31b9e 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -328,7 +328,7 @@ func AddTestPullRequestTask(doer *user_model.User, repoID int64, branch string, if err == nil { for _, pr := range prs { objectFormat, _ := git.GetObjectFormatOfRepo(ctx, pr.BaseRepo.RepoPath()) - if newCommitID != "" && newCommitID != objectFormat.Empty().String() { + if newCommitID != "" && newCommitID != objectFormat.EmptyObjectID().String() { changed, err := checkIfPRContentChanged(ctx, pr, oldCommitID, newCommitID) if err != nil { log.Error("checkIfPRContentChanged: %v", err) diff --git a/services/pull/temp_repo.go b/services/pull/temp_repo.go index fde8673a2403f..36bdbde55c7a3 100644 --- a/services/pull/temp_repo.go +++ b/services/pull/temp_repo.go @@ -93,14 +93,8 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest) baseRepoPath := pr.BaseRepo.RepoPath() headRepoPath := pr.HeadRepo.RepoPath() - objectFormat, err := git.GetObjectFormatOfRepo(ctx, baseRepoPath) - if err != nil { - log.Error("Unable to fetch ObjectFormat of repository %s: %v", baseRepoPath, err) - cancel() - return nil, nil, err - } - if err := git.InitRepository(ctx, tmpBasePath, false, objectFormat); err != nil { + if err := git.InitRepository(ctx, tmpBasePath, false, pr.BaseRepo.ObjectFormatName); err != nil { log.Error("Unable to init tmpBasePath for %-v: %v", pr, err) cancel() return nil, nil, err @@ -174,6 +168,7 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest) } trackingBranch := "tracking" + objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName) // Fetch head branch var headBranch string if pr.Flow == issues_model.PullRequestFlowGithub { diff --git a/services/release/release.go b/services/release/release.go index 4cd520e82f965..fc91171fba6ae 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -89,14 +89,14 @@ func createTag(ctx context.Context, gitRepo *git.Repository, rel *repo_model.Rel objectFormat, _ := gitRepo.GetObjectFormat() commits := repository.NewPushCommits() commits.HeadCommit = repository.CommitToPushCommit(commit) - commits.CompareURL = rel.Repo.ComposeCompareURL(objectFormat.Empty().String(), commit.ID.String()) + commits.CompareURL = rel.Repo.ComposeCompareURL(objectFormat.EmptyObjectID().String(), commit.ID.String()) refFullName := git.RefNameFromTag(rel.TagName) notify_service.PushCommits( ctx, rel.Publisher, rel.Repo, &repository.PushUpdateOptions{ RefFullName: refFullName, - OldCommitID: objectFormat.Empty().String(), + OldCommitID: objectFormat.EmptyObjectID().String(), NewCommitID: commit.ID.String(), }, commits) notify_service.CreateRef(ctx, rel.Publisher, rel.Repo, refFullName, commit.ID.String()) @@ -335,7 +335,7 @@ func DeleteReleaseByID(ctx context.Context, repo *repo_model.Repository, rel *re &repository.PushUpdateOptions{ RefFullName: refName, OldCommitID: rel.Sha1, - NewCommitID: objectFormat.Empty().String(), + NewCommitID: objectFormat.EmptyObjectID().String(), }, repository.NewPushCommits()) notify_service.DeleteRef(ctx, doer, repo, refName) diff --git a/services/repository/branch.go b/services/repository/branch.go index b797917757ede..dca938444aa35 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -408,7 +408,7 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R &repo_module.PushUpdateOptions{ RefFullName: git.RefNameFromBranch(branchName), OldCommitID: commit.ID.String(), - NewCommitID: objectFormat.Empty().String(), + NewCommitID: objectFormat.EmptyObjectID().String(), PusherID: doer.ID, PusherName: doer.Name, RepoUserName: repo.OwnerName, diff --git a/services/repository/check.go b/services/repository/check.go index 23c4f79bf2045..b874ede51fdbc 100644 --- a/services/repository/check.go +++ b/services/repository/check.go @@ -192,7 +192,7 @@ func ReinitMissingRepositories(ctx context.Context) error { default: } log.Trace("Initializing %d/%d...", repo.OwnerID, repo.ID) - if err := git.InitRepository(ctx, repo.RepoPath(), true, repo.ObjectFormat); err != nil { + if err := git.InitRepository(ctx, repo.RepoPath(), true, repo.ObjectFormatName); err != nil { log.Error("Unable (re)initialize repository %d at %s. Error: %v", repo.ID, repo.RepoPath(), err) if err2 := system_model.CreateRepositoryNotice("InitRepository [%d]: %v", repo.ID, err); err2 != nil { log.Error("CreateRepositoryNotice: %v", err2) diff --git a/services/repository/create.go b/services/repository/create.go index a41904eb7cdf0..bcf2c85c21817 100644 --- a/services/repository/create.go +++ b/services/repository/create.go @@ -27,23 +27,23 @@ import ( // CreateRepoOptions contains the create repository options type CreateRepoOptions struct { - Name string - Description string - OriginalURL string - GitServiceType api.GitServiceType - Gitignores string - IssueLabels string - License string - Readme string - DefaultBranch string - IsPrivate bool - IsMirror bool - IsTemplate bool - AutoInit bool - Status repo_model.RepositoryStatus - TrustModel repo_model.TrustModelType - MirrorInterval string - ObjectFormat git.ObjectFormat + Name string + Description string + OriginalURL string + GitServiceType api.GitServiceType + Gitignores string + IssueLabels string + License string + Readme string + DefaultBranch string + IsPrivate bool + IsMirror bool + IsTemplate bool + AutoInit bool + Status repo_model.RepositoryStatus + TrustModel repo_model.TrustModelType + MirrorInterval string + ObjectFormatName string } func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, repoPath string, opts CreateRepoOptions) error { @@ -135,7 +135,7 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir, // InitRepository initializes README and .gitignore if needed. func initRepository(ctx context.Context, repoPath string, u *user_model.User, repo *repo_model.Repository, opts CreateRepoOptions) (err error) { - if err = repo_module.CheckInitRepository(ctx, repo.OwnerName, repo.Name, opts.ObjectFormat); err != nil { + if err = repo_module.CheckInitRepository(ctx, repo.OwnerName, repo.Name, opts.ObjectFormatName); err != nil { return err } @@ -210,10 +210,6 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt opts.DefaultBranch = setting.Repository.DefaultBranch } - if opts.ObjectFormat == nil { - opts.ObjectFormat = git.ObjectFormatFromID(git.Sha1) - } - // Check if label template exist if len(opts.IssueLabels) > 0 { if _, err := repo_module.LoadTemplateLabelsByDisplayName(opts.IssueLabels); err != nil { @@ -239,7 +235,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, u *user_model.User, opt TrustModel: opts.TrustModel, IsMirror: opts.IsMirror, DefaultBranch: opts.DefaultBranch, - ObjectFormat: opts.ObjectFormat, + ObjectFormatName: opts.ObjectFormatName, } var rollbackRepo *repo_model.Repository diff --git a/services/repository/files/cherry_pick.go b/services/repository/files/cherry_pick.go index 0085e88d55274..e88ea16119799 100644 --- a/services/repository/files/cherry_pick.go +++ b/services/repository/files/cherry_pick.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/services/pull" @@ -66,7 +67,7 @@ func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_mod } parent, err := commit.ParentID(0) if err != nil { - parent = repo.ObjectFormat.EmptyTree() + parent = git.ObjectFormatFromName(repo.ObjectFormatName).EmptyTree() } base, right := parent.String(), commit.ID.String() diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go index 0b5aaba1544ad..6a0b7b675c81e 100644 --- a/services/repository/files/temp_repo.go +++ b/services/repository/files/temp_repo.go @@ -77,8 +77,8 @@ func (t *TemporaryUploadRepository) Clone(branch string) error { } // Init the repository -func (t *TemporaryUploadRepository) Init(objectFormat git.ObjectFormat) error { - if err := git.InitRepository(t.ctx, t.basePath, false, objectFormat); err != nil { +func (t *TemporaryUploadRepository) Init(objectFormatName string) error { + if err := git.InitRepository(t.ctx, t.basePath, false, objectFormatName); err != nil { return err } gitRepo, err := git.OpenRepository(t.ctx, t.basePath) diff --git a/services/repository/files/update.go b/services/repository/files/update.go index d202717ef5706..dd8d9ee42563d 100644 --- a/services/repository/files/update.go +++ b/services/repository/files/update.go @@ -155,8 +155,7 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use if !git.IsErrBranchNotExist(err) || !repo.IsEmpty { return nil, err } - objectFormat, _ := gitRepo.GetObjectFormat() - if err := t.Init(objectFormat); err != nil { + if err := t.Init(repo.ObjectFormatName); err != nil { return nil, err } hasOldBranch = false diff --git a/services/repository/files/upload.go b/services/repository/files/upload.go index 8be8773544779..61e38b55a3705 100644 --- a/services/repository/files/upload.go +++ b/services/repository/files/upload.go @@ -91,7 +91,7 @@ func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use if !git.IsErrBranchNotExist(err) || !repo.IsEmpty { return err } - if err = t.Init(repo.ObjectFormat); err != nil { + if err = t.Init(repo.ObjectFormatName); err != nil { return err } hasOldBranch = false diff --git a/services/repository/push.go b/services/repository/push.go index 3003933c34bcf..3bc7a78cb955d 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -111,7 +111,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { log.Trace("pushUpdates: %-v %s %s %s", repo, opts.OldCommitID, opts.NewCommitID, opts.RefFullName) if opts.IsNewRef() && opts.IsDelRef() { - return fmt.Errorf("old and new revisions are both %s", objectFormat.Empty()) + return fmt.Errorf("old and new revisions are both %s", objectFormat.EmptyObjectID()) } if opts.RefFullName.IsTag() { if pusher == nil || pusher.ID != opts.PusherID { @@ -131,7 +131,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { &repo_module.PushUpdateOptions{ RefFullName: git.RefNameFromTag(tagName), OldCommitID: opts.OldCommitID, - NewCommitID: objectFormat.Empty().String(), + NewCommitID: objectFormat.EmptyObjectID().String(), }, repo_module.NewPushCommits()) delTags = append(delTags, tagName) @@ -144,13 +144,13 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { commits := repo_module.NewPushCommits() commits.HeadCommit = repo_module.CommitToPushCommit(newCommit) - commits.CompareURL = repo.ComposeCompareURL(objectFormat.Empty().String(), opts.NewCommitID) + commits.CompareURL = repo.ComposeCompareURL(objectFormat.EmptyObjectID().String(), opts.NewCommitID) notify_service.PushCommits( ctx, pusher, repo, &repo_module.PushUpdateOptions{ RefFullName: opts.RefFullName, - OldCommitID: objectFormat.Empty().String(), + OldCommitID: objectFormat.EmptyObjectID().String(), NewCommitID: opts.NewCommitID, }, commits) @@ -234,7 +234,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { } oldCommitID := opts.OldCommitID - if oldCommitID == objectFormat.Empty().String() && len(commits.Commits) > 0 { + if oldCommitID == objectFormat.EmptyObjectID().String() && len(commits.Commits) > 0 { oldCommit, err := gitRepo.GetCommit(commits.Commits[len(commits.Commits)-1].Sha1) if err != nil && !git.IsErrNotExist(err) { log.Error("unable to GetCommit %s from %-v: %v", oldCommitID, repo, err) @@ -250,11 +250,11 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error { } } - if oldCommitID == objectFormat.Empty().String() && repo.DefaultBranch != branch { + if oldCommitID == objectFormat.EmptyObjectID().String() && repo.DefaultBranch != branch { oldCommitID = repo.DefaultBranch } - if oldCommitID != objectFormat.Empty().String() { + if oldCommitID != objectFormat.EmptyObjectID().String() { commits.CompareURL = repo.ComposeCompareURL(oldCommitID, opts.NewCommitID) } else { commits.CompareURL = "" diff --git a/services/wiki/wiki.go b/services/wiki/wiki.go index ecda926ec1e2d..f98854c8dd5f6 100644 --- a/services/wiki/wiki.go +++ b/services/wiki/wiki.go @@ -36,7 +36,7 @@ func InitWiki(ctx context.Context, repo *repo_model.Repository) error { return nil } - if err := git.InitRepository(ctx, repo.WikiPath(), true, git.ObjectFormatFromID(git.Sha1)); err != nil { + if err := git.InitRepository(ctx, repo.WikiPath(), true, repo.ObjectFormatName); err != nil { return fmt.Errorf("InitRepository: %w", err) } else if err = repo_module.CreateDelegateHooks(repo.WikiPath()); err != nil { return fmt.Errorf("createDelegateHooks: %w", err) diff --git a/services/wiki/wiki_test.go b/services/wiki/wiki_test.go index 9981fb42583f3..277fa086ac13c 100644 --- a/services/wiki/wiki_test.go +++ b/services/wiki/wiki_test.go @@ -302,7 +302,7 @@ func TestPrepareWikiFileName_FirstPage(t *testing.T) { // Now create a temporaryDirectory tmpDir := t.TempDir() - err := git.InitRepository(git.DefaultContext, tmpDir, true, git.ObjectFormatFromID(git.Sha1)) + err := git.InitRepository(git.DefaultContext, tmpDir, true, git.Sha1ObjectFormat.Name()) assert.NoError(t, err) gitRepo, err := git.OpenRepository(git.DefaultContext, tmpDir) diff --git a/tests/integration/git_helper_for_declarative_test.go b/tests/integration/git_helper_for_declarative_test.go index de671dec19e98..77fe07128e75a 100644 --- a/tests/integration/git_helper_for_declarative_test.go +++ b/tests/integration/git_helper_for_declarative_test.go @@ -120,7 +120,7 @@ func doGitCloneFail(u *url.URL) func(*testing.T) { func doGitInitTestRepository(dstPath string) func(*testing.T) { return func(t *testing.T) { // Init repository in dstPath - assert.NoError(t, git.InitRepository(git.DefaultContext, dstPath, false, git.ObjectFormatFromID(git.Sha1))) + assert.NoError(t, git.InitRepository(git.DefaultContext, dstPath, false, git.Sha1ObjectFormat.Name())) // forcibly set default branch to master _, _, err := git.NewCommand(git.DefaultContext, "symbolic-ref", "HEAD", git.BranchPrefix+"master").RunStdString(&git.RunOpts{Dir: dstPath}) assert.NoError(t, err) From 20929edc9962281e35a81756d76dd1caa5741ff8 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 17 Dec 2023 22:38:54 +0800 Subject: [PATCH 37/60] Add option to disable ambiguous unicode characters detection (#28454) * Close #24483 * Close #28123 * Close #23682 * Close #23149 (maybe more) --- custom/conf/app.example.ini | 3 + .../config-cheat-sheet.en-us.md | 1 + modules/charset/escape.go | 59 ++++--------------- modules/charset/escape_stream.go | 2 +- modules/charset/escape_test.go | 52 +++++----------- modules/git/command.go | 11 +--- modules/highlight/highlight.go | 29 +++++---- modules/highlight/highlight_test.go | 32 ++++++---- modules/indexer/code/search.go | 3 +- modules/markup/orgmode/orgmode.go | 2 +- modules/setting/ui.go | 5 ++ modules/util/string.go | 14 ++++- routers/web/repo/blame.go | 3 +- routers/web/repo/view.go | 24 ++++---- services/gitdiff/gitdiff.go | 6 +- services/gitdiff/highlightdiff.go | 6 +- templates/repo/view_file.tmpl | 6 +- 17 files changed, 111 insertions(+), 147 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index e10c4f7582e91..9a5d19074595f 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1212,6 +1212,9 @@ LEVEL = Info ;; Max size of files to be displayed (default is 8MiB) ;MAX_DISPLAY_FILE_SIZE = 8388608 ;; +;; Detect ambiguous unicode characters in file contents and show warnings on the UI +;AMBIGUOUS_UNICODE_DETECTION = true +;; ;; Whether the email of the user should be shown in the Explore Users page ;SHOW_USER_EMAIL = true ;; diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 1fa8dacb67e25..9810dab49bc15 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -220,6 +220,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `THEMES`: **gitea-auto,gitea-light,gitea-dark**: All available themes. Allow users select personalized themes. regardless of the value of `DEFAULT_THEME`. - `MAX_DISPLAY_FILE_SIZE`: **8388608**: Max size of files to be displayed (default is 8MiB) +- `AMBIGUOUS_UNICODE_DETECTION`: **true**: Detect ambiguous unicode characters in file contents and show warnings on the UI - `REACTIONS`: All available reactions users can choose on issues/prs and comments Values can be emoji alias (:smile:) or a unicode emoji. For custom reactions, add a tightly cropped square image to public/assets/img/emoji/reaction_name.png diff --git a/modules/charset/escape.go b/modules/charset/escape.go index 5608836a4510e..92e417d1f7283 100644 --- a/modules/charset/escape.go +++ b/modules/charset/escape.go @@ -8,11 +8,12 @@ package charset import ( - "bufio" + "html/template" "io" "strings" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/translation" ) @@ -20,20 +21,18 @@ import ( const RuneNBSP = 0xa0 // EscapeControlHTML escapes the unicode control sequences in a provided html document -func EscapeControlHTML(text string, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, output string) { +func EscapeControlHTML(html template.HTML, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, output template.HTML) { sb := &strings.Builder{} - outputStream := &HTMLStreamerWriter{Writer: sb} - streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer) - - if err := StreamHTML(strings.NewReader(text), streamer); err != nil { - streamer.escaped.HasError = true - log.Error("Error whilst escaping: %v", err) - } - return streamer.escaped, sb.String() + escaped, _ = EscapeControlReader(strings.NewReader(string(html)), sb, locale, allowed...) // err has been handled in EscapeControlReader + return escaped, template.HTML(sb.String()) } -// EscapeControlReaders escapes the unicode control sequences in a provided reader of HTML content and writer in a locale and returns the findings as an EscapeStatus and the escaped []byte +// EscapeControlReader escapes the unicode control sequences in a provided reader of HTML content and writer in a locale and returns the findings as an EscapeStatus func EscapeControlReader(reader io.Reader, writer io.Writer, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, err error) { + if !setting.UI.AmbiguousUnicodeDetection { + _, err = io.Copy(writer, reader) + return &EscapeStatus{}, err + } outputStream := &HTMLStreamerWriter{Writer: writer} streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer) @@ -43,41 +42,3 @@ func EscapeControlReader(reader io.Reader, writer io.Writer, locale translation. } return streamer.escaped, err } - -// EscapeControlStringReader escapes the unicode control sequences in a provided reader of string content and writer in a locale and returns the findings as an EscapeStatus and the escaped []byte. HTML line breaks are not inserted after every newline by this method. -func EscapeControlStringReader(reader io.Reader, writer io.Writer, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, err error) { - bufRd := bufio.NewReader(reader) - outputStream := &HTMLStreamerWriter{Writer: writer} - streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer) - - for { - line, rdErr := bufRd.ReadString('\n') - if len(line) > 0 { - if err := streamer.Text(line); err != nil { - streamer.escaped.HasError = true - log.Error("Error whilst escaping: %v", err) - return streamer.escaped, err - } - } - if rdErr != nil { - if rdErr != io.EOF { - err = rdErr - } - break - } - } - return streamer.escaped, err -} - -// EscapeControlString escapes the unicode control sequences in a provided string and returns the findings as an EscapeStatus and the escaped string -func EscapeControlString(text string, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, output string) { - sb := &strings.Builder{} - outputStream := &HTMLStreamerWriter{Writer: sb} - streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer) - - if err := streamer.Text(text); err != nil { - streamer.escaped.HasError = true - log.Error("Error whilst escaping: %v", err) - } - return streamer.escaped, sb.String() -} diff --git a/modules/charset/escape_stream.go b/modules/charset/escape_stream.go index 03d4cfc0c17bc..3f08fd94a497f 100644 --- a/modules/charset/escape_stream.go +++ b/modules/charset/escape_stream.go @@ -64,7 +64,7 @@ func (e *escapeStreamer) Text(data string) error { until, next = nextIdxs[0]+pos, nextIdxs[1]+pos } - // from pos until until we know that the runes are not \r\t\n or even ' ' + // from pos until we know that the runes are not \r\t\n or even ' ' runes := make([]rune, 0, next-until) positions := make([]int, 0, next-until+1) diff --git a/modules/charset/escape_test.go b/modules/charset/escape_test.go index f63c5c5c52b32..a353ced63169f 100644 --- a/modules/charset/escape_test.go +++ b/modules/charset/escape_test.go @@ -4,11 +4,14 @@ package charset import ( - "reflect" "strings" "testing" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/translation" + + "github.com/stretchr/testify/assert" ) type escapeControlTest struct { @@ -132,22 +135,8 @@ then resh (ר), and finally heh (ה) (which should appear leftmost).`, }, } -func TestEscapeControlString(t *testing.T) { - for _, tt := range escapeControlTests { - t.Run(tt.name, func(t *testing.T) { - status, result := EscapeControlString(tt.text, &translation.MockLocale{}) - if !reflect.DeepEqual(*status, tt.status) { - t.Errorf("EscapeControlString() status = %v, wanted= %v", status, tt.status) - } - if result != tt.result { - t.Errorf("EscapeControlString()\nresult= %v,\nwanted= %v", result, tt.result) - } - }) - } -} - func TestEscapeControlReader(t *testing.T) { - // lets add some control characters to the tests + // add some control characters to the tests tests := make([]escapeControlTest, 0, len(escapeControlTests)*3) copy(tests, escapeControlTests) @@ -169,29 +158,20 @@ func TestEscapeControlReader(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - input := strings.NewReader(tt.text) output := &strings.Builder{} - status, err := EscapeControlReader(input, output, &translation.MockLocale{}) - result := output.String() - if err != nil { - t.Errorf("EscapeControlReader(): err = %v", err) - } - - if !reflect.DeepEqual(*status, tt.status) { - t.Errorf("EscapeControlReader() status = %v, wanted= %v", status, tt.status) - } - if result != tt.result { - t.Errorf("EscapeControlReader()\nresult= %v,\nwanted= %v", result, tt.result) - } + status, err := EscapeControlReader(strings.NewReader(tt.text), output, &translation.MockLocale{}) + assert.NoError(t, err) + assert.Equal(t, tt.status, *status) + assert.Equal(t, tt.result, output.String()) }) } } -func TestEscapeControlReader_panic(t *testing.T) { - bs := make([]byte, 0, 20479) - bs = append(bs, 'A') - for i := 0; i < 6826; i++ { - bs = append(bs, []byte("—")...) - } - _, _ = EscapeControlString(string(bs), &translation.MockLocale{}) +func TestSettingAmbiguousUnicodeDetection(t *testing.T) { + defer test.MockVariableValue(&setting.UI.AmbiguousUnicodeDetection, true)() + _, out := EscapeControlHTML("a test", &translation.MockLocale{}) + assert.EqualValues(t, `a test`, out) + setting.UI.AmbiguousUnicodeDetection = false + _, out = EscapeControlHTML("a test", &translation.MockLocale{}) + assert.EqualValues(t, `a test`, out) } diff --git a/modules/git/command.go b/modules/git/command.go index f095bb18bef75..9305ef6f928e7 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -14,7 +14,6 @@ import ( "os/exec" "strings" "time" - "unsafe" "code.gitea.io/gitea/modules/git/internal" //nolint:depguard // only this file can use the internal type CmdArg, other files and packages should use AddXxx functions "code.gitea.io/gitea/modules/log" @@ -389,15 +388,11 @@ func (r *runStdError) IsExitCode(code int) bool { return false } -func bytesToString(b []byte) string { - return *(*string)(unsafe.Pointer(&b)) // that's what Golang's strings.Builder.String() does (go/src/strings/builder.go) -} - // RunStdString runs the command with options and returns stdout/stderr as string. and store stderr to returned error (err combined with stderr). func (c *Command) RunStdString(opts *RunOpts) (stdout, stderr string, runErr RunStdError) { stdoutBytes, stderrBytes, err := c.RunStdBytes(opts) - stdout = bytesToString(stdoutBytes) - stderr = bytesToString(stderrBytes) + stdout = util.UnsafeBytesToString(stdoutBytes) + stderr = util.UnsafeBytesToString(stderrBytes) if err != nil { return stdout, stderr, &runStdError{err: err, stderr: stderr} } @@ -432,7 +427,7 @@ func (c *Command) RunStdBytes(opts *RunOpts) (stdout, stderr []byte, runErr RunS err := c.Run(newOpts) stderr = stderrBuf.Bytes() if err != nil { - return nil, stderr, &runStdError{err: err, stderr: bytesToString(stderr)} + return nil, stderr, &runStdError{err: err, stderr: util.UnsafeBytesToString(stderr)} } // even if there is no err, there could still be some stderr output return stdoutBuf.Bytes(), stderr, nil diff --git a/modules/highlight/highlight.go b/modules/highlight/highlight.go index a67217e864675..d7ab3f7afd3e7 100644 --- a/modules/highlight/highlight.go +++ b/modules/highlight/highlight.go @@ -9,6 +9,7 @@ import ( "bytes" "fmt" gohtml "html" + "html/template" "io" "path/filepath" "strings" @@ -55,7 +56,7 @@ func NewContext() { } // Code returns a HTML version of code string with chroma syntax highlighting classes and the matched lexer name -func Code(fileName, language, code string) (string, string) { +func Code(fileName, language, code string) (output template.HTML, lexerName string) { NewContext() // diff view newline will be passed as empty, change to literal '\n' so it can be copied @@ -65,7 +66,7 @@ func Code(fileName, language, code string) (string, string) { } if len(code) > sizeLimit { - return code, "" + return template.HTML(template.HTMLEscapeString(code)), "" } var lexer chroma.Lexer @@ -102,13 +103,11 @@ func Code(fileName, language, code string) (string, string) { cache.Add(fileName, lexer) } - lexerName := formatLexerName(lexer.Config().Name) - - return CodeFromLexer(lexer, code), lexerName + return CodeFromLexer(lexer, code), formatLexerName(lexer.Config().Name) } // CodeFromLexer returns a HTML version of code string with chroma syntax highlighting classes -func CodeFromLexer(lexer chroma.Lexer, code string) string { +func CodeFromLexer(lexer chroma.Lexer, code string) template.HTML { formatter := html.New(html.WithClasses(true), html.WithLineNumbers(false), html.PreventSurroundingPre(true), @@ -120,23 +119,23 @@ func CodeFromLexer(lexer chroma.Lexer, code string) string { iterator, err := lexer.Tokenise(nil, code) if err != nil { log.Error("Can't tokenize code: %v", err) - return code + return template.HTML(template.HTMLEscapeString(code)) } // style not used for live site but need to pass something err = formatter.Format(htmlw, githubStyles, iterator) if err != nil { log.Error("Can't format code: %v", err) - return code + return template.HTML(template.HTMLEscapeString(code)) } _ = htmlw.Flush() // Chroma will add newlines for certain lexers in order to highlight them properly // Once highlighted, strip them here, so they don't cause copy/paste trouble in HTML output - return strings.TrimSuffix(htmlbuf.String(), "\n") + return template.HTML(strings.TrimSuffix(htmlbuf.String(), "\n")) } // File returns a slice of chroma syntax highlighted HTML lines of code and the matched lexer name -func File(fileName, language string, code []byte) ([]string, string, error) { +func File(fileName, language string, code []byte) ([]template.HTML, string, error) { NewContext() if len(code) > sizeLimit { @@ -183,14 +182,14 @@ func File(fileName, language string, code []byte) ([]string, string, error) { tokensLines := chroma.SplitTokensIntoLines(iterator.Tokens()) htmlBuf := &bytes.Buffer{} - lines := make([]string, 0, len(tokensLines)) + lines := make([]template.HTML, 0, len(tokensLines)) for _, tokens := range tokensLines { iterator = chroma.Literator(tokens...) err = formatter.Format(htmlBuf, githubStyles, iterator) if err != nil { return nil, "", fmt.Errorf("can't format code: %w", err) } - lines = append(lines, htmlBuf.String()) + lines = append(lines, template.HTML(htmlBuf.String())) htmlBuf.Reset() } @@ -198,9 +197,9 @@ func File(fileName, language string, code []byte) ([]string, string, error) { } // PlainText returns non-highlighted HTML for code -func PlainText(code []byte) []string { +func PlainText(code []byte) []template.HTML { r := bufio.NewReader(bytes.NewReader(code)) - m := make([]string, 0, bytes.Count(code, []byte{'\n'})+1) + m := make([]template.HTML, 0, bytes.Count(code, []byte{'\n'})+1) for { content, err := r.ReadString('\n') if err != nil && err != io.EOF { @@ -210,7 +209,7 @@ func PlainText(code []byte) []string { if content == "" && err == io.EOF { break } - s := gohtml.EscapeString(content) + s := template.HTML(gohtml.EscapeString(content)) m = append(m, s) } return m diff --git a/modules/highlight/highlight_test.go b/modules/highlight/highlight_test.go index 7a9887728f18d..659688bd0fdba 100644 --- a/modules/highlight/highlight_test.go +++ b/modules/highlight/highlight_test.go @@ -4,21 +4,36 @@ package highlight import ( + "html/template" "strings" "testing" "github.com/stretchr/testify/assert" ) -func lines(s string) []string { - return strings.Split(strings.ReplaceAll(strings.TrimSpace(s), `\n`, "\n"), "\n") +func lines(s string) (out []template.HTML) { + // "" => [], "a" => ["a"], "a\n" => ["a\n"], "a\nb" => ["a\n", "b"] (each line always includes EOL "\n" if it exists) + out = make([]template.HTML, 0) + s = strings.ReplaceAll(strings.ReplaceAll(strings.TrimSpace(s), "\n", ""), `\n`, "\n") + for { + if p := strings.IndexByte(s, '\n'); p != -1 { + out = append(out, template.HTML(s[:p+1])) + s = s[p+1:] + } else { + break + } + } + if s != "" { + out = append(out, template.HTML(s)) + } + return out } func TestFile(t *testing.T) { tests := []struct { name string code string - want []string + want []template.HTML lexerName string }{ { @@ -99,10 +114,7 @@ c=2 t.Run(tt.name, func(t *testing.T) { out, lexerName, err := File(tt.name, "", []byte(tt.code)) assert.NoError(t, err) - expected := strings.Join(tt.want, "\n") - actual := strings.Join(out, "\n") - assert.Equal(t, strings.Count(actual, "")) - assert.EqualValues(t, expected, actual) + assert.EqualValues(t, tt.want, out) assert.Equal(t, tt.lexerName, lexerName) }) } @@ -112,7 +124,7 @@ func TestPlainText(t *testing.T) { tests := []struct { name string code string - want []string + want []template.HTML }{ { name: "empty.py", @@ -165,9 +177,7 @@ c=2`), for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { out := PlainText([]byte(tt.code)) - expected := strings.Join(tt.want, "\n") - actual := strings.Join(out, "\n") - assert.EqualValues(t, expected, actual) + assert.EqualValues(t, tt.want, out) }) } } diff --git a/modules/indexer/code/search.go b/modules/indexer/code/search.go index fdb468df1ab5b..e19e22eea0e1e 100644 --- a/modules/indexer/code/search.go +++ b/modules/indexer/code/search.go @@ -6,6 +6,7 @@ package code import ( "bytes" "context" + "html/template" "strings" "code.gitea.io/gitea/modules/highlight" @@ -22,7 +23,7 @@ type Result struct { Language string Color string LineNumbers []int - FormattedLines string + FormattedLines template.HTML } type SearchResultLanguages = internal.SearchResultLanguages diff --git a/modules/markup/orgmode/orgmode.go b/modules/markup/orgmode/orgmode.go index c1e0144199323..e7af02b49670f 100644 --- a/modules/markup/orgmode/orgmode.go +++ b/modules/markup/orgmode/orgmode.go @@ -87,7 +87,7 @@ func Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error } lexer = chroma.Coalesce(lexer) - if _, err := w.WriteString(highlight.CodeFromLexer(lexer, source)); err != nil { + if _, err := w.WriteString(string(highlight.CodeFromLexer(lexer, source))); err != nil { return "" } } diff --git a/modules/setting/ui.go b/modules/setting/ui.go index 31042d3ee0dda..f94e6206cd995 100644 --- a/modules/setting/ui.go +++ b/modules/setting/ui.go @@ -35,6 +35,8 @@ var UI = struct { OnlyShowRelevantRepos bool ExploreDefaultSort string `ini:"EXPLORE_PAGING_DEFAULT_SORT"` + AmbiguousUnicodeDetection bool + Notification struct { MinTimeout time.Duration TimeoutStep time.Duration @@ -82,6 +84,9 @@ var UI = struct { Reactions: []string{`+1`, `-1`, `laugh`, `hooray`, `confused`, `heart`, `rocket`, `eyes`}, CustomEmojis: []string{`git`, `gitea`, `codeberg`, `gitlab`, `github`, `gogs`}, CustomEmojisMap: map[string]string{"git": ":git:", "gitea": ":gitea:", "codeberg": ":codeberg:", "gitlab": ":gitlab:", "github": ":github:", "gogs": ":gogs:"}, + + AmbiguousUnicodeDetection: true, + Notification: struct { MinTimeout time.Duration TimeoutStep time.Duration diff --git a/modules/util/string.go b/modules/util/string.go index f2def7b0ece2c..2cf44d29b1f0a 100644 --- a/modules/util/string.go +++ b/modules/util/string.go @@ -3,7 +3,7 @@ package util -import "github.com/yuin/goldmark/util" +import "unsafe" func isSnakeCaseUpper(c byte) bool { return 'A' <= c && c <= 'Z' @@ -83,5 +83,15 @@ func ToSnakeCase(input string) string { } } } - return util.BytesToReadOnlyString(res) + return UnsafeBytesToString(res) +} + +// UnsafeBytesToString uses Go's unsafe package to convert a byte slice to a string. +// TODO: replace all "goldmark/util.BytesToReadOnlyString" with this official approach +func UnsafeBytesToString(b []byte) string { + return unsafe.String(unsafe.SliceData(b), len(b)) +} + +func UnsafeStringToBytes(s string) []byte { + return unsafe.Slice(unsafe.StringData(s), len(s)) } diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go index db9be51257e7f..b2374e32c2849 100644 --- a/routers/web/repo/blame.go +++ b/routers/web/repo/blame.go @@ -315,8 +315,7 @@ func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames m lexerName = lexerNameForLine } - br.EscapeStatus, line = charset.EscapeControlHTML(line, ctx.Locale) - br.Code = gotemplate.HTML(line) + br.EscapeStatus, br.Code = charset.EscapeControlHTML(line, ctx.Locale) rows = append(rows, br) escapeStatus = escapeStatus.Or(br.EscapeStatus) } diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 70556185bb53b..9cf0dff5d8e2f 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -9,6 +9,7 @@ import ( gocontext "context" "encoding/base64" "fmt" + "html/template" "image" "io" "net/http" @@ -317,19 +318,18 @@ func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.Tr }, rd) if err != nil { log.Error("Render failed for %s in %-v: %v Falling back to rendering source", readmeFile.Name(), ctx.Repo.Repository, err) - buf := &bytes.Buffer{} - ctx.Data["EscapeStatus"], _ = charset.EscapeControlStringReader(rd, buf, ctx.Locale) - ctx.Data["FileContent"] = buf.String() + delete(ctx.Data, "IsMarkup") } - } else { + } + + if ctx.Data["IsMarkup"] != true { ctx.Data["IsPlainText"] = true - buf := &bytes.Buffer{} - ctx.Data["EscapeStatus"], err = charset.EscapeControlStringReader(rd, buf, ctx.Locale) + content, err := io.ReadAll(rd) if err != nil { - log.Error("Read failed: %v", err) + log.Error("Read readme content failed: %v", err) } - - ctx.Data["FileContent"] = buf.String() + contentEscaped := template.HTMLEscapeString(util.UnsafeBytesToString(content)) + ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlHTML(template.HTML(contentEscaped), ctx.Locale) } if !fInfo.isLFSFile && ctx.Repo.CanEnableEditor(ctx, ctx.Doer) { @@ -493,7 +493,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st buf, _ := io.ReadAll(rd) // The Open Group Base Specification: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html - // empty: 0 lines; "a": 1 line, 1 incomplete-line; "a\n": 1 line; "a\nb": 1 line, 1 incomplete-line; + // empty: 0 lines; "a": 1 incomplete-line; "a\n": 1 line; "a\nb": 1 line, 1 incomplete-line; // Gitea uses the definition (like most modern editors): // empty: 0 lines; "a": 1 line; "a\n": 2 lines; "a\nb": 2 lines; // When rendering, the last empty line is not rendered in UI, while the line-number is still counted, to tell users that the file contains a trailing EOL. @@ -620,7 +620,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st } } -func markupRender(ctx *context.Context, renderCtx *markup.RenderContext, input io.Reader) (escaped *charset.EscapeStatus, output string, err error) { +func markupRender(ctx *context.Context, renderCtx *markup.RenderContext, input io.Reader) (escaped *charset.EscapeStatus, output template.HTML, err error) { markupRd, markupWr := io.Pipe() defer markupWr.Close() done := make(chan struct{}) @@ -628,7 +628,7 @@ func markupRender(ctx *context.Context, renderCtx *markup.RenderContext, input i sb := &strings.Builder{} // We allow NBSP here this is rendered escaped, _ = charset.EscapeControlReader(markupRd, sb, ctx.Locale, charset.RuneNBSP) - output = sb.String() + output = template.HTML(sb.String()) close(done) }() err = markup.Render(renderCtx, input, markupWr) diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 75fc687c86a52..0f6e2b6c17d5b 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -285,15 +285,15 @@ type DiffInline struct { // DiffInlineWithUnicodeEscape makes a DiffInline with hidden unicode characters escaped func DiffInlineWithUnicodeEscape(s template.HTML, locale translation.Locale) DiffInline { - status, content := charset.EscapeControlHTML(string(s), locale) - return DiffInline{EscapeStatus: status, Content: template.HTML(content)} + status, content := charset.EscapeControlHTML(s, locale) + return DiffInline{EscapeStatus: status, Content: content} } // DiffInlineWithHighlightCode makes a DiffInline with code highlight and hidden unicode characters escaped func DiffInlineWithHighlightCode(fileName, language, code string, locale translation.Locale) DiffInline { highlighted, _ := highlight.Code(fileName, language, code) status, content := charset.EscapeControlHTML(highlighted, locale) - return DiffInline{EscapeStatus: status, Content: template.HTML(content)} + return DiffInline{EscapeStatus: status, Content: content} } // GetComputedInlineDiffFor computes inline diff for the given line. diff --git a/services/gitdiff/highlightdiff.go b/services/gitdiff/highlightdiff.go index f1e2b1d3cb31a..35d48445504ae 100644 --- a/services/gitdiff/highlightdiff.go +++ b/services/gitdiff/highlightdiff.go @@ -93,10 +93,10 @@ func (hcd *highlightCodeDiff) diffWithHighlight(filename, language, codeA, codeB highlightCodeA, _ := highlight.Code(filename, language, codeA) highlightCodeB, _ := highlight.Code(filename, language, codeB) - highlightCodeA = hcd.convertToPlaceholders(highlightCodeA) - highlightCodeB = hcd.convertToPlaceholders(highlightCodeB) + convertedCodeA := hcd.convertToPlaceholders(string(highlightCodeA)) + convertedCodeB := hcd.convertToPlaceholders(string(highlightCodeB)) - diffs := diffMatchPatch.DiffMain(highlightCodeA, highlightCodeB, true) + diffs := diffMatchPatch.DiffMain(convertedCodeA, convertedCodeB, true) diffs = diffMatchPatch.DiffCleanupEfficiency(diffs) for i := range diffs { diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index 4129a133b7e76..e7d1c04c12ef2 100644 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -74,9 +74,9 @@ {{end}}
{{if .IsMarkup}} - {{if .FileContent}}{{.FileContent | Safe}}{{end}} + {{if .FileContent}}{{.FileContent}}{{end}} {{else if .IsPlainText}} -
{{if .FileContent}}{{.FileContent | Safe}}{{end}}
+
{{if .FileContent}}{{.FileContent}}{{end}}
{{else if not .IsTextSource}}
{{if .IsImageFile}} @@ -114,7 +114,7 @@ {{if $.EscapeStatus.Escaped}} {{if (index $.LineEscapeStatus $idx).Escaped}}{{end}} {{end}} - {{$code | Safe}} + {{$code}} {{end}} From 69f2b698c5000a566bc04267f7e9bd387b880109 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Mon, 18 Dec 2023 00:25:45 +0000 Subject: [PATCH 38/60] [skip ci] Updated translations via Crowdin --- options/locale/locale_ja-JP.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 7a7dcea8f8988..c2557b180e7ce 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -888,7 +888,7 @@ webauthn_nickname=ニックネーム webauthn_delete_key=セキュリティキーの登録解除 webauthn_delete_key_desc=セキュリティキーの登録を解除すると、今後そのセキュリティキーでサインインすることはできなくなります。 続行しますか? webauthn_key_loss_warning=セキュリティキーを紛失すると、アカウントへのアクセスを失います。 -webauthn_alternative_tip=もうひとつ別の認証方法も設定すると良いかもしれません。 +webauthn_alternative_tip=もうひとつ別の認証方法も設定しておくと良いでしょう。 manage_account_links=連携アカウントの管理 manage_account_links_desc=これらの外部アカウントがGiteaアカウントと連携されています。 @@ -3457,7 +3457,7 @@ owner.settings.chef.keypair.description=Chefレジストリの認証にはキー [secrets] secrets=シークレット description=シークレットは特定のActionsに渡されます。 それ以外で読み出されることはありません。 -none=まだシークレットはありません。 +none=シークレットはまだありません。 creation=シークレットを追加 creation.name_placeholder=大文字小文字の区別なし、英数字とアンダースコアのみ、GITEA_ や GITHUB_ で始まるものは不可 creation.value_placeholder=内容を入力してください。前後の空白は除去されます。 From bf8b082c40f2aee7d3fbd3c68d73886e13381712 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 18 Dec 2023 22:53:04 +0800 Subject: [PATCH 39/60] Improve the prompt for "ssh-keygen sign" (#28509) Close #28505, ref: * https://github.com/go-gitea/gitea/pull/20112#issuecomment-1165423026 * https://github.com/go-gitea/gitea/issues/28505#issuecomment-1860048116 --- templates/user/settings/keys_ssh.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/user/settings/keys_ssh.tmpl b/templates/user/settings/keys_ssh.tmpl index f4aa7ef9689a8..fc8b70ea289f3 100644 --- a/templates/user/settings/keys_ssh.tmpl +++ b/templates/user/settings/keys_ssh.tmpl @@ -78,7 +78,7 @@

{{ctx.Locale.Tr "settings.ssh_token_help"}}

-

{{printf "echo -n '%s' | ssh-keygen -Y sign -n gitea -f /path_to_your_privkey" $.TokenToSign}}

+

{{printf "echo -n '%s' | ssh-keygen -Y sign -n gitea -f /path_to_PrivateKey_or_RelatedPublicKey" $.TokenToSign}}


From e02095c5b6e04f70ae6562f5aee169f7ee93cf7a Mon Sep 17 00:00:00 2001 From: Earl Warren <109468362+earl-warren@users.noreply.github.com> Date: Mon, 18 Dec 2023 16:32:08 +0100 Subject: [PATCH 40/60] Add orphaned topic consistency check (#28507) - If a topic has zero repository count, it means that none of the repositories are using that topic, that would make them 'useless' to keep. One caveat is that if that topic is going to be used in the future, it will be added again to the database, but simply with a new ID. Refs: https://codeberg.org/forgejo/forgejo/pulls/1964 Co-authored-by: Gusted --- models/repo/topic.go | 10 ++++++++++ modules/doctor/dbconsistency.go | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/models/repo/topic.go b/models/repo/topic.go index ca533fc1e0919..b71f43bc88046 100644 --- a/models/repo/topic.go +++ b/models/repo/topic.go @@ -377,3 +377,13 @@ func syncTopicsInRepository(sess db.Engine, repoID int64) error { } return nil } + +// CountOrphanedAttachments returns the number of topics that don't belong to any repository. +func CountOrphanedTopics(ctx context.Context) (int64, error) { + return db.GetEngine(ctx).Where("repo_count = 0").Count(new(Topic)) +} + +// DeleteOrphanedAttachments delete all topics that don't belong to any repository. +func DeleteOrphanedTopics(ctx context.Context) (int64, error) { + return db.GetEngine(ctx).Where("repo_count = 0").Delete(new(Topic)) +} diff --git a/modules/doctor/dbconsistency.go b/modules/doctor/dbconsistency.go index ac983f916157c..e2dcb63f33a7c 100644 --- a/modules/doctor/dbconsistency.go +++ b/modules/doctor/dbconsistency.go @@ -158,6 +158,12 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er Fixer: actions_model.FixRunnersWithoutBelongingOwner, FixedMessage: "Removed", }, + { + Name: "Topics with empty repository count", + Counter: repo_model.CountOrphanedTopics, + Fixer: repo_model.DeleteOrphanedTopics, + FixedMessage: "Removed", + }, } // TODO: function to recalc all counters From 4ea522fecfd8f2d6b51466cb9ab6772f4594bf2e Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Tue, 19 Dec 2023 01:06:19 +0900 Subject: [PATCH 41/60] Only check online runner when detecting matching runners in workflows (#28286) Mentioned: [#28277](https://github.com/go-gitea/gitea/issues/28277#issuecomment-1831325276) We should only check online runner when detecting matching runners in workflows, as if runner is not online, the workflow will not run. ![image](https://github.com/go-gitea/gitea/assets/18380374/11855e9d-7241-4b7a-b8d7-49dbb94ba1c5) --- models/actions/runner.go | 17 +++++++++++++++-- options/locale/locale_en-US.ini | 2 +- routers/web/repo/actions/actions.go | 4 +++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/models/actions/runner.go b/models/actions/runner.go index 717b770800dc5..5630741550d5d 100644 --- a/models/actions/runner.go +++ b/models/actions/runner.go @@ -51,6 +51,11 @@ type ActionRunner struct { Deleted timeutil.TimeStamp `xorm:"deleted"` } +const ( + RunnerOfflineTime = time.Minute + RunnerIdleTime = 10 * time.Second +) + // BelongsToOwnerName before calling, should guarantee that all attributes are loaded func (r *ActionRunner) BelongsToOwnerName() string { if r.RepoID != 0 { @@ -76,11 +81,12 @@ func (r *ActionRunner) BelongsToOwnerType() types.OwnerType { return types.OwnerTypeSystemGlobal } +// if the logic here changed, you should also modify FindRunnerOptions.ToCond func (r *ActionRunner) Status() runnerv1.RunnerStatus { - if time.Since(r.LastOnline.AsTime()) > time.Minute { + if time.Since(r.LastOnline.AsTime()) > RunnerOfflineTime { return runnerv1.RunnerStatus_RUNNER_STATUS_OFFLINE } - if time.Since(r.LastActive.AsTime()) > 10*time.Second { + if time.Since(r.LastActive.AsTime()) > RunnerIdleTime { return runnerv1.RunnerStatus_RUNNER_STATUS_IDLE } return runnerv1.RunnerStatus_RUNNER_STATUS_ACTIVE @@ -153,6 +159,7 @@ type FindRunnerOptions struct { OwnerID int64 Sort string Filter string + IsOnline util.OptionalBool WithAvailable bool // not only runners belong to, but also runners can be used } @@ -178,6 +185,12 @@ func (opts FindRunnerOptions) ToConds() builder.Cond { if opts.Filter != "" { cond = cond.And(builder.Like{"name", opts.Filter}) } + + if opts.IsOnline.IsTrue() { + cond = cond.And(builder.Gt{"last_online": time.Now().Add(-RunnerOfflineTime).Unix()}) + } else if opts.IsOnline.IsFalse() { + cond = cond.And(builder.Lte{"last_online": time.Now().Add(-RunnerOfflineTime).Unix()}) + } return cond } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index e57dd7794e4db..53f0402e2dfaa 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3525,7 +3525,7 @@ runs.commit = Commit runs.scheduled = Scheduled runs.pushed_by = pushed by runs.invalid_workflow_helper = Workflow config file is invalid. Please check your config file: %s -runs.no_matching_runner_helper = No matching runner: %s +runs.no_matching_online_runner_helper = No matching online runner with label: %s runs.actor = Actor runs.status = Status runs.actors_no_select = All actors diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index fd541647b716e..fe528a483b4a2 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -18,6 +18,7 @@ import ( "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/web/repo" "code.gitea.io/gitea/services/convert" @@ -77,6 +78,7 @@ func List(ctx *context.Context) { // Get all runner labels runners, err := db.Find[actions_model.ActionRunner](ctx, actions_model.FindRunnerOptions{ RepoID: ctx.Repo.Repository.ID, + IsOnline: util.OptionalBoolTrue, WithAvailable: true, }) if err != nil { @@ -113,7 +115,7 @@ func List(ctx *context.Context) { continue } if !allRunnerLabels.Contains(ro) { - workflow.ErrMsg = ctx.Locale.Tr("actions.runs.no_matching_runner_helper", ro) + workflow.ErrMsg = ctx.Locale.Tr("actions.runs.no_matching_online_runner_helper", ro) break } } From cd2ff6e83dba82e7d810b68bba79242a98ea8248 Mon Sep 17 00:00:00 2001 From: Yevhen Pavlov Date: Mon, 18 Dec 2023 23:42:04 +0200 Subject: [PATCH 42/60] Bump google/go-github to v57 (#28514) --- assets/go-licenses.json | 4 ++-- contrib/backport/backport.go | 2 +- go.mod | 2 +- go.sum | 7 ++++--- services/migrations/error.go | 2 +- services/migrations/github.go | 8 ++++---- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/assets/go-licenses.json b/assets/go-licenses.json index ee1e503f2a672..adcac88d348ac 100644 --- a/assets/go-licenses.json +++ b/assets/go-licenses.json @@ -545,8 +545,8 @@ "licenseText": "Copyright (c) 2011 The Snappy-Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }, { - "name": "github.com/google/go-github/v53/github", - "path": "github.com/google/go-github/v53/github/LICENSE", + "name": "github.com/google/go-github/v57/github", + "path": "github.com/google/go-github/v57/github/LICENSE", "licenseText": "Copyright (c) 2013 The go-github AUTHORS. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }, { diff --git a/contrib/backport/backport.go b/contrib/backport/backport.go index 5cd0fe0f6e6da..820c0702b742d 100644 --- a/contrib/backport/backport.go +++ b/contrib/backport/backport.go @@ -17,7 +17,7 @@ import ( "strings" "syscall" - "github.com/google/go-github/v53/github" + "github.com/google/go-github/v57/github" "github.com/urfave/cli/v2" "gopkg.in/yaml.v3" ) diff --git a/go.mod b/go.mod index 569f8cd359156..0d0147628256d 100644 --- a/go.mod +++ b/go.mod @@ -55,7 +55,7 @@ require ( github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 github.com/golang-jwt/jwt/v5 v5.0.0 - github.com/google/go-github/v53 v53.2.0 + github.com/google/go-github/v57 v57.0.0 github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 github.com/google/uuid v1.3.1 github.com/gorilla/feeds v1.1.1 diff --git a/go.sum b/go.sum index 9c9defb12aef7..f3c20981b477a 100644 --- a/go.sum +++ b/go.sum @@ -533,10 +533,11 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI= -github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-github/v57 v57.0.0 h1:L+Y3UPTY8ALM8x+TV0lg+IEBI+upibemtBD8Q9u7zHs= +github.com/google/go-github/v57 v57.0.0/go.mod h1:s0omdnye0hvK/ecLvpsGfJMiRt85PimQh4oygmLIxHw= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= diff --git a/services/migrations/error.go b/services/migrations/error.go index c8e6c8fe13d95..5e0e0742c9293 100644 --- a/services/migrations/error.go +++ b/services/migrations/error.go @@ -7,7 +7,7 @@ package migrations import ( "errors" - "github.com/google/go-github/v53/github" + "github.com/google/go-github/v57/github" ) // ErrRepoNotCreated returns the error that repository not created diff --git a/services/migrations/github.go b/services/migrations/github.go index f27c1a34dafb4..be573b33b3f8c 100644 --- a/services/migrations/github.go +++ b/services/migrations/github.go @@ -20,7 +20,7 @@ import ( "code.gitea.io/gitea/modules/proxy" "code.gitea.io/gitea/modules/structs" - "github.com/google/go-github/v53/github" + "github.com/google/go-github/v57/github" "golang.org/x/oauth2" ) @@ -135,7 +135,7 @@ func (g *GithubDownloaderV3) LogString() string { func (g *GithubDownloaderV3) addClient(client *http.Client, baseURL string) { githubClient := github.NewClient(client) if baseURL != "https://github.com" { - githubClient, _ = github.NewEnterpriseClient(baseURL, baseURL, client) + githubClient, _ = github.NewClient(client).WithEnterpriseURLs(baseURL, baseURL) } g.clients = append(g.clients, githubClient) g.rates = append(g.rates, nil) @@ -168,14 +168,14 @@ func (g *GithubDownloaderV3) waitAndPickClient() { err := g.RefreshRate() if err != nil { - log.Error("g.getClient().RateLimits: %s", err) + log.Error("g.getClient().RateLimit.Get: %s", err) } } } // RefreshRate update the current rate (doesn't count in rate limit) func (g *GithubDownloaderV3) RefreshRate() error { - rates, _, err := g.getClient().RateLimits(g.ctx) + rates, _, err := g.getClient().RateLimit.Get(g.ctx) if err != nil { // if rate limit is not enabled, ignore it if strings.Contains(err.Error(), "404") { From 11f0519ad852809d842e3382595579d8f3ffbc87 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 19 Dec 2023 09:18:42 +0800 Subject: [PATCH 43/60] Update go dependencies (#28518) Update golang.org/x/crypto for CVE-2023-48795 and update other packages. `go-git` is not updated because it needs time to figure out why some tests fail. --- assets/go-licenses.json | 14 +- go.mod | 164 ++++----- go.sum | 477 +++++++++----------------- modules/git/repo_commitgraph_gogit.go | 2 +- services/cron/tasks_test.go | 18 +- 5 files changed, 273 insertions(+), 402 deletions(-) diff --git a/assets/go-licenses.json b/assets/go-licenses.json index adcac88d348ac..846cd55276689 100644 --- a/assets/go-licenses.json +++ b/assets/go-licenses.json @@ -572,27 +572,27 @@ { "name": "github.com/gorilla/css/scanner", "path": "github.com/gorilla/css/scanner/LICENSE", - "licenseText": "Copyright (c) 2013, Gorilla web toolkit\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n Redistributions in binary form must reproduce the above copyright notice, this\n list of conditions and the following disclaimer in the documentation and/or\n other materials provided with the distribution.\n\n Neither the name of the {organization} nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "licenseText": "Copyright (c) 2023 The Gorilla Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n\t * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\t * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\t * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n" }, { "name": "github.com/gorilla/feeds", "path": "github.com/gorilla/feeds/LICENSE", - "licenseText": "Copyright (c) 2013-2018 The Gorilla Feeds Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "licenseText": "Copyright (c) 2023 The Gorilla Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n\t * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\t * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\t * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n" }, { "name": "github.com/gorilla/mux", "path": "github.com/gorilla/mux/LICENSE", - "licenseText": "Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n\t * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\t * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\t * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "licenseText": "Copyright (c) 2023 The Gorilla Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n\t * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\t * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\t * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }, { "name": "github.com/gorilla/securecookie", "path": "github.com/gorilla/securecookie/LICENSE", - "licenseText": "Copyright (c) 2012 Rodrigo Moraes. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n\t * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\t * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\t * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "licenseText": "Copyright (c) 2023 The Gorilla Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n\t * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\t * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\t * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }, { "name": "github.com/gorilla/sessions", "path": "github.com/gorilla/sessions/LICENSE", - "licenseText": "Copyright (c) 2012-2018 The Gorilla Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n\t * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\t * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\t * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + "licenseText": "Copyright (c) 2023 The Gorilla Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n\t * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\t * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\t * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }, { "name": "github.com/hashicorp/go-cleanhttp", @@ -735,8 +735,8 @@ "licenseText": "The MIT License (MIT)\n\nCopyright (c) 2016 Yasuhiro Matsumoto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" }, { - "name": "github.com/matttproud/golang_protobuf_extensions/pbutil", - "path": "github.com/matttproud/golang_protobuf_extensions/pbutil/LICENSE", + "name": "github.com/matttproud/golang_protobuf_extensions/v2/pbutil", + "path": "github.com/matttproud/golang_protobuf_extensions/v2/pbutil/LICENSE", "licenseText": " Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"{}\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright {yyyy} {name of copyright owner}\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n" }, { diff --git a/go.mod b/go.mod index 0d0147628256d..54a56086701c3 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.21 require ( code.gitea.io/actions-proto-go v0.3.1 code.gitea.io/gitea-vet v0.2.3 - code.gitea.io/sdk/gitea v0.16.0 + code.gitea.io/sdk/gitea v0.17.0 codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 gitea.com/go-chi/binding v0.0.0-20230415142243-04b515c6d669 gitea.com/go-chi/cache v0.2.0 @@ -17,12 +17,12 @@ require ( github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 github.com/NYTimes/gziphandler v1.1.1 github.com/PuerkitoBio/goquery v1.8.1 - github.com/alecthomas/chroma/v2 v2.10.0 + github.com/alecthomas/chroma/v2 v2.12.0 github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb github.com/blevesearch/bleve/v2 v2.3.10 github.com/bufbuild/connect-go v1.10.0 - github.com/buildkite/terminal-to-html/v3 v3.9.1 - github.com/caddyserver/certmagic v0.19.2 + github.com/buildkite/terminal-to-html/v3 v3.10.0 + github.com/caddyserver/certmagic v0.20.0 github.com/chi-middleware/proxy v1.1.1 github.com/denisenkom/go-mssqldb v0.12.3 github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21 @@ -35,13 +35,13 @@ require ( github.com/emirpasic/gods v1.18.1 github.com/ethantkoenig/rupture v1.0.1 github.com/felixge/fgprof v0.9.3 - github.com/fsnotify/fsnotify v1.6.0 + github.com/fsnotify/fsnotify v1.7.0 github.com/gliderlabs/ssh v0.3.6-0.20230927171611-ece6c7995e46 - github.com/go-ap/activitypub v0.0.0-20231003111253-1fba3772399b + github.com/go-ap/activitypub v0.0.0-20231114162308-e219254dc5c9 github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73 github.com/go-chi/chi/v5 v5.0.10 github.com/go-chi/cors v1.2.1 - github.com/go-co-op/gocron v1.31.1 + github.com/go-co-op/gocron v1.37.0 github.com/go-enry/go-enry/v2 v2.8.6 github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e github.com/go-git/go-billy/v5 v5.5.0 @@ -50,34 +50,34 @@ require ( github.com/go-sql-driver/mysql v1.7.1 github.com/go-swagger/go-swagger v0.30.5 github.com/go-testfixtures/testfixtures/v3 v3.9.0 - github.com/go-webauthn/webauthn v0.8.6 + github.com/go-webauthn/webauthn v0.9.4 github.com/gobwas/glob v0.2.3 github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 - github.com/golang-jwt/jwt/v5 v5.0.0 + github.com/golang-jwt/jwt/v5 v5.2.0 github.com/google/go-github/v57 v57.0.0 - github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 - github.com/google/uuid v1.3.1 - github.com/gorilla/feeds v1.1.1 - github.com/gorilla/sessions v1.2.1 + github.com/google/pprof v0.0.0-20231212022811-ec68065c825e + github.com/google/uuid v1.5.0 + github.com/gorilla/feeds v1.1.2 + github.com/gorilla/sessions v1.2.2 github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/huandu/xstrings v1.4.0 github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 - github.com/jhillyerd/enmime v1.0.1 + github.com/jhillyerd/enmime v1.1.0 github.com/json-iterator/go v1.1.12 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 - github.com/klauspost/compress v1.17.0 - github.com/klauspost/cpuid/v2 v2.2.5 + github.com/klauspost/compress v1.17.4 + github.com/klauspost/cpuid/v2 v2.2.6 github.com/lib/pq v1.10.9 github.com/markbates/goth v1.78.0 - github.com/mattn/go-isatty v0.0.19 - github.com/mattn/go-sqlite3 v1.14.17 - github.com/meilisearch/meilisearch-go v0.25.1 + github.com/mattn/go-isatty v0.0.20 + github.com/mattn/go-sqlite3 v1.14.19 + github.com/meilisearch/meilisearch-go v0.26.0 github.com/mholt/archiver/v3 v3.5.1 github.com/microcosm-cc/bluemonday v1.0.26 - github.com/minio/minio-go/v7 v7.0.63 + github.com/minio/minio-go/v7 v7.0.66 github.com/minio/sha256-simd v1.0.1 github.com/msteinert/pam v1.2.0 github.com/nektos/act v0.2.52 @@ -89,7 +89,7 @@ require ( github.com/pquerna/otp v1.4.0 github.com/prometheus/client_golang v1.17.0 github.com/quasoft/websspi v1.1.2 - github.com/redis/go-redis/v9 v9.2.1 + github.com/redis/go-redis/v9 v9.3.0 github.com/robfig/cron/v3 v3.0.1 github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 github.com/sassoftware/go-rpmutils v0.2.0 @@ -100,20 +100,20 @@ require ( github.com/tstranex/u2f v1.0.0 github.com/ulikunitz/xz v0.5.11 github.com/urfave/cli/v2 v2.26.0 - github.com/xanzy/go-gitlab v0.93.1 + github.com/xanzy/go-gitlab v0.95.2 github.com/xeipuuv/gojsonschema v1.2.0 github.com/yohcop/openid-go v1.0.1 - github.com/yuin/goldmark v1.5.6 + github.com/yuin/goldmark v1.6.0 github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc github.com/yuin/goldmark-meta v1.1.0 - golang.org/x/crypto v0.14.0 - golang.org/x/image v0.13.0 - golang.org/x/net v0.17.0 - golang.org/x/oauth2 v0.13.0 - golang.org/x/sys v0.13.0 - golang.org/x/text v0.13.0 - golang.org/x/tools v0.14.0 - google.golang.org/grpc v1.58.3 + golang.org/x/crypto v0.17.0 + golang.org/x/image v0.14.0 + golang.org/x/net v0.19.0 + golang.org/x/oauth2 v0.15.0 + golang.org/x/sys v0.15.0 + golang.org/x/text v0.14.0 + golang.org/x/tools v0.16.1 + google.golang.org/grpc v1.60.0 google.golang.org/protobuf v1.31.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/ini.v1 v1.67.0 @@ -125,33 +125,33 @@ require ( ) require ( - cloud.google.com/go/compute v1.23.1 // indirect + cloud.google.com/go/compute v1.23.3 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect dario.cat/mergo v1.0.0 // indirect git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect - github.com/ClickHouse/ch-go v0.58.2 // indirect - github.com/ClickHouse/clickhouse-go/v2 v2.14.3 // indirect + github.com/ClickHouse/ch-go v0.61.0 // indirect + github.com/ClickHouse/clickhouse-go/v2 v2.16.0 // indirect github.com/DataDog/zstd v1.5.5 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect - github.com/RoaringBitmap/roaring v1.6.0 // indirect + github.com/RoaringBitmap/roaring v1.7.0 // indirect github.com/acomagu/bufpipe v1.0.4 // indirect - github.com/andybalholm/brotli v1.0.5 // indirect + github.com/andybalholm/brotli v1.0.6 // indirect github.com/andybalholm/cascadia v1.3.2 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.9.0 // indirect - github.com/blevesearch/bleve_index_api v1.0.6 // indirect + github.com/bits-and-blooms/bitset v1.12.0 // indirect + github.com/blevesearch/bleve_index_api v1.1.4 // indirect github.com/blevesearch/geo v0.1.18 // indirect github.com/blevesearch/go-porterstemmer v1.0.3 // indirect github.com/blevesearch/gtreap v0.1.1 // indirect github.com/blevesearch/mmap-go v1.0.4 // indirect - github.com/blevesearch/scorch_segment_api/v2 v2.1.6 // indirect + github.com/blevesearch/scorch_segment_api/v2 v2.2.5 // indirect github.com/blevesearch/segment v0.9.1 // indirect github.com/blevesearch/snowballstem v0.9.0 // indirect github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect @@ -165,9 +165,9 @@ require ( github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/cloudflare/circl v1.3.3 // indirect + github.com/cloudflare/circl v1.3.6 // indirect github.com/couchbase/go-couchbase v0.1.1 // indirect - github.com/couchbase/gomemcached v0.2.1 // indirect + github.com/couchbase/gomemcached v0.3.0 // indirect github.com/couchbase/goutils v0.1.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect @@ -175,28 +175,28 @@ require ( github.com/davidmz/go-pageant v1.0.2 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/dlclark/regexp2 v1.10.0 // indirect - github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead // indirect - github.com/fatih/color v1.15.0 // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fxamacker/cbor/v2 v2.5.0 // indirect github.com/go-ap/errors v0.0.0-20231003111023-183eef4b31b7 // indirect github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect github.com/go-enry/go-oniguruma v1.2.1 // indirect github.com/go-faster/city v1.0.1 // indirect - github.com/go-faster/errors v0.6.1 // indirect + github.com/go-faster/errors v0.7.1 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-openapi/analysis v0.21.4 // indirect - github.com/go-openapi/errors v0.20.4 // indirect + github.com/go-openapi/analysis v0.21.5 // indirect + github.com/go-openapi/errors v0.21.0 // indirect github.com/go-openapi/inflect v0.19.0 // indirect - github.com/go-openapi/jsonpointer v0.20.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/loads v0.21.2 // indirect - github.com/go-openapi/runtime v0.26.0 // indirect - github.com/go-openapi/spec v0.20.9 // indirect - github.com/go-openapi/strfmt v0.21.7 // indirect - github.com/go-openapi/swag v0.22.4 // indirect - github.com/go-openapi/validate v0.22.1 // indirect - github.com/go-webauthn/x v0.1.4 // indirect + github.com/go-openapi/jsonpointer v0.20.1 // indirect + github.com/go-openapi/jsonreference v0.20.3 // indirect + github.com/go-openapi/loads v0.21.3 // indirect + github.com/go-openapi/runtime v0.26.2 // indirect + github.com/go-openapi/spec v0.20.12 // indirect + github.com/go-openapi/strfmt v0.21.10 // indirect + github.com/go-openapi/swag v0.22.5 // indirect + github.com/go-openapi/validate v0.22.4 // indirect + github.com/go-webauthn/x v0.1.5 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect @@ -207,12 +207,12 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/go-tpm v0.9.0 // indirect - github.com/gorilla/css v1.0.0 // indirect - github.com/gorilla/handlers v1.5.1 // indirect - github.com/gorilla/mux v1.8.0 // indirect - github.com/gorilla/securecookie v1.1.1 // indirect + github.com/gorilla/css v1.0.1 // indirect + github.com/gorilla/handlers v1.5.2 // indirect + github.com/gorilla/mux v1.8.1 // indirect + github.com/gorilla/securecookie v1.1.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-retryablehttp v0.7.4 // indirect + github.com/hashicorp/go-retryablehttp v0.7.5 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect @@ -228,9 +228,9 @@ require ( github.com/markbates/going v1.0.3 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mholt/acmez v1.2.0 // indirect - github.com/miekg/dns v1.1.56 // indirect + github.com/miekg/dns v1.1.57 // indirect github.com/minio/md5-simd v1.1.2 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -244,19 +244,19 @@ require ( github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/onsi/ginkgo v1.16.5 // indirect github.com/paulmach/orb v0.10.0 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect - github.com/pierrec/lz4/v4 v4.1.18 // indirect + github.com/pelletier/go-toml/v2 v2.1.1 // indirect + github.com/pierrec/lz4/v4 v4.1.19 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/rhysd/actionlint v1.6.26 // indirect github.com/rivo/uniseg v0.4.4 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/xid v1.5.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/sagikazarmark/locafero v0.3.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/shopspring/decimal v1.3.1 // indirect @@ -264,37 +264,37 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/skeema/knownhosts v1.2.1 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.10.0 // indirect - github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.17.0 // indirect + github.com/spf13/viper v1.18.2 // indirect github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/toqueteos/webbrowser v1.2.0 // indirect github.com/unknwon/com v1.0.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasthttp v1.50.0 // indirect + github.com/valyala/fasthttp v1.51.0 // indirect github.com/valyala/fastjson v1.6.4 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect github.com/zeebo/blake3 v0.2.3 // indirect - go.etcd.io/bbolt v1.3.7 // indirect - go.mongodb.org/mongo-driver v1.12.1 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.etcd.io/bbolt v1.3.8 // indirect + go.mongodb.org/mongo-driver v1.13.1 // indirect + go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/sync v0.4.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/sync v0.5.0 // indirect + golang.org/x/time v0.5.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index f3c20981b477a..348fc86da4142 100644 --- a/go.sum +++ b/go.sum @@ -3,7 +3,6 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -15,17 +14,14 @@ cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZ cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.67.0/go.mod h1:YNan/mUhNZFrYUor0vqrsQ0Ffl7Xtm/ACOy/vsTS858= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.23.1 h1:V97tBoDaZHb6leicZ1G6DLK2BAaZLJ/7+9BB/En3hR0= -cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78= +cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= +cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= @@ -39,13 +35,12 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= code.gitea.io/actions-proto-go v0.3.1 h1:PMyiQtBKb8dNnpEO2R5rcZdXSis+UQZVo/SciMtR1aU= code.gitea.io/actions-proto-go v0.3.1/go.mod h1:00ys5QDo1iHN1tHNvvddAcy2W/g+425hQya1cCSvq9A= code.gitea.io/gitea-vet v0.2.3 h1:gdFmm6WOTM65rE8FUBTRzeQZYzXePKSSB1+r574hWwI= code.gitea.io/gitea-vet v0.2.3/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= -code.gitea.io/sdk/gitea v0.16.0 h1:gAfssETO1Hv9QbE+/nhWu7EjoFQYKt6kPoyDytQgw00= -code.gitea.io/sdk/gitea v0.16.0/go.mod h1:ndkDk99BnfiUCCYEUhpNzi0lpmApXlwRFqClBlOlEBg= +code.gitea.io/sdk/gitea v0.17.0 h1:8JPBss4+Jf7AE1YcfyiGrngTXE8dFSG3si/bypsTH34= +code.gitea.io/sdk/gitea v0.17.0/go.mod h1:ndkDk99BnfiUCCYEUhpNzi0lpmApXlwRFqClBlOlEBg= codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 h1:TXbikPqa7YRtfU9vS6QJBg77pUvbEb6StRdZO8t1bEY= codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570/go.mod h1:IIAjsijsd8q1isWX8MACefDEgTQslQ4stk2AeeTt3kM= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= @@ -82,10 +77,10 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/ClickHouse/ch-go v0.58.2 h1:jSm2szHbT9MCAB1rJ3WuCJqmGLi5UTjlNu+f530UTS0= -github.com/ClickHouse/ch-go v0.58.2/go.mod h1:Ap/0bEmiLa14gYjCiRkYGbXvbe8vwdrfTYWhsuQ99aw= -github.com/ClickHouse/clickhouse-go/v2 v2.14.3 h1:s9SuU3PfJrfJ4SDbVRo6XM2ZWlr7efvW9Z/ppUpE1vo= -github.com/ClickHouse/clickhouse-go/v2 v2.14.3/go.mod h1:qdw8IMGH4Y+PedKlf9QEhFO1ATTSFhh4exQRVIa3y2A= +github.com/ClickHouse/ch-go v0.61.0 h1:22JYeFJoFNAU/Vod4etAeUEY28cYt7Ixnwqj1+EUfro= +github.com/ClickHouse/ch-go v0.61.0/go.mod h1:POJBl0MxEMS91Zd0uTgDDt05KfXEjf5KIwW6lNhje9Y= +github.com/ClickHouse/clickhouse-go/v2 v2.16.0 h1:rhMfnPewXPnY4Q4lQRGdYuTLRBRKJEIEYHtbUMrzmvI= +github.com/ClickHouse/clickhouse-go/v2 v2.16.0/go.mod h1:J7SPfIxwR+x4mQ+o8MLSe0oY50NNntEqCIjFe/T1VPM= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= @@ -107,19 +102,17 @@ github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c h1:kMFnB0vCcX github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo= github.com/RoaringBitmap/roaring v0.7.1/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I= -github.com/RoaringBitmap/roaring v1.6.0 h1:dc7kRiroETgJcHhWX6BerXkZz2b3JgLGg9nTURJL/og= -github.com/RoaringBitmap/roaring v1.6.0/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE= +github.com/RoaringBitmap/roaring v1.7.0 h1:OZF303tJCER1Tj3x+aArx/S5X7hrT186ri6JjrGvG68= +github.com/RoaringBitmap/roaring v1.7.0/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90= github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/alecthomas/assert/v2 v2.2.1 h1:XivOgYcduV98QCahG8T5XTezV5bylXe+lBxLG2K2ink= github.com/alecthomas/assert/v2 v2.2.1/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs= -github.com/alecthomas/chroma/v2 v2.10.0 h1:T2iQOCCt4pRmRMfL55gTodMtc7cU0y7lc1Jb8/mK/64= -github.com/alecthomas/chroma/v2 v2.10.0/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurGF0EpseFXdKMBw= +github.com/alecthomas/chroma/v2 v2.12.0 h1:Wh8qLEgMMsN7mgyG8/qIpegky2Hvzr4By6gEF7cmWgw= +github.com/alecthomas/chroma/v2 v2.12.0/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurGF0EpseFXdKMBw= github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= @@ -127,8 +120,8 @@ github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3Uu github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= -github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= +github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss= github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= @@ -137,7 +130,6 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuW github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= @@ -146,16 +138,16 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.1.10/go.mod h1:w0XsmFg8qg6cmpTtJ0z3pKgjTDBMMnI/+I2syrE6XBE= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bits-and-blooms/bitset v1.9.0 h1:g1YivPG8jOtrN013Fe8OBXubkiTwvm7/vG2vXz03ANU= -github.com/bits-and-blooms/bitset v1.9.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.12.0 h1:U/q1fAF7xXRhFCrhROzIfffYnu+dlS38vCZtmFVPHmA= +github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM= github.com/blevesearch/bleve/v2 v2.3.10 h1:z8V0wwGoL4rp7nG/O3qVVLYxUqCbEwskMt4iRJsPLgg= github.com/blevesearch/bleve/v2 v2.3.10/go.mod h1:RJzeoeHC+vNHsoLR54+crS1HmOWpnH87fL70HAUCzIA= github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4= -github.com/blevesearch/bleve_index_api v1.0.6 h1:gyUUxdsrvmW3jVhhYdCVL6h9dCjNT/geNU7PxGn37p8= -github.com/blevesearch/bleve_index_api v1.0.6/go.mod h1:YXMDwaXFFXwncRS8UobWs7nvo0DmusriM1nztTlj1ms= +github.com/blevesearch/bleve_index_api v1.1.4 h1:n9Ilxlb80g9DAhchR95IcVrzohamDSri0wPnkKnva50= +github.com/blevesearch/bleve_index_api v1.1.4/go.mod h1:PbcwjIcRmjhGbkS/lJCpfgVSMROV6TRubGGAODaK1W8= github.com/blevesearch/geo v0.1.18 h1:Np8jycHTZ5scFe7VEPLrDoHnnb9C4j636ue/CGrhtDw= github.com/blevesearch/geo v0.1.18/go.mod h1:uRMGWG0HJYfWfFJpK3zTdnnr1K+ksZTuWKhXeSokfnM= github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo= @@ -166,8 +158,8 @@ github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+ github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc= github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs= github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU= -github.com/blevesearch/scorch_segment_api/v2 v2.1.6 h1:CdekX/Ob6YCYmeHzD72cKpwzBjvkOGegHOqhAkXp6yA= -github.com/blevesearch/scorch_segment_api/v2 v2.1.6/go.mod h1:nQQYlp51XvoSVxcciBjtvuHPIVjlWrN1hX4qwK2cqdc= +github.com/blevesearch/scorch_segment_api/v2 v2.2.5 h1:5SsNQmR8v1bojtGQ1zFhZravcMg5rdiX8AVu6LwlVtc= +github.com/blevesearch/scorch_segment_api/v2 v2.2.5/go.mod h1:8N2ytOlBCdurlxDgbqsfeR1oTKRN0ZVIKdUUP1VFZNc= github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ= github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU= github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw= @@ -207,11 +199,11 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/bufbuild/connect-go v1.10.0 h1:QAJ3G9A1OYQW2Jbk3DeoJbkCxuKArrvZgDt47mjdTbg= github.com/bufbuild/connect-go v1.10.0/go.mod h1:CAIePUgkDR5pAFaylSMtNK45ANQjp9JvpluG20rhpV8= -github.com/buildkite/terminal-to-html/v3 v3.9.1 h1:8SOCKFK9ntpYvPE3yUAXHiZYdQI4xf9o9S3wOX7x12A= -github.com/buildkite/terminal-to-html/v3 v3.9.1/go.mod h1:Nsx19oOIo6MZM/cEPookXi/nrQQmnSJFLZL1KS05t+A= +github.com/buildkite/terminal-to-html/v3 v3.10.0 h1:mW1PSgDdUvmQMHOfXEOJDPGfqGWaskJfnGzdaQuJvsE= +github.com/buildkite/terminal-to-html/v3 v3.10.0/go.mod h1:qtuRyYs6/Sw3FS9jUyVEaANHgHGqZsGqMknPLyau5cQ= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/caddyserver/certmagic v0.19.2 h1:HZd1AKLx4592MalEGQS39DKs2ZOAJCEM/xYPMQ2/ui0= -github.com/caddyserver/certmagic v0.19.2/go.mod h1:fsL01NomQ6N+kE2j37ZCnig2MFosG+MIO4ztnmG/zz8= +github.com/caddyserver/certmagic v0.20.0 h1:bTw7LcEZAh9ucYCRXyCpIrSAGplplI0vGYJ4BpCQ/Fc= +github.com/caddyserver/certmagic v0.20.0/go.mod h1:N4sXgpICQUskEWpj7zVzvWD41p3NYacrNoZYiRM2jTg= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI= github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8= @@ -227,11 +219,10 @@ github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86c github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.6 h1:/xbKIqSHbZXHwkhbrhrt2YOHIwYJlXH94E3tI/gDlUg= +github.com/cloudflare/circl v1.3.6/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -243,8 +234,8 @@ github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89/go.mod h1:+ github.com/couchbase/go-couchbase v0.1.1 h1:ClFXELcKj/ojyoTYbsY34QUrrYCBi/1G749sXSCkdhk= github.com/couchbase/go-couchbase v0.1.1/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A= github.com/couchbase/gomemcached v0.1.1/go.mod h1:mxliKQxOv84gQ0bJWbI+w9Wxdpt9HjDvgW9MjCym5Vo= -github.com/couchbase/gomemcached v0.2.1 h1:lDONROGbklo8pOt4Sr4eV436PVEaKDr3o9gUlhv9I2U= -github.com/couchbase/gomemcached v0.2.1/go.mod h1:mxliKQxOv84gQ0bJWbI+w9Wxdpt9HjDvgW9MjCym5Vo= +github.com/couchbase/gomemcached v0.3.0 h1:XkMDdP6w7rtvLijDE0/RhcccX+XvAk5cboyBv1YcI0U= +github.com/couchbase/gomemcached v0.3.0/go.mod h1:mxliKQxOv84gQ0bJWbI+w9Wxdpt9HjDvgW9MjCym5Vo= github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= github.com/couchbase/goutils v0.1.2 h1:gWr8B6XNWPIhfalHNog3qQKfGiYyh4K4VhO3P2o9BCs= github.com/couchbase/goutils v0.1.2/go.mod h1:h89Ek/tiOxxqjz30nPPlwZdQbdB8BwgnuBxeoUe/ViE= @@ -299,42 +290,39 @@ github.com/emersion/go-imap v1.2.1 h1:+s9ZjMEjOB8NzZMVTM3cCenz2JrQIGGo5j1df19WjT github.com/emersion/go-imap v1.2.1/go.mod h1:Qlx1FSx2FTxjnjWpIlVNEuX+ylerZQNFE5NsmKFSejY= github.com/emersion/go-message v0.15.0/go.mod h1:wQUEfE+38+7EW8p8aZ96ptg6bAb1iwdgej19uXASlE4= github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= -github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead h1:fI1Jck0vUrXT8bnphprS1EoVRe2Q5CKCX8iDlpqjQ/Y= -github.com/emersion/go-sasl v0.0.0-20220912192320-0145f2c60ead/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= +github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 h1:hH4PQfOndHDlpzYfLAAfl63E8Le6F2+EL/cdhlkyRJY= +github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= github.com/emersion/go-textwrapper v0.0.0-20200911093747-65d896831594/go.mod h1:aqO8z8wPrjkscevZJFVE1wXJrLpC5LtJG7fqLOsPb2U= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ethantkoenig/rupture v1.0.1 h1:6aAXghmvtnngMgQzy7SMGdicMvkV86V4n9fT0meE5E4= github.com/ethantkoenig/rupture v1.0.1/go.mod h1:Sjqo/nbffZp1pVVXNGhpugIjsWmuS9KiIB4GtpEBur4= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE= github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/gliderlabs/ssh v0.3.6-0.20230927171611-ece6c7995e46 h1:fYiA820jw7wmAvdXrHwMItxjJkra7dT9y8yiXhtzb94= github.com/gliderlabs/ssh v0.3.6-0.20230927171611-ece6c7995e46/go.mod h1:i/TCLcdiX9Up/vs+Rp8c3yMbqp2Y4Y7Nh9uzGFCa5pM= github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= -github.com/go-ap/activitypub v0.0.0-20231003111253-1fba3772399b h1:VLD6IPBDkqEsOZ+EfLO6MayuHycZ0cv4BStTlRoZduo= -github.com/go-ap/activitypub v0.0.0-20231003111253-1fba3772399b/go.mod h1:cJ9Ye0ZNSMN7RzZDBRY3E+8M3Bpf/R1JX22Ir9yX6WI= +github.com/go-ap/activitypub v0.0.0-20231114162308-e219254dc5c9 h1:j2TrkUG/NATGi/EQS+MvEoF79CxiRUmT16ErFroNcKI= +github.com/go-ap/activitypub v0.0.0-20231114162308-e219254dc5c9/go.mod h1:cJ9Ye0ZNSMN7RzZDBRY3E+8M3Bpf/R1JX22Ir9yX6WI= github.com/go-ap/errors v0.0.0-20231003111023-183eef4b31b7 h1:I2nuhyVI/48VXoRCCZR2hYBgnSXa+EuDJf/VyX06TC0= github.com/go-ap/errors v0.0.0-20231003111023-183eef4b31b7/go.mod h1:5x8a6P/dhmMGFxWLcyYlyOuJ2lRNaHGhRv+yu8BaTSI= github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73 h1:GMKIYXyXPGIp+hYiWOhfqK4A023HdgisDT4YGgf99mw= @@ -347,16 +335,16 @@ github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= -github.com/go-co-op/gocron v1.31.1 h1:LZAuBlU0t3SPGUMJGhrJ6VuCc3CsrYzkzicygvVWlfA= -github.com/go-co-op/gocron v1.31.1/go.mod h1:39f6KNSGVOU1LO/ZOoZfcSxwlsJDQOKSu8erN0SH48Y= +github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0= +github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY= github.com/go-enry/go-enry/v2 v2.8.6 h1:T6ljs5+qNiUTDqpfK5GUD5EvLNdDbf804u8iC30vw7U= github.com/go-enry/go-enry/v2 v2.8.6/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8= github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo= github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4= github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= -github.com/go-faster/errors v0.6.1 h1:nNIPOBkprlKzkThvS/0YaX8Zs9KewLCOSFQS5BU06FI= -github.com/go-faster/errors v0.6.1/go.mod h1:5MGV2/2T9yvlrbhe9pD9LO5Z/2zCSq2T8j+Jpi2LAyY= +github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg= +github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo= github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e h1:oRq/fiirun5HqlEWMLIcDmLpIELlG4iGbd0s8iqgPi8= github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= @@ -375,47 +363,28 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-ldap/ldap/v3 v3.4.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A= github.com/go-ldap/ldap/v3 v3.4.6/go.mod h1:IGMQANNtxpsOzj7uUAMjpGBaOVTC4DYyIy8VsTdxmtc= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= -github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= -github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= -github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M= -github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= +github.com/go-openapi/analysis v0.21.5 h1:3tHfEBh6Ia8eKc4M7khOGjPOAlWKJ10d877Cr9teujI= +github.com/go-openapi/analysis v0.21.5/go.mod h1:25YcZosX9Lwz2wBsrFrrsL8bmjjXdlyP6zsr2AMy29M= +github.com/go-openapi/errors v0.21.0 h1:FhChC/duCnfoLj1gZ0BgaBmzhJC2SL/sJr8a2vAobSY= +github.com/go-openapi/errors v0.21.0/go.mod h1:jxNTMUxRCKj65yb/okJGEtahVd7uvWnuWfj53bse4ho= github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= -github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= -github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= -github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= -github.com/go-openapi/runtime v0.26.0 h1:HYOFtG00FM1UvqrcxbEJg/SwvDRvYLQKGhw2zaQjTcc= -github.com/go-openapi/runtime v0.26.0/go.mod h1:QgRGeZwrUcSHdeh4Ka9Glvo0ug1LC5WyE+EV88plZrQ= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8= -github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= -github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k= -github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= -github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-openapi/jsonpointer v0.20.1 h1:MkK4VEIEZMj4wT9PmjaUmGflVBr9nvud4Q4UVFbDoBE= +github.com/go-openapi/jsonpointer v0.20.1/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= +github.com/go-openapi/jsonreference v0.20.3 h1:EjGcjTW8pD1mRis6+w/gmoBdqv5+RbE9B85D1NgDOVQ= +github.com/go-openapi/jsonreference v0.20.3/go.mod h1:FviDZ46i9ivh810gqzFLl5NttD5q3tSlMLqLr6okedM= +github.com/go-openapi/loads v0.21.3 h1:8sSH2FIm/SnbDUGv572md4YqVMFne/a9Eubvcd3anew= +github.com/go-openapi/loads v0.21.3/go.mod h1:Y3aMR24iHbKHppOj91nQ/SHc0cuPbAr4ndY4a02xydc= +github.com/go-openapi/runtime v0.26.2 h1:elWyB9MacRzvIVgAZCBJmqTi7hBzU0hlKD4IvfX0Zl0= +github.com/go-openapi/runtime v0.26.2/go.mod h1:O034jyRZ557uJKzngbMDJXkcKJVzXJiymdSfgejrcRw= +github.com/go-openapi/spec v0.20.12 h1:cgSLbrsmziAP2iais+Vz7kSazwZ8rsUZd6TUzdDgkVI= +github.com/go-openapi/spec v0.20.12/go.mod h1:iSCgnBcwbMW9SfzJb8iYynXvcY6C/QFrI7otzF7xGM4= +github.com/go-openapi/strfmt v0.21.10 h1:JIsly3KXZB/Qf4UzvzJpg4OELH/0ASDQsyk//TTBDDk= +github.com/go-openapi/strfmt v0.21.10/go.mod h1:vNDMwbilnl7xKiO/Ve/8H8Bb2JIInBnH+lqiw6QWgis= +github.com/go-openapi/swag v0.22.5 h1:fVS63IE3M0lsuWRzuom3RLwUMVI2peDH01s6M70ugys= +github.com/go-openapi/swag v0.22.5/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0= +github.com/go-openapi/validate v0.22.4 h1:5v3jmMyIPKTR8Lv9syBAIRxG6lY0RqeBPB1LKEijzk8= +github.com/go-openapi/validate v0.22.4/go.mod h1:qm6O8ZIcPVdSY5219468Jv7kBdGvkiZLPOmqnqTUZ2A= github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -432,34 +401,10 @@ github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-testfixtures/testfixtures/v3 v3.9.0 h1:938g5V+GWLVejm3Hc+nWCuEXRlcglZDDlN/t1gWzcSY= github.com/go-testfixtures/testfixtures/v3 v3.9.0/go.mod h1:cdsKD2ApFBjdog9jRsz6EJqF+LClq/hrwE9K/1Dzo4s= -github.com/go-webauthn/webauthn v0.8.6 h1:bKMtL1qzd2WTFkf1mFTVbreYrwn7dsYmEPjTq6QN90E= -github.com/go-webauthn/webauthn v0.8.6/go.mod h1:emwVLMCI5yx9evTTvr0r+aOZCdWJqMfbRhF0MufyUog= -github.com/go-webauthn/x v0.1.4 h1:sGmIFhcY70l6k7JIDfnjVBiAAFEssga5lXIUXe0GtAs= -github.com/go-webauthn/x v0.1.4/go.mod h1:75Ug0oK6KYpANh5hDOanfDI+dvPWHk788naJVG/37H8= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/go-webauthn/webauthn v0.9.4 h1:YxvHSqgUyc5AK2pZbqkWWR55qKeDPhP8zLDr6lpIc2g= +github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAhr9xlRbdbgnTw= +github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= +github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= @@ -475,8 +420,8 @@ github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85/go.mod h1:fR6z github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= -github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw= +github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= @@ -510,7 +455,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= @@ -531,7 +475,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -543,9 +486,10 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17 github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -554,52 +498,50 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= -github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 h1:pUa4ghanp6q4IJHwE9RwLgmVFfReJN+KbQ8ExNEUUoQ= -github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20231212022811-ec68065c825e h1:bwOy7hAFd0C91URzMIEBfr6BAz29yk7Qj0cy6S7DJlU= +github.com/google/pprof v0.0.0-20231212022811-ec68065c825e/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 h1:twflg0XRTjwKpxb/jFExr4HGq6on2dEOmnL6FV+fgPw= github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= -github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= -github.com/gorilla/feeds v1.1.1 h1:HwKXxqzcRNg9to+BbvJog4+f3s/xzvtZXICcQGutYfY= -github.com/gorilla/feeds v1.1.1/go.mod h1:Nk0jZrvPFZX1OBe5NPiddPw7CfwF6Q9eqzaBbaightA= -github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8= +github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0= +github.com/gorilla/feeds v1.1.2 h1:pxzZ5PD3RJdhFH2FsJJ4x6PqMqbgFk1+Vez4XWBW8Iw= +github.com/gorilla/feeds v1.1.2/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= +github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1 h1:LqbZZ9sNMWVjeXS4NN5oVvhMjDyLhmA1LG86oSo+IqY= github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY= -github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= +github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/sessions v1.1.1/go.mod h1:8KCfur6+4Mqcc6S0FEfKuN15Vl5MgXW92AE8ovaJD0w= github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= -github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY= +github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= -github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= +github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= @@ -613,7 +555,6 @@ github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= @@ -677,9 +618,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/jhillyerd/enmime v1.0.1 h1:y6RyqIgBOI2hIinOXIzmeB+ITRVls0zTJIm5GwgXnjE= -github.com/jhillyerd/enmime v1.0.1/go.mod h1:LMMbm6oTlzWHghPavqHtOrP/NosVv3l42CUrZjn03/Q= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jhillyerd/enmime v1.1.0 h1:ubaIzg68VY7CMCe2YbHe6nkRvU9vujixTkNz3EBvZOw= +github.com/jhillyerd/enmime v1.1.0/go.mod h1:FRFuUPCLh8PByQv+8xRcLO9QHqaqTqreYhopv5eyk4I= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -691,8 +631,6 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= @@ -707,20 +645,19 @@ github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= -github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= +github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc= +github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= @@ -753,9 +690,6 @@ github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0/go.mod h1:JEfTc3+2DF9 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA= @@ -763,8 +697,6 @@ github.com/markbates/going v1.0.3 h1:mY45T5TvW+Xz5A6jY7lf4+NLg9D8+iuStIHyR7M8qsE github.com/markbates/going v1.0.3/go.mod h1:fQiT6v6yQar9UD6bd/D4Z5Afbk9J6BBVBtLiyY4gp2o= github.com/markbates/goth v1.78.0 h1:7VEIFDycJp9deyVv3YraGBPdD0ZYQW93Y3Aw1eVP3BY= github.com/markbates/goth v1.78.0/go.mod h1:X6xdNgpapSENS0O35iTBBcMHoJDQDfI9bJl+APCkYMc= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= @@ -775,32 +707,32 @@ github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= -github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/meilisearch/meilisearch-go v0.25.1 h1:D5wY22sn5kkpRH3uYMGlwltdUEq5regIFmO7awHz3Vo= -github.com/meilisearch/meilisearch-go v0.25.1/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0= +github.com/mattn/go-sqlite3 v1.14.19 h1:fhGleo2h1p8tVChob4I9HpmVFIAkKGpiukdrgQbWfGI= +github.com/mattn/go-sqlite3 v1.14.19/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/meilisearch/meilisearch-go v0.26.0 h1:6IdFC9S53gEp7FMkt99swIFyEZE+4TwJAgen3eQdw40= +github.com/meilisearch/meilisearch-go v0.26.0/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0= github.com/mholt/acmez v1.2.0 h1:1hhLxSgY5FvH5HCnGUuwbKY2VQVo8IU7rxXKSnZ7F30= github.com/mholt/acmez v1.2.0/go.mod h1:VT9YwH1xgNX1kmYY89gY8xPJC84BFAisjo8Egigt4kE= github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58= github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs= -github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= -github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= +github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= +github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.63 h1:GbZ2oCvaUdgT5640WJOpyDhhDxvknAJU2/T3yurwcbQ= -github.com/minio/minio-go/v7 v7.0.63/go.mod h1:Q6X7Qjb7WMhvG65qKf4gUgA5XaiSox74kR1uAEjxRS4= +github.com/minio/minio-go/v7 v7.0.66 h1:bnTOXOHjOqv/gcMuiVbN9o2ngRItvqE774dG9nq0Dzw= +github.com/minio/minio-go/v7 v7.0.66/go.mod h1:DHAgmyQEGdW3Cif0UooKOyrT3Vxs82zNdV6tkKhRtbs= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= @@ -808,8 +740,6 @@ github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa1 github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= @@ -830,7 +760,6 @@ github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= github.com/msteinert/pam v1.2.0 h1:mYfjlvN2KYs2Pb9G6nb/1f/nPfAttT/Jee5Sq9r3bGE= github.com/msteinert/pam v1.2.0/go.mod h1:d2n0DCUK8rGecChV3JzvmsDjOY4R7AYbsNxAT+ftQl0= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/niklasfasching/go-org v1.7.0 h1:vyMdcMWWTe/XmANk19F4k8XGBYg0GQ/gJGMimOjGMek= github.com/niklasfasching/go-org v1.7.0/go.mod h1:WuVm4d45oePiE0eX25GqTDQIt/qPW1T9DGkRscqLW5o= github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= @@ -867,23 +796,20 @@ github.com/paulmach/orb v0.10.0 h1:guVYVqzxHE/CQ1KpfGO077TR0ATHSNjp4s6XGLn3W9s= github.com/paulmach/orb v0.10.0/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU= github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= +github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= -github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.19 h1:tYLzDnjDXh9qIxSTKHwXwOYmm9d887Y7Y1ZkyXYHAN4= +github.com/pierrec/lz4/v4 v4.1.19/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -894,15 +820,15 @@ github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+L github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/quasoft/websspi v1.1.2 h1:/mA4w0LxWlE3novvsoEL6BBA1WnjJATbjkh1kFrTidw= github.com/quasoft/websspi v1.1.2/go.mod h1:HmVdl939dQ0WIXZhyik+ARdI03M6bQzaSEKcgpFmewk= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/redis/go-redis/v9 v9.2.1 h1:WlYJg71ODF0dVspZZCpYmoF1+U1Jjk9Rwd7pq6QmlCg= -github.com/redis/go-redis/v9 v9.2.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= +github.com/redis/go-redis/v9 v9.3.0 h1:RiVDjmig62jIWp7Kk4XVLs0hzV6pI3PyTnnL0cnn0u0= +github.com/redis/go-redis/v9 v9.3.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rhysd/actionlint v1.6.26 h1:zi7jPZf3Ks14gCXYAAL47uBziyFlX7+Xwilqhexct9g= @@ -913,14 +839,12 @@ github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc github.com/robertkrimen/godocdown v0.0.0-20130622164427-0bfa04905481/go.mod h1:C9WhFzY47SzYBIvzFqSvHIR6ROgDo4TtdTuRaOMjF/s= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -929,8 +853,8 @@ github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThC github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ= -github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= @@ -952,7 +876,6 @@ github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBf github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0tzqLRu6TS7Id0wMo2N5QzJoKedVeovOpHjnykSzY= github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg= github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= -github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -970,21 +893,20 @@ github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:s github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= -github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= -github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM= github.com/stephens2424/writerset v1.0.2/go.mod h1:aS2JhsMn6eA7e82oNmW4rfsgAOp9COBTTl8mzkwADnc= @@ -1029,23 +951,21 @@ github.com/urfave/cli/v2 v2.26.0/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6S github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I= -github.com/valyala/fasthttp v1.50.0 h1:H7fweIlBm0rXLs2q0XbalvJ6r0CUPFWK3/bB4N13e9M= -github.com/valyala/fasthttp v1.50.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA= +github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= +github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ= github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xanzy/go-gitlab v0.93.1 h1:f7J33cw/P9b/8paIOoH0F3H+TFrswvWHs6yUgoTp9LY= -github.com/xanzy/go-gitlab v0.93.1/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw= +github.com/xanzy/go-gitlab v0.95.2 h1:4p0IirHqEp5f0baK/aQqr4TR57IsD+8e4fuyAA1yi88= +github.com/xanzy/go-gitlab v0.95.2/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -1058,8 +978,8 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI= +github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yohcop/openid-go v1.0.1 h1:DPRd3iPO5F6O5zX2e62XpVAbPT6wV51cuucH0z9g3js= github.com/yohcop/openid-go v1.0.1/go.mod h1:b/AvD03P0KHj4yuihb+VtLD6bYYgsy0zqBzPCRjkCNs= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= @@ -1069,8 +989,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.5.6 h1:COmQAWTCcGetChm3Ig7G/t8AFAN00t+o8Mt4cf7JpwA= -github.com/yuin/goldmark v1.5.6/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68= +github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ= github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I= github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= @@ -1084,25 +1004,21 @@ github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= -go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= +go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= +go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= -go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE= -go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= +go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk= +go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw= -go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= -go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= -go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= -go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1124,21 +1040,17 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -1146,15 +1058,14 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1165,12 +1076,12 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611 h1:qCEDpW1G+vcj3Y7Fy52pEM1AWm3abj8WimGYejI3SC4= +golang.org/x/exp v0.0.0-20231214170342-aacd6d4b4611/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg= -golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk= +golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= +golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1181,7 +1092,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -1190,12 +1100,10 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1228,11 +1136,7 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1244,35 +1148,30 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= -golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1283,11 +1182,9 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1319,16 +1216,10 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1338,7 +1229,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1346,8 +1236,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1357,15 +1247,14 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= @@ -1373,13 +1262,14 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -1387,14 +1277,10 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -1436,19 +1322,13 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200928182047-19e03678916f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1472,9 +1352,6 @@ google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1515,14 +1392,8 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200929141702-51c3e5b607fe/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a h1:a2MQQVoTo96JC9PMGtGBymLp7+/RzpFc2yX/9WfFg1c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 h1:/jFB8jK5R3Sq3i/lmeZO0cATSzFfZaJq1J2Euan3XKU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1537,11 +1408,8 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.60.0 h1:6FQAR0kM31P6MRdeluor2w2gPaS4SVNrD/DNTxrQ15k= +google.golang.org/grpc v1.60.0/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1562,7 +1430,6 @@ gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -1586,8 +1453,6 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/modules/git/repo_commitgraph_gogit.go b/modules/git/repo_commitgraph_gogit.go index 8e92c30e54705..c2d741daae259 100644 --- a/modules/git/repo_commitgraph_gogit.go +++ b/modules/git/repo_commitgraph_gogit.go @@ -22,7 +22,7 @@ func (r *Repository) CommitNodeIndex() (cgobject.CommitNodeIndex, *os.File) { file, err := os.Open(indexPath) if err == nil { - var index commitgraph.Index + var index commitgraph.Index // TODO: in newer go-git, it might need to use "github.com/go-git/go-git/v5/plumbing/format/commitgraph/v2" package to compile index, err = commitgraph.OpenFileIndex(file) if err == nil { return cgobject.NewGraphCommitNodeIndex(index, r.gogitRepo.Storer), file diff --git a/services/cron/tasks_test.go b/services/cron/tasks_test.go index 69052d739c4ce..979371a022948 100644 --- a/services/cron/tasks_test.go +++ b/services/cron/tasks_test.go @@ -4,6 +4,7 @@ package cron import ( + "sort" "strconv" "testing" @@ -22,9 +23,10 @@ func TestAddTaskToScheduler(t *testing.T) { }, }) assert.NoError(t, err) - assert.Len(t, scheduler.Jobs(), 1) - assert.Equal(t, "task 1", scheduler.Jobs()[0].Tags()[0]) - assert.Equal(t, "5 4 * * *", scheduler.Jobs()[0].Tags()[1]) + jobs := scheduler.Jobs() + assert.Len(t, jobs, 1) + assert.Equal(t, "task 1", jobs[0].Tags()[0]) + assert.Equal(t, "5 4 * * *", jobs[0].Tags()[1]) // with seconds err = addTaskToScheduler(&Task{ @@ -34,9 +36,13 @@ func TestAddTaskToScheduler(t *testing.T) { }, }) assert.NoError(t, err) - assert.Len(t, scheduler.Jobs(), 2) - assert.Equal(t, "task 2", scheduler.Jobs()[1].Tags()[0]) - assert.Equal(t, "30 5 4 * * *", scheduler.Jobs()[1].Tags()[1]) + jobs = scheduler.Jobs() // the item order is not guaranteed, so we need to sort it before "assert" + sort.Slice(jobs, func(i, j int) bool { + return jobs[i].Tags()[0] < jobs[j].Tags()[0] + }) + assert.Len(t, jobs, 2) + assert.Equal(t, "task 2", jobs[1].Tags()[0]) + assert.Equal(t, "30 5 4 * * *", jobs[1].Tags()[1]) } func TestScheduleHasSeconds(t *testing.T) { From 14ffdf617375eda6f9d676271fcb796a5b83186d Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Tue, 19 Dec 2023 10:32:45 +0800 Subject: [PATCH 44/60] chore(api): support ignore password if login source type is LDAP for creating user API (#28491) - Modify the `Password` field in `CreateUserOption` struct to remove the `Required` tag - Update the `v1_json.tmpl` template to include the `email` field and remove the `password` field --------- Signed-off-by: Bo-Yi Wu --- modules/structs/admin_user.go | 5 ++--- routers/api/v1/admin/user.go | 32 +++++++++++++++++++++----------- templates/swagger/v1_json.tmpl | 3 +-- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/modules/structs/admin_user.go b/modules/structs/admin_user.go index 4d679c81d0017..f7c6d10ba0f83 100644 --- a/modules/structs/admin_user.go +++ b/modules/structs/admin_user.go @@ -15,9 +15,8 @@ type CreateUserOption struct { FullName string `json:"full_name" binding:"MaxSize(100)"` // required: true // swagger:strfmt email - Email string `json:"email" binding:"Required;Email;MaxSize(254)"` - // required: true - Password string `json:"password" binding:"Required;MaxSize(255)"` + Email string `json:"email" binding:"Required;Email;MaxSize(254)"` + Password string `json:"password" binding:"MaxSize(255)"` MustChangePassword *bool `json:"must_change_password"` SendNotify bool `json:"send_notify"` Restricted *bool `json:"restricted"` diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index 09d7c1a9403a9..91b5f3a1b0b64 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -93,18 +93,28 @@ func CreateUser(ctx *context.APIContext) { if ctx.Written() { return } - if !password.IsComplexEnough(form.Password) { - err := errors.New("PasswordComplexity") - ctx.Error(http.StatusBadRequest, "PasswordComplexity", err) - return - } - pwned, err := password.IsPwned(ctx, form.Password) - if pwned { - if err != nil { - log.Error(err.Error()) + + if u.LoginType == auth.Plain { + if len(form.Password) < setting.MinPasswordLength { + err := errors.New("PasswordIsRequired") + ctx.Error(http.StatusBadRequest, "PasswordIsRequired", err) + return + } + + if !password.IsComplexEnough(form.Password) { + err := errors.New("PasswordComplexity") + ctx.Error(http.StatusBadRequest, "PasswordComplexity", err) + return + } + + pwned, err := password.IsPwned(ctx, form.Password) + if pwned { + if err != nil { + log.Error(err.Error()) + } + ctx.Error(http.StatusBadRequest, "PasswordPwned", errors.New("PasswordPwned")) + return } - ctx.Error(http.StatusBadRequest, "PasswordPwned", errors.New("PasswordPwned")) - return } overwriteDefault := &user_model.CreateUserOverwriteOptions{ diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index 6cf2beafec6e8..215c1692f61a0 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -18406,8 +18406,7 @@ "type": "object", "required": [ "username", - "email", - "password" + "email" ], "properties": { "created_at": { From 128eac9e0b03ee9c1e45dbd49da8e4726ca569f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20=C3=98vrelid?= <46874830+framitdavid@users.noreply.github.com> Date: Tue, 19 Dec 2023 05:40:05 +0100 Subject: [PATCH 45/60] Fix duplicate ID when deleting repo (#28520) There is an accessibility issue in the interface when attempting to delete a repository. When I click on "Delete repository," a dialog box appears, requiring confirmation to proceed with the repository deletion. However, when I press the "Repo name" label, the wrong input field gains focus. The focused field is located behind the dialog and is intended for renaming the repository. --- templates/repo/migrate/migrating.tmpl | 4 ++-- templates/repo/settings/options.tmpl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/repo/migrate/migrating.tmpl b/templates/repo/migrate/migrating.tmpl index 649d14ad990d3..48411e2da233f 100644 --- a/templates/repo/migrate/migrating.tmpl +++ b/templates/repo/migrate/migrating.tmpl @@ -73,8 +73,8 @@
- - + +
diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index 85ff82fda77a5..5a32f5e7ae1a1 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -921,8 +921,8 @@
- - + +
From 4eb2a29910779ac6005a5d67f31067a1132c5297 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 19 Dec 2023 15:20:47 +0800 Subject: [PATCH 46/60] Improve ObjectFormat interface (#28496) The 4 functions are duplicated, especially as interface methods. I think we just need to keep `MustID` the only one and remove other 3. ``` MustID(b []byte) ObjectID MustIDFromString(s string) ObjectID NewID(b []byte) (ObjectID, error) NewIDFromString(s string) (ObjectID, error) ``` Introduced the new interfrace method `ComputeHash` which will replace the interface `HasherInterface`. Now we don't need to keep two interfaces. Reintroduced `git.NewIDFromString` and `git.MustIDFromString`. The new function will detect the hash length to decide which objectformat of it. If it's 40, then it's SHA1. If it's 64, then it's SHA256. This will be right if the commitID is a full one. So the parameter should be always a full commit id. @AdamMajer Please review. --- cmd/hook.go | 4 +- models/git/branch_test.go | 3 +- models/git/commit_status.go | 2 +- modules/git/commit_info_nogogit.go | 2 +- modules/git/commit_reader.go | 4 +- modules/git/commit_test.go | 4 +- modules/git/last_commit_cache.go | 6 +- modules/git/object_format.go | 37 +++++---- modules/git/object_id.go | 88 ++++++---------------- modules/git/parse_gogit.go | 2 +- modules/git/parse_gogit_test.go | 12 +-- modules/git/parse_nogogit.go | 2 +- modules/git/parse_nogogit_test.go | 12 +-- modules/git/pipeline/lfs_nogogit.go | 6 +- modules/git/repo.go | 2 +- modules/git/repo_blob.go | 2 +- modules/git/repo_blob_test.go | 2 +- modules/git/repo_commit.go | 4 +- modules/git/repo_commit_gogit.go | 4 +- modules/git/repo_commit_nogogit.go | 4 +- modules/git/repo_index.go | 4 +- modules/git/repo_language_stats_nogogit.go | 2 +- modules/git/repo_object.go | 4 +- modules/git/repo_ref_nogogit.go | 2 +- modules/git/repo_tag.go | 10 +-- modules/git/repo_tag_gogit.go | 2 +- modules/git/repo_tag_nogogit.go | 2 +- modules/git/repo_tag_test.go | 12 +-- modules/git/repo_tree.go | 2 +- modules/git/repo_tree_gogit.go | 2 +- modules/git/repo_tree_nogogit.go | 2 +- modules/git/tag.go | 2 +- modules/repository/commits_test.go | 7 +- modules/repository/push.go | 4 +- routers/api/v1/utils/git.go | 2 +- routers/private/hook_verification.go | 4 +- routers/web/repo/setting/lfs.go | 2 +- services/actions/commit_status.go | 2 +- services/pull/patch.go | 8 +- 39 files changed, 109 insertions(+), 168 deletions(-) diff --git a/cmd/hook.go b/cmd/hook.go index 6f31c326fd066..6a3358853ddc9 100644 --- a/cmd/hook.go +++ b/cmd/hook.go @@ -377,7 +377,7 @@ Gitea or set your environment appropriately.`, "") newCommitIDs[count] = string(fields[1]) refFullNames[count] = git.RefName(fields[2]) - commitID, _ := git.IDFromString(newCommitIDs[count]) + commitID, _ := git.NewIDFromString(newCommitIDs[count]) if refFullNames[count] == git.BranchPrefix+"master" && !commitID.IsZero() && count == total { masterPushed = true } @@ -671,7 +671,7 @@ Gitea or set your environment appropriately.`, "") if err != nil { return err } - commitID, _ := git.IDFromString(rs.OldOID) + commitID, _ := git.NewIDFromString(rs.OldOID) if !commitID.IsZero() { err = writeDataPktLine(ctx, os.Stdout, []byte("option old-oid "+rs.OldOID)) if err != nil { diff --git a/models/git/branch_test.go b/models/git/branch_test.go index 8febc80f14747..d480e2ec30c22 100644 --- a/models/git/branch_test.go +++ b/models/git/branch_test.go @@ -30,9 +30,8 @@ func TestAddDeletedBranch(t *testing.T) { secondBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{RepoID: repo.ID, Name: "branch2"}) assert.True(t, secondBranch.IsDeleted) - objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName) commit := &git.Commit{ - ID: objectFormat.MustIDFromString(secondBranch.CommitID), + ID: git.MustIDFromString(secondBranch.CommitID), CommitMessage: secondBranch.CommitMessage, Committer: &git.Signature{ When: secondBranch.CommitTime.AsLocalTime(), diff --git a/models/git/commit_status.go b/models/git/commit_status.go index a22fd2304362a..488e45de26f37 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -114,7 +114,7 @@ WHEN NOT MATCHED // GetNextCommitStatusIndex retried 3 times to generate a resource index func GetNextCommitStatusIndex(ctx context.Context, repoID int64, sha string) (int64, error) { - _, err := git.IDFromString(sha) + _, err := git.NewIDFromString(sha) if err != nil { return 0, git.ErrInvalidSHA{SHA: sha} } diff --git a/modules/git/commit_info_nogogit.go b/modules/git/commit_info_nogogit.go index 8cf8200c3f741..e469d2cab6374 100644 --- a/modules/git/commit_info_nogogit.go +++ b/modules/git/commit_info_nogogit.go @@ -153,7 +153,7 @@ func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string, if typ != "commit" { return nil, fmt.Errorf("unexpected type: %s for commit id: %s", typ, commitID) } - c, err = CommitFromReader(commit.repo, commit.ID.Type().MustIDFromString(commitID), io.LimitReader(batchReader, size)) + c, err = CommitFromReader(commit.repo, MustIDFromString(commitID), io.LimitReader(batchReader, size)) if err != nil { return nil, err } diff --git a/modules/git/commit_reader.go b/modules/git/commit_reader.go index 08a529a13219c..d74bcffed8a69 100644 --- a/modules/git/commit_reader.go +++ b/modules/git/commit_reader.go @@ -71,10 +71,10 @@ readLoop: switch string(split[0]) { case "tree": - commit.Tree = *NewTree(gitRepo, objectID.Type().MustIDFromString(string(data))) + commit.Tree = *NewTree(gitRepo, MustIDFromString(string(data))) _, _ = payloadSB.Write(line) case "parent": - commit.Parents = append(commit.Parents, objectID.Type().MustIDFromString(string(data))) + commit.Parents = append(commit.Parents, MustIDFromString(string(data))) _, _ = payloadSB.Write(line) case "author": commit.Author = &Signature{} diff --git a/modules/git/commit_test.go b/modules/git/commit_test.go index dec67f6628609..e512eecc563be 100644 --- a/modules/git/commit_test.go +++ b/modules/git/commit_test.go @@ -135,8 +135,8 @@ func TestHasPreviousCommit(t *testing.T) { commit, err := repo.GetCommit("8006ff9adbf0cb94da7dad9e537e53817f9fa5c0") assert.NoError(t, err) - parentSHA := repo.objectFormat.MustIDFromString("8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2") - notParentSHA := repo.objectFormat.MustIDFromString("2839944139e0de9737a044f78b0e4b40d989a9e3") + parentSHA := MustIDFromString("8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2") + notParentSHA := MustIDFromString("2839944139e0de9737a044f78b0e4b40d989a9e3") haz, err := commit.HasPreviousCommit(parentSHA) assert.NoError(t, err) diff --git a/modules/git/last_commit_cache.go b/modules/git/last_commit_cache.go index 55585ac4ac9ec..44a4f43728610 100644 --- a/modules/git/last_commit_cache.go +++ b/modules/git/last_commit_cache.go @@ -92,11 +92,7 @@ func (c *LastCommitCache) Get(ref, entryPath string) (*Commit, error) { // GetCommitByPath gets the last commit for the entry in the provided commit func (c *LastCommitCache) GetCommitByPath(commitID, entryPath string) (*Commit, error) { - objectFormat, err := c.repo.GetObjectFormat() - if err != nil { - return nil, err - } - sha, err := objectFormat.NewIDFromString(commitID) + sha, err := NewIDFromString(commitID) if err != nil { return nil, err } diff --git a/modules/git/object_format.go b/modules/git/object_format.go index ee7e659ed04dd..27771e74598d9 100644 --- a/modules/git/object_format.go +++ b/modules/git/object_format.go @@ -6,6 +6,7 @@ package git import ( "crypto/sha1" "regexp" + "strconv" ) // sha1Pattern can be used to determine if a string is an valid sha @@ -20,14 +21,12 @@ type ObjectFormat interface { EmptyTree() ObjectID // FullLength is the length of the hash's hex string FullLength() int - + // IsValid returns true if the input is a valid hash IsValid(input string) bool + // MustID creates a new ObjectID from a byte slice MustID(b []byte) ObjectID - MustIDFromString(s string) ObjectID - NewID(b []byte) (ObjectID, error) - NewIDFromString(s string) (ObjectID, error) - - NewHasher() HasherInterface + // ComputeHash compute the hash for a given ObjectType and content + ComputeHash(t ObjectType, content []byte) ObjectID } type Sha1ObjectFormatImpl struct{} @@ -59,20 +58,18 @@ func (Sha1ObjectFormatImpl) MustID(b []byte) ObjectID { return &id } -func (h Sha1ObjectFormatImpl) MustIDFromString(s string) ObjectID { - return MustIDFromString(h, s) -} - -func (h Sha1ObjectFormatImpl) NewID(b []byte) (ObjectID, error) { - return IDFromRaw(h, b) -} - -func (h Sha1ObjectFormatImpl) NewIDFromString(s string) (ObjectID, error) { - return genericIDFromString(h, s) -} - -func (h Sha1ObjectFormatImpl) NewHasher() HasherInterface { - return &Sha1Hasher{sha1.New()} +// ComputeHash compute the hash for a given ObjectType and content +func (h Sha1ObjectFormatImpl) ComputeHash(t ObjectType, content []byte) ObjectID { + hasher := sha1.New() + _, _ = hasher.Write(t.Bytes()) + _, _ = hasher.Write([]byte(" ")) + _, _ = hasher.Write([]byte(strconv.FormatInt(int64(len(content)), 10))) + _, _ = hasher.Write([]byte{0}) + + // HashSum generates a SHA1 for the provided hash + var sha1 Sha1Hash + copy(sha1[:], hasher.Sum(nil)) + return &sha1 } var Sha1ObjectFormat ObjectFormat = Sha1ObjectFormatImpl{} diff --git a/modules/git/object_id.go b/modules/git/object_id.go index a90683678a817..01c23ed3dae84 100644 --- a/modules/git/object_id.go +++ b/modules/git/object_id.go @@ -6,11 +6,7 @@ package git import ( "bytes" "encoding/hex" - "errors" "fmt" - "hash" - "strconv" - "strings" ) type ObjectID interface { @@ -35,48 +31,36 @@ func (*Sha1Hash) Type() ObjectFormat { return Sha1ObjectFormat } var _ ObjectID = &Sha1Hash{} -// EmptyObjectID creates a new ObjectID from an object format hash name -func EmptyObjectID(objectFormatName string) (ObjectID, error) { - objectFormat := ObjectFormatFromName(objectFormatName) - if objectFormat != nil { - return objectFormat.EmptyObjectID(), nil +func MustIDFromString(hexHash string) ObjectID { + id, err := NewIDFromString(hexHash) + if err != nil { + panic(err) } - - return nil, errors.New("unsupported hash type") + return id } -func IDFromRaw(h ObjectFormat, b []byte) (ObjectID, error) { - if len(b) != h.FullLength()/2 { - return h.EmptyObjectID(), fmt.Errorf("length must be %d: %v", h.FullLength(), b) +func NewIDFromString(hexHash string) (ObjectID, error) { + var theObjectFormat ObjectFormat + for _, objectFormat := range SupportedObjectFormats { + if len(hexHash) == objectFormat.FullLength() { + theObjectFormat = objectFormat + break + } } - return h.MustID(b), nil -} -func MustIDFromString(h ObjectFormat, s string) ObjectID { - b, _ := hex.DecodeString(s) - return h.MustID(b) -} - -func genericIDFromString(h ObjectFormat, s string) (ObjectID, error) { - s = strings.TrimSpace(s) - if len(s) != h.FullLength() { - return h.EmptyObjectID(), fmt.Errorf("length must be %d: %s", h.FullLength(), s) + if theObjectFormat == nil { + return nil, fmt.Errorf("length %d has no matched object format: %s", len(hexHash), hexHash) } - b, err := hex.DecodeString(s) + + b, err := hex.DecodeString(hexHash) if err != nil { - return h.EmptyObjectID(), err + return nil, err } - return h.NewID(b) -} -func IDFromString(hexHash string) (ObjectID, error) { - for _, objectFormat := range SupportedObjectFormats { - if len(hexHash) == objectFormat.FullLength() { - return objectFormat.NewIDFromString(hexHash) - } + if len(b) != theObjectFormat.FullLength()/2 { + return theObjectFormat.EmptyObjectID(), fmt.Errorf("length must be %d: %v", theObjectFormat.FullLength(), b) } - - return nil, fmt.Errorf("invalid hash hex string: '%s' len: %d", hexHash, len(hexHash)) + return theObjectFormat.MustID(b), nil } func IsEmptyCommitID(commitID string) bool { @@ -84,7 +68,7 @@ func IsEmptyCommitID(commitID string) bool { return true } - id, err := IDFromString(commitID) + id, err := NewIDFromString(commitID) if err != nil { return false } @@ -92,37 +76,9 @@ func IsEmptyCommitID(commitID string) bool { return id.IsZero() } -// HasherInterface is a struct that will generate a Hash -type HasherInterface interface { - hash.Hash - - HashSum() ObjectID -} - -type Sha1Hasher struct { - hash.Hash -} - // ComputeBlobHash compute the hash for a given blob content func ComputeBlobHash(hashType ObjectFormat, content []byte) ObjectID { - return ComputeHash(hashType, ObjectBlob, content) -} - -// ComputeHash compute the hash for a given ObjectType and content -func ComputeHash(hashType ObjectFormat, t ObjectType, content []byte) ObjectID { - h := hashType.NewHasher() - _, _ = h.Write(t.Bytes()) - _, _ = h.Write([]byte(" ")) - _, _ = h.Write([]byte(strconv.FormatInt(int64(len(content)), 10))) - _, _ = h.Write([]byte{0}) - return h.HashSum() -} - -// HashSum generates a SHA1 for the provided hash -func (h *Sha1Hasher) HashSum() ObjectID { - var sha1 Sha1Hash - copy(sha1[:], h.Hash.Sum(nil)) - return &sha1 + return hashType.ComputeHash(ObjectBlob, content) } type ErrInvalidSHA struct { diff --git a/modules/git/parse_gogit.go b/modules/git/parse_gogit.go index 6c22ea8da7bf5..d1fdd346e4158 100644 --- a/modules/git/parse_gogit.go +++ b/modules/git/parse_gogit.go @@ -57,7 +57,7 @@ func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) { return nil, fmt.Errorf("Invalid ls-tree output: %s", string(data)) } var err error - entry.ID, err = IDFromString(string(data[pos : pos+hash.Size*2])) + entry.ID, err = NewIDFromString(string(data[pos : pos+hash.Size*2])) if err != nil { return nil, fmt.Errorf("invalid ls-tree output: %w", err) } diff --git a/modules/git/parse_gogit_test.go b/modules/git/parse_gogit_test.go index 9755f81cce617..d9e5b4441fffd 100644 --- a/modules/git/parse_gogit_test.go +++ b/modules/git/parse_gogit_test.go @@ -28,9 +28,9 @@ func TestParseTreeEntries(t *testing.T) { Input: "100644 blob 61ab7345a1a3bbc590068ccae37b8515cfc5843c 1022\texample/file2.txt\n", Expected: []*TreeEntry{ { - ID: Sha1ObjectFormat.MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), + ID: MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), gogitTreeEntry: &object.TreeEntry{ - Hash: plumbing.Hash(Sha1ObjectFormat.MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c").RawValue()), + Hash: plumbing.Hash(MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c").RawValue()), Name: "example/file2.txt", Mode: filemode.Regular, }, @@ -44,9 +44,9 @@ func TestParseTreeEntries(t *testing.T) { "040000 tree 1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8 -\texample\n", Expected: []*TreeEntry{ { - ID: Sha1ObjectFormat.MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), + ID: MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"), gogitTreeEntry: &object.TreeEntry{ - Hash: plumbing.Hash(Sha1ObjectFormat.MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c").RawValue()), + Hash: plumbing.Hash(MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c").RawValue()), Name: "example/\n.txt", Mode: filemode.Symlink, }, @@ -54,10 +54,10 @@ func TestParseTreeEntries(t *testing.T) { sized: true, }, { - ID: Sha1ObjectFormat.MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8"), + ID: MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8"), sized: true, gogitTreeEntry: &object.TreeEntry{ - Hash: plumbing.Hash(Sha1ObjectFormat.MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8").RawValue()), + Hash: plumbing.Hash(MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8").RawValue()), Name: "example", Mode: filemode.Dir, }, diff --git a/modules/git/parse_nogogit.go b/modules/git/parse_nogogit.go index e35704eb34e9c..225342cc5a108 100644 --- a/modules/git/parse_nogogit.go +++ b/modules/git/parse_nogogit.go @@ -72,7 +72,7 @@ func parseTreeEntries(objectFormat ObjectFormat, data []byte, ptree *Tree) ([]*T return nil, fmt.Errorf("unknown type: %v", string(entryMode)) } - entry.ID, err = objectFormat.NewIDFromString(string(entryObjectID)) + entry.ID, err = NewIDFromString(string(entryObjectID)) if err != nil { return nil, fmt.Errorf("invalid ls-tree output (invalid object id): %q, err: %w", line, err) } diff --git a/modules/git/parse_nogogit_test.go b/modules/git/parse_nogogit_test.go index 36313e00f331c..f037fd7a2e75b 100644 --- a/modules/git/parse_nogogit_test.go +++ b/modules/git/parse_nogogit_test.go @@ -26,28 +26,28 @@ func TestParseTreeEntriesLong(t *testing.T) { `, Expected: []*TreeEntry{ { - ID: objectFormat.MustIDFromString("ea0d83c9081af9500ac9f804101b3fd0a5c293af"), + ID: MustIDFromString("ea0d83c9081af9500ac9f804101b3fd0a5c293af"), name: "README.md", entryMode: EntryModeBlob, size: 8218, sized: true, }, { - ID: objectFormat.MustIDFromString("037f27dc9d353ae4fd50f0474b2194c593914e35"), + ID: MustIDFromString("037f27dc9d353ae4fd50f0474b2194c593914e35"), name: "README_ZH.md", entryMode: EntryModeBlob, size: 4681, sized: true, }, { - ID: objectFormat.MustIDFromString("9846a94f7e8350a916632929d0fda38c90dd2ca8"), + ID: MustIDFromString("9846a94f7e8350a916632929d0fda38c90dd2ca8"), name: "SECURITY.md", entryMode: EntryModeBlob, size: 429, sized: true, }, { - ID: objectFormat.MustIDFromString("84b90550547016f73c5dd3f50dea662389e67b6d"), + ID: MustIDFromString("84b90550547016f73c5dd3f50dea662389e67b6d"), name: "assets", entryMode: EntryModeTree, sized: true, @@ -78,12 +78,12 @@ func TestParseTreeEntriesShort(t *testing.T) { `, Expected: []*TreeEntry{ { - ID: objectFormat.MustIDFromString("ea0d83c9081af9500ac9f804101b3fd0a5c293af"), + ID: MustIDFromString("ea0d83c9081af9500ac9f804101b3fd0a5c293af"), name: "README.md", entryMode: EntryModeBlob, }, { - ID: objectFormat.MustIDFromString("84b90550547016f73c5dd3f50dea662389e67b6d"), + ID: MustIDFromString("84b90550547016f73c5dd3f50dea662389e67b6d"), name: "assets", entryMode: EntryModeTree, }, diff --git a/modules/git/pipeline/lfs_nogogit.go b/modules/git/pipeline/lfs_nogogit.go index 89cbf740ffa9e..a725f4799db80 100644 --- a/modules/git/pipeline/lfs_nogogit.go +++ b/modules/git/pipeline/lfs_nogogit.go @@ -115,11 +115,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err continue case "commit": // Read in the commit to get its tree and in case this is one of the last used commits - objectFormat, err := repo.GetObjectFormat() - if err != nil { - return nil, err - } - curCommit, err = git.CommitFromReader(repo, objectFormat.MustIDFromString(string(commitID)), io.LimitReader(batchReader, size)) + curCommit, err = git.CommitFromReader(repo, git.MustIDFromString(string(commitID)), io.LimitReader(batchReader, size)) if err != nil { return nil, err } diff --git a/modules/git/repo.go b/modules/git/repo.go index 52e54715d6532..7ccce0ba20e67 100644 --- a/modules/git/repo.go +++ b/modules/git/repo.go @@ -81,7 +81,7 @@ func GetObjectFormatOfRepo(ctx context.Context, repoPath string) (ObjectFormat, return nil, errors.New(stderr.String()) } - h, err := IDFromString(strings.TrimRight(stdout.String(), "\n")) + h, err := NewIDFromString(strings.TrimRight(stdout.String(), "\n")) if err != nil { return nil, err } diff --git a/modules/git/repo_blob.go b/modules/git/repo_blob.go index b5447b2bb131a..698b6c7074a68 100644 --- a/modules/git/repo_blob.go +++ b/modules/git/repo_blob.go @@ -5,7 +5,7 @@ package git // GetBlob finds the blob object in the repository. func (repo *Repository) GetBlob(idStr string) (*Blob, error) { - id, err := repo.objectFormat.NewIDFromString(idStr) + id, err := NewIDFromString(idStr) if err != nil { return nil, err } diff --git a/modules/git/repo_blob_test.go b/modules/git/repo_blob_test.go index e122573954180..8a5f5fcd5b050 100644 --- a/modules/git/repo_blob_test.go +++ b/modules/git/repo_blob_test.go @@ -61,7 +61,7 @@ func TestRepository_GetBlob_NoId(t *testing.T) { defer r.Close() testCase := "" - testError := fmt.Errorf("length must be 40: %s", testCase) + testError := fmt.Errorf("length %d has no matched object format: %s", len(testCase), testCase) blob, err := r.GetBlob(testCase) assert.Nil(t, blob) diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go index 58bbcf9303f2c..ccb3eb4adef0b 100644 --- a/modules/git/repo_commit.go +++ b/modules/git/repo_commit.go @@ -63,7 +63,7 @@ func (repo *Repository) getCommitByPathWithID(id ObjectID, relpath string) (*Com return nil, runErr } - id, err := repo.objectFormat.NewIDFromString(stdout) + id, err := NewIDFromString(stdout) if err != nil { return nil, err } @@ -254,7 +254,7 @@ func (repo *Repository) CommitsByFileAndRange(opts CommitsByFileAndRangeOptions) } return commits, err } - objectID, err := repo.objectFormat.NewIDFromString(string(shaline[0:len])) + objectID, err := NewIDFromString(string(shaline[0:len])) if err != nil { return nil, err } diff --git a/modules/git/repo_commit_gogit.go b/modules/git/repo_commit_gogit.go index d0992fd385ae0..4cab9575644cc 100644 --- a/modules/git/repo_commit_gogit.go +++ b/modules/git/repo_commit_gogit.go @@ -43,7 +43,7 @@ func (repo *Repository) RemoveReference(name string) error { func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) { objectFormat := repo.objectFormat if len(commitID) == hash.HexSize && objectFormat.IsValid(commitID) { - ID, err := objectFormat.NewIDFromString(commitID) + ID, err := NewIDFromString(commitID) if err == nil { return ID, nil } @@ -59,7 +59,7 @@ func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) { return objectFormat.EmptyObjectID(), err } - return objectFormat.NewIDFromString(actualCommitID) + return NewIDFromString(actualCommitID) } // IsCommitExist returns true if given commit exists in current repository. diff --git a/modules/git/repo_commit_nogogit.go b/modules/git/repo_commit_nogogit.go index 018e271c394ef..f0214e1ff8582 100644 --- a/modules/git/repo_commit_nogogit.go +++ b/modules/git/repo_commit_nogogit.go @@ -135,7 +135,7 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id ObjectID) func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) { IDType := repo.objectFormat if len(commitID) == IDType.FullLength() && IDType.IsValid(commitID) { - ID, err := repo.objectFormat.NewIDFromString(commitID) + ID, err := NewIDFromString(commitID) if err == nil { return ID, nil } @@ -155,5 +155,5 @@ func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) { return nil, err } - return repo.objectFormat.MustIDFromString(string(sha)), nil + return MustIDFromString(string(sha)), nil } diff --git a/modules/git/repo_index.go b/modules/git/repo_index.go index e3b19bf036463..47705a92af6f3 100644 --- a/modules/git/repo_index.go +++ b/modules/git/repo_index.go @@ -30,7 +30,7 @@ func (repo *Repository) ReadTreeToIndex(treeish string, indexFilename ...string) treeish = res[:len(res)-1] } } - id, err := objectFormat.NewIDFromString(treeish) + id, err := NewIDFromString(treeish) if err != nil { return err } @@ -128,7 +128,7 @@ func (repo *Repository) WriteTree() (*Tree, error) { if runErr != nil { return nil, runErr } - id, err := repo.objectFormat.NewIDFromString(strings.TrimSpace(stdout)) + id, err := NewIDFromString(strings.TrimSpace(stdout)) if err != nil { return nil, err } diff --git a/modules/git/repo_language_stats_nogogit.go b/modules/git/repo_language_stats_nogogit.go index b733c119f9e7c..1d94ad6c00f4b 100644 --- a/modules/git/repo_language_stats_nogogit.go +++ b/modules/git/repo_language_stats_nogogit.go @@ -39,7 +39,7 @@ func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, err return nil, ErrNotExist{commitID, ""} } - sha, err := repo.objectFormat.NewIDFromString(string(shaBytes)) + sha, err := NewIDFromString(string(shaBytes)) if err != nil { log.Debug("Unable to get commit for: %s. Err: %v", commitID, err) return nil, ErrNotExist{commitID, ""} diff --git a/modules/git/repo_object.go b/modules/git/repo_object.go index 220fdb38074de..3d48b91c6d961 100644 --- a/modules/git/repo_object.go +++ b/modules/git/repo_object.go @@ -46,7 +46,7 @@ func (repo *Repository) GetObjectFormat() (ObjectFormat, error) { if err != nil { return nil, err } - hash, err := IDFromString(str) + hash, err := NewIDFromString(str) if err != nil { return nil, err } @@ -62,7 +62,7 @@ func (repo *Repository) HashObject(reader io.Reader) (ObjectID, error) { if err != nil { return nil, err } - return repo.objectFormat.NewIDFromString(idStr) + return NewIDFromString(idStr) } func (repo *Repository) hashObject(reader io.Reader, save bool) (string, error) { diff --git a/modules/git/repo_ref_nogogit.go b/modules/git/repo_ref_nogogit.go index c1be60871cfe4..ac53d661b517b 100644 --- a/modules/git/repo_ref_nogogit.go +++ b/modules/git/repo_ref_nogogit.go @@ -75,7 +75,7 @@ func (repo *Repository) GetRefsFiltered(pattern string) ([]*Reference, error) { if pattern == "" || strings.HasPrefix(refName, pattern) { r := &Reference{ Name: refName, - Object: repo.objectFormat.MustIDFromString(sha), + Object: MustIDFromString(sha), Type: typ, repo: repo, } diff --git a/modules/git/repo_tag.go b/modules/git/repo_tag.go index 0b08e457cbe94..698b9b41f3ce4 100644 --- a/modules/git/repo_tag.go +++ b/modules/git/repo_tag.go @@ -84,7 +84,7 @@ func (repo *Repository) GetTag(name string) (*Tag, error) { return nil, err } - id, err := repo.objectFormat.NewIDFromString(idStr) + id, err := NewIDFromString(idStr) if err != nil { return nil, err } @@ -98,7 +98,7 @@ func (repo *Repository) GetTag(name string) (*Tag, error) { // GetTagWithID returns a Git tag by given name and ID func (repo *Repository) GetTagWithID(idStr, name string) (*Tag, error) { - id, err := repo.objectFormat.NewIDFromString(idStr) + id, err := NewIDFromString(idStr) if err != nil { return nil, err } @@ -165,7 +165,7 @@ func parseTagRef(objectFormat ObjectFormat, ref map[string]string) (tag *Tag, er Name: ref["refname:short"], } - tag.ID, err = objectFormat.NewIDFromString(ref["objectname"]) + tag.ID, err = NewIDFromString(ref["objectname"]) if err != nil { return nil, fmt.Errorf("parse objectname '%s': %w", ref["objectname"], err) } @@ -175,7 +175,7 @@ func parseTagRef(objectFormat ObjectFormat, ref map[string]string) (tag *Tag, er tag.Object = tag.ID } else { // annotated tag - tag.Object, err = objectFormat.NewIDFromString(ref["object"]) + tag.Object, err = NewIDFromString(ref["object"]) if err != nil { return nil, fmt.Errorf("parse object '%s': %w", ref["object"], err) } @@ -208,7 +208,7 @@ func parseTagRef(objectFormat ObjectFormat, ref map[string]string) (tag *Tag, er // GetAnnotatedTag returns a Git tag by its SHA, must be an annotated tag func (repo *Repository) GetAnnotatedTag(sha string) (*Tag, error) { - id, err := repo.objectFormat.NewIDFromString(sha) + id, err := NewIDFromString(sha) if err != nil { return nil, err } diff --git a/modules/git/repo_tag_gogit.go b/modules/git/repo_tag_gogit.go index c3711ba5a07d0..4a7a06e9bdaf1 100644 --- a/modules/git/repo_tag_gogit.go +++ b/modules/git/repo_tag_gogit.go @@ -88,7 +88,7 @@ func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) { // every tag should have a commit ID so return all errors return nil, err } - commitID, err := IDFromString(commitIDStr) + commitID, err := NewIDFromString(commitIDStr) if err != nil { return nil, err } diff --git a/modules/git/repo_tag_nogogit.go b/modules/git/repo_tag_nogogit.go index 3cea4894f17a2..5d98fadd54366 100644 --- a/modules/git/repo_tag_nogogit.go +++ b/modules/git/repo_tag_nogogit.go @@ -64,7 +64,7 @@ func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) { // every tag should have a commit ID so return all errors return nil, err } - commitID, err := repo.objectFormat.NewIDFromString(commitIDStr) + commitID, err := NewIDFromString(commitIDStr) if err != nil { return nil, err } diff --git a/modules/git/repo_tag_test.go b/modules/git/repo_tag_test.go index 48c1bc41c2375..6b9df1746f7d2 100644 --- a/modules/git/repo_tag_test.go +++ b/modules/git/repo_tag_test.go @@ -224,8 +224,8 @@ func TestRepository_parseTagRef(t *testing.T) { want: &Tag{ Name: "v1.9.1", - ID: sha1.MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), - Object: sha1.MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), + ID: MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), + Object: MustIDFromString("ab23e4b7f4cd0caafe0174c0e7ef6d651ba72889"), Type: "commit", Tagger: parseAuthorLine(t, "Foo Bar 1565789218 +0300"), Message: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md\n", @@ -253,8 +253,8 @@ func TestRepository_parseTagRef(t *testing.T) { want: &Tag{ Name: "v0.0.1", - ID: sha1.MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), - Object: sha1.MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), + ID: MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), + Object: MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), Type: "tag", Tagger: parseAuthorLine(t, "Foo Bar 1565789218 +0300"), Message: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md\n", @@ -311,8 +311,8 @@ qbHDASXl want: &Tag{ Name: "v0.0.1", - ID: sha1.MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), - Object: sha1.MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), + ID: MustIDFromString("8c68a1f06fc59c655b7e3905b159d761e91c53c9"), + Object: MustIDFromString("3325fd8a973321fd59455492976c042dde3fd1ca"), Type: "tag", Tagger: parseAuthorLine(t, "Foo Bar 1565789218 +0300"), Message: "Add changelog of v1.9.1 (#7859)\n\n* add changelog of v1.9.1\n* Update CHANGELOG.md", diff --git a/modules/git/repo_tree.go b/modules/git/repo_tree.go index 9ee80351f0f61..ab48d47d13c09 100644 --- a/modules/git/repo_tree.go +++ b/modules/git/repo_tree.go @@ -63,5 +63,5 @@ func (repo *Repository) CommitTree(author, committer *Signature, tree *Tree, opt if err != nil { return nil, ConcatenateError(err, stderr.String()) } - return repo.objectFormat.NewIDFromString(strings.TrimSpace(stdout.String())) + return NewIDFromString(strings.TrimSpace(stdout.String())) } diff --git a/modules/git/repo_tree_gogit.go b/modules/git/repo_tree_gogit.go index 415572e65a138..6391959e6acd3 100644 --- a/modules/git/repo_tree_gogit.go +++ b/modules/git/repo_tree_gogit.go @@ -30,7 +30,7 @@ func (repo *Repository) GetTree(idStr string) (*Tree, error) { idStr = res[:len(res)-1] } } - id, err := repo.objectFormat.NewIDFromString(idStr) + id, err := NewIDFromString(idStr) if err != nil { return nil, err } diff --git a/modules/git/repo_tree_nogogit.go b/modules/git/repo_tree_nogogit.go index f502cc140b7f9..20c92a79ed9b1 100644 --- a/modules/git/repo_tree_nogogit.go +++ b/modules/git/repo_tree_nogogit.go @@ -75,7 +75,7 @@ func (repo *Repository) GetTree(idStr string) (*Tree, error) { idStr = res } } - id, err := repo.objectFormat.NewIDFromString(idStr) + id, err := NewIDFromString(idStr) if err != nil { return nil, err } diff --git a/modules/git/tag.go b/modules/git/tag.go index c7d0d8aef92b2..01a8d6f6a552b 100644 --- a/modules/git/tag.go +++ b/modules/git/tag.go @@ -50,7 +50,7 @@ l: reftype := line[:spacepos] switch string(reftype) { case "object": - id, err := objectFormat.NewIDFromString(string(line[spacepos+1:])) + id, err := NewIDFromString(string(line[spacepos+1:])) if err != nil { return nil, err } diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go index afcb183d7237a..827b2a98493b0 100644 --- a/modules/repository/commits_test.go +++ b/modules/repository/commits_test.go @@ -144,7 +144,7 @@ func TestCommitToPushCommit(t *testing.T) { When: now, } const hexString = "0123456789abcdef0123456789abcdef01234567" - sha1, err := git.IDFromString(hexString) + sha1, err := git.NewIDFromString(hexString) assert.NoError(t, err) pushCommit := CommitToPushCommit(&git.Commit{ ID: sha1, @@ -169,12 +169,11 @@ func TestListToPushCommits(t *testing.T) { When: now, } - hashType := git.Sha1ObjectFormat const hexString1 = "0123456789abcdef0123456789abcdef01234567" - hash1, err := hashType.NewIDFromString(hexString1) + hash1, err := git.NewIDFromString(hexString1) assert.NoError(t, err) const hexString2 = "fedcba9876543210fedcba9876543210fedcba98" - hash2, err := hashType.NewIDFromString(hexString2) + hash2, err := git.NewIDFromString(hexString2) assert.NoError(t, err) l := []*git.Commit{ diff --git a/modules/repository/push.go b/modules/repository/push.go index 25695336a52d3..cf047847b6ca9 100644 --- a/modules/repository/push.go +++ b/modules/repository/push.go @@ -20,13 +20,13 @@ type PushUpdateOptions struct { // IsNewRef return true if it's a first-time push to a branch, tag or etc. func (opts *PushUpdateOptions) IsNewRef() bool { - commitID, err := git.IDFromString(opts.OldCommitID) + commitID, err := git.NewIDFromString(opts.OldCommitID) return err == nil && commitID.IsZero() } // IsDelRef return true if it's a deletion to a branch or tag func (opts *PushUpdateOptions) IsDelRef() bool { - commitID, err := git.IDFromString(opts.NewCommitID) + commitID, err := git.NewIDFromString(opts.NewCommitID) return err == nil && commitID.IsZero() } diff --git a/routers/api/v1/utils/git.go b/routers/api/v1/utils/git.go index dfb1a130c3711..39714e343f013 100644 --- a/routers/api/v1/utils/git.go +++ b/routers/api/v1/utils/git.go @@ -73,7 +73,7 @@ func searchRefCommitByType(ctx *context.APIContext, refType, filter string) (str func ConvertToObjectID(ctx gocontext.Context, repo *context.Repository, commitID string) (git.ObjectID, error) { objectFormat, _ := repo.GitRepo.GetObjectFormat() if len(commitID) == objectFormat.FullLength() && objectFormat.IsValid(commitID) { - sha, err := objectFormat.NewIDFromString(commitID) + sha, err := git.NewIDFromString(commitID) if err == nil { return sha, nil } diff --git a/routers/private/hook_verification.go b/routers/private/hook_verification.go index 8b2d0dd848a9d..42b8e5abed810 100644 --- a/routers/private/hook_verification.go +++ b/routers/private/hook_verification.go @@ -83,8 +83,8 @@ func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error { _ = stdoutReader.Close() _ = stdoutWriter.Close() }() - objectFormat, _ := repo.GetObjectFormat() - commitID := objectFormat.MustIDFromString(sha) + + commitID := git.MustIDFromString(sha) return git.NewCommand(repo.Ctx, "cat-file", "commit").AddDynamicArguments(sha). Run(&git.RunOpts{ diff --git a/routers/web/repo/setting/lfs.go b/routers/web/repo/setting/lfs.go index 230f1a2a608a5..edf1298c2073e 100644 --- a/routers/web/repo/setting/lfs.go +++ b/routers/web/repo/setting/lfs.go @@ -395,7 +395,7 @@ func LFSFileFind(ctx *context.Context) { objectID = git.ComputeBlobHash(objectFormat, []byte(pointer.StringContent())) sha = objectID.String() } else { - objectID = objectFormat.MustIDFromString(sha) + objectID = git.MustIDFromString(sha) } ctx.Data["LFSFilesLink"] = ctx.Repo.RepoLink + "/settings/lfs" ctx.Data["Oid"] = oid diff --git a/services/actions/commit_status.go b/services/actions/commit_status.go index c1fc1eda92aab..72a3ab7ac60e2 100644 --- a/services/actions/commit_status.go +++ b/services/actions/commit_status.go @@ -115,7 +115,7 @@ func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er } creator := user_model.NewActionsUser() - commitID, err := git.IDFromString(sha) + commitID, err := git.NewIDFromString(sha) if err != nil { return fmt.Errorf("HashTypeInterfaceFromHashString: %w", err) } diff --git a/services/pull/patch.go b/services/pull/patch.go index 1dbbec373d165..acaff04bda474 100644 --- a/services/pull/patch.go +++ b/services/pull/patch.go @@ -130,8 +130,6 @@ func (e *errMergeConflict) Error() string { func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, gitRepo *git.Repository) error { log.Trace("Attempt to merge:\n%v", file) - objectFormat, _ := gitRepo.GetObjectFormat() - switch { case file.stage1 != nil && (file.stage2 == nil || file.stage3 == nil): // 1. Deleted in one or both: @@ -148,7 +146,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, g // 2. Added in ours but not in theirs or identical in both // // Not a genuine conflict just add to the index - if err := gitRepo.AddObjectToIndex(file.stage2.mode, objectFormat.MustIDFromString(file.stage2.sha), file.stage2.path); err != nil { + if err := gitRepo.AddObjectToIndex(file.stage2.mode, git.MustIDFromString(file.stage2.sha), file.stage2.path); err != nil { return err } return nil @@ -161,7 +159,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, g // 4. Added in theirs but not ours: // // Not a genuine conflict just add to the index - return gitRepo.AddObjectToIndex(file.stage3.mode, objectFormat.MustIDFromString(file.stage3.sha), file.stage3.path) + return gitRepo.AddObjectToIndex(file.stage3.mode, git.MustIDFromString(file.stage3.sha), file.stage3.path) case file.stage1 == nil: // 5. Created by new in both // @@ -222,7 +220,7 @@ func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, g return err } hash = strings.TrimSpace(hash) - return gitRepo.AddObjectToIndex(file.stage2.mode, objectFormat.MustIDFromString(hash), file.stage2.path) + return gitRepo.AddObjectToIndex(file.stage2.mode, git.MustIDFromString(hash), file.stage2.path) default: if file.stage1 != nil { return &errMergeConflict{file.stage1.path} From e7cb8da2a8310ac167b6f613b283caa3316a7154 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 19 Dec 2023 17:29:05 +0800 Subject: [PATCH 47/60] Always enable caches (#28527) Nowadays, cache will be used on almost everywhere of Gitea and it cannot be disabled, otherwise some features will become unaviable. Then I think we can just remove the option for cache enable. That means cache cannot be disabled. But of course, we can still use cache configuration to set how should Gitea use the cache. --- custom/conf/app.example.ini | 5 ---- .../config-cheat-sheet.en-us.md | 2 -- .../config-cheat-sheet.zh-cn.md | 2 -- modules/cache/cache.go | 6 ++--- modules/cache/cache_test.go | 4 ++-- modules/git/last_commit_cache.go | 2 +- modules/setting/cache.go | 23 ------------------- routers/api/v1/misc/nodeinfo.go | 16 ++++++------- routers/init.go | 2 +- routers/web/auth/auth.go | 16 +++++-------- routers/web/auth/password.go | 8 +++---- routers/web/healthcheck/check.go | 4 ---- routers/web/user/setting/account.go | 18 +++++++-------- services/repository/cache.go | 5 ---- 14 files changed, 31 insertions(+), 82 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 9a5d19074595f..f10a3f2edff37 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1705,9 +1705,6 @@ LEVEL = Info ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; if the cache enabled -;ENABLED = true -;; ;; Either "memory", "redis", "memcache", or "twoqueue". default is "memory" ;ADAPTER = memory ;; @@ -1732,8 +1729,6 @@ LEVEL = Info ;[cache.last_commit] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; if the cache enabled -;ENABLED = true ;; ;; Time to keep items in cache if not used, default is 8760 hours. ;; Setting it to -1 disables caching diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 9810dab49bc15..93a19cec4e7bb 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -763,7 +763,6 @@ and ## Cache (`cache`) -- `ENABLED`: **true**: Enable the cache. - `ADAPTER`: **memory**: Cache engine adapter, either `memory`, `redis`, `redis-cluster`, `twoqueue` or `memcache`. (`twoqueue` represents a size limited LRU cache.) - `INTERVAL`: **60**: Garbage Collection interval (sec), for memory and twoqueue cache only. - `HOST`: **_empty_**: Connection string for `redis`, `redis-cluster` and `memcache`. For `twoqueue` sets configuration for the queue. @@ -775,7 +774,6 @@ and ## Cache - LastCommitCache settings (`cache.last_commit`) -- `ENABLED`: **true**: Enable the cache. - `ITEM_TTL`: **8760h**: Time to keep items in cache if not used, Setting it to -1 disables caching. - `COMMITS_COUNT`: **1000**: Only enable the cache when repository's commits count great than. diff --git a/docs/content/administration/config-cheat-sheet.zh-cn.md b/docs/content/administration/config-cheat-sheet.zh-cn.md index eed752c1cbd7d..596e82a12a0e1 100644 --- a/docs/content/administration/config-cheat-sheet.zh-cn.md +++ b/docs/content/administration/config-cheat-sheet.zh-cn.md @@ -721,7 +721,6 @@ Gitea 创建以下非唯一队列: ## 缓存 (`cache`) -- `ENABLED`: **true**: 是否启用缓存。 - `ADAPTER`: **memory**: 缓存引擎,可以为 `memory`, `redis`, `redis-cluster`, `twoqueue` 和 `memcache`. (`twoqueue` 代表缓冲区固定的LRU缓存) - `INTERVAL`: **60**: 垃圾回收间隔(秒),只对`memory`和`towqueue`有效。 - `HOST`: **_empty_**: 缓存配置。`redis`, `redis-cluster`,`memcache`配置连接字符串;`twoqueue` 设置队列参数 @@ -733,7 +732,6 @@ Gitea 创建以下非唯一队列: ### 缓存 - 最后提交缓存设置 (`cache.last_commit`) -- `ENABLED`: **true**:是否启用缓存。 - `ITEM_TTL`: **8760h**:如果未使用,保持缓存中的项目的时间,将其设置为 -1 会禁用缓存。 - `COMMITS_COUNT`: **1000**:仅在存储库的提交计数大于时启用缓存。 diff --git a/modules/cache/cache.go b/modules/cache/cache.go index edaf483135b86..09afc8b7f7364 100644 --- a/modules/cache/cache.go +++ b/modules/cache/cache.go @@ -24,11 +24,11 @@ func newCache(cacheConfig setting.Cache) (mc.Cache, error) { }) } -// NewContext start cache service -func NewContext() error { +// Init start cache service +func Init() error { var err error - if conn == nil && setting.CacheService.Enabled { + if conn == nil { if conn, err = newCache(setting.CacheService.Cache); err != nil { return err } diff --git a/modules/cache/cache_test.go b/modules/cache/cache_test.go index cf464af392d53..3f6504092462a 100644 --- a/modules/cache/cache_test.go +++ b/modules/cache/cache_test.go @@ -22,9 +22,9 @@ func createTestCache() { } func TestNewContext(t *testing.T) { - assert.NoError(t, NewContext()) + assert.NoError(t, Init()) - setting.CacheService.Cache = setting.Cache{Enabled: true, Adapter: "redis", Conn: "some random string"} + setting.CacheService.Cache = setting.Cache{Adapter: "redis", Conn: "some random string"} con, err := newCache(setting.Cache{ Adapter: "rand", Conn: "false conf", diff --git a/modules/git/last_commit_cache.go b/modules/git/last_commit_cache.go index 44a4f43728610..7c7baedd2f39d 100644 --- a/modules/git/last_commit_cache.go +++ b/modules/git/last_commit_cache.go @@ -39,7 +39,7 @@ func NewLastCommitCache(count int64, repoPath string, gitRepo *Repository, cache if cache == nil { return nil } - if !setting.CacheService.LastCommit.Enabled || count < setting.CacheService.LastCommit.CommitsCount { + if count < setting.CacheService.LastCommit.CommitsCount { return nil } diff --git a/modules/setting/cache.go b/modules/setting/cache.go index 783246077d906..bfa6ca0e61678 100644 --- a/modules/setting/cache.go +++ b/modules/setting/cache.go @@ -12,7 +12,6 @@ import ( // Cache represents cache settings type Cache struct { - Enabled bool Adapter string Interval int Conn string @@ -24,23 +23,19 @@ var CacheService = struct { Cache `ini:"cache"` LastCommit struct { - Enabled bool TTL time.Duration `ini:"ITEM_TTL"` CommitsCount int64 } `ini:"cache.last_commit"` }{ Cache: Cache{ - Enabled: true, Adapter: "memory", Interval: 60, TTL: 16 * time.Hour, }, LastCommit: struct { - Enabled bool TTL time.Duration `ini:"ITEM_TTL"` CommitsCount int64 }{ - Enabled: true, TTL: 8760 * time.Hour, CommitsCount: 1000, }, @@ -65,30 +60,12 @@ func loadCacheFrom(rootCfg ConfigProvider) { if CacheService.Conn == "" { CacheService.Conn = "50000" } - case "": // disable cache - CacheService.Enabled = false default: log.Fatal("Unknown cache adapter: %s", CacheService.Adapter) } - if CacheService.Enabled { - log.Info("Cache Service Enabled") - } else { - log.Warn("Cache Service Disabled so that captcha disabled too") - // captcha depends on cache service - Service.EnableCaptcha = false - } - sec = rootCfg.Section("cache.last_commit") - if !CacheService.Enabled { - CacheService.LastCommit.Enabled = false - } - CacheService.LastCommit.CommitsCount = sec.Key("COMMITS_COUNT").MustInt64(1000) - - if CacheService.LastCommit.Enabled { - log.Info("Last Commit Cache Service Enabled") - } } // TTLSeconds returns the TTLSeconds or unix timestamp for memcache diff --git a/routers/api/v1/misc/nodeinfo.go b/routers/api/v1/misc/nodeinfo.go index f0d8d80dd4e1f..cc754f64a21a9 100644 --- a/routers/api/v1/misc/nodeinfo.go +++ b/routers/api/v1/misc/nodeinfo.go @@ -29,10 +29,9 @@ func NodeInfo(ctx *context.APIContext) { nodeInfoUsage := structs.NodeInfoUsage{} if setting.Federation.ShareUserStatistics { - cached := false - if setting.CacheService.Enabled { - nodeInfoUsage, cached = ctx.Cache.Get(cacheKeyNodeInfoUsage).(structs.NodeInfoUsage) - } + var cached bool + nodeInfoUsage, cached = ctx.Cache.Get(cacheKeyNodeInfoUsage).(structs.NodeInfoUsage) + if !cached { usersTotal := int(user_model.CountUsers(ctx, nil)) now := time.Now() @@ -53,11 +52,10 @@ func NodeInfo(ctx *context.APIContext) { LocalPosts: int(allIssues), LocalComments: int(allComments), } - if setting.CacheService.Enabled { - if err := ctx.Cache.Put(cacheKeyNodeInfoUsage, nodeInfoUsage, 180); err != nil { - ctx.InternalServerError(err) - return - } + + if err := ctx.Cache.Put(cacheKeyNodeInfoUsage, nodeInfoUsage, 180); err != nil { + ctx.InternalServerError(err) + return } } } diff --git a/routers/init.go b/routers/init.go index c1cfe26bc4c64..ee98aedb1655a 100644 --- a/routers/init.go +++ b/routers/init.go @@ -118,7 +118,7 @@ func InitWebInstalled(ctx context.Context) { mustInit(storage.Init) mailer.NewContext(ctx) - mustInit(cache.NewContext) + mustInit(cache.Init) mustInit(feed_service.Init) mustInit(uinotification.Init) mustInitCtx(ctx, archiver.Init) diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index 0ea91fc759a9a..8f37d05fda0ef 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -622,10 +622,8 @@ func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth. ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale) ctx.HTML(http.StatusOK, TplActivate) - if setting.CacheService.Enabled { - if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { - log.Error("Set cache(MailResendLimit) fail: %v", err) - } + if err := ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { + log.Error("Set cache(MailResendLimit) fail: %v", err) } return false } @@ -645,16 +643,14 @@ func Activate(ctx *context.Context) { } // Resend confirmation email. if setting.Service.RegisterEmailConfirm { - if setting.CacheService.Enabled && ctx.Cache.IsExist("MailResendLimit_"+ctx.Doer.LowerName) { + if ctx.Cache.IsExist("MailResendLimit_" + ctx.Doer.LowerName) { ctx.Data["ResendLimited"] = true } else { ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale) mailer.SendActivateAccountMail(ctx.Locale, ctx.Doer) - if setting.CacheService.Enabled { - if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil { - log.Error("Set cache(MailResendLimit) fail: %v", err) - } + if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil { + log.Error("Set cache(MailResendLimit) fail: %v", err) } } } else { @@ -789,7 +785,7 @@ func ActivateEmail(ctx *context.Context) { if u, err := user_model.GetUserByID(ctx, email.UID); err != nil { log.Warn("GetUserByID: %d", email.UID) - } else if setting.CacheService.Enabled { + } else { // Allow user to validate more emails _ = ctx.Cache.Delete("MailResendLimit_" + u.LowerName) } diff --git a/routers/web/auth/password.go b/routers/web/auth/password.go index bdfa8c40258f3..def9c2bcaac26 100644 --- a/routers/web/auth/password.go +++ b/routers/web/auth/password.go @@ -79,7 +79,7 @@ func ForgotPasswdPost(ctx *context.Context) { return } - if setting.CacheService.Enabled && ctx.Cache.IsExist("MailResendLimit_"+u.LowerName) { + if ctx.Cache.IsExist("MailResendLimit_" + u.LowerName) { ctx.Data["ResendLimited"] = true ctx.HTML(http.StatusOK, tplForgotPassword) return @@ -87,10 +87,8 @@ func ForgotPasswdPost(ctx *context.Context) { mailer.SendResetPasswordMail(u) - if setting.CacheService.Enabled { - if err = ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { - log.Error("Set cache(MailResendLimit) fail: %v", err) - } + if err = ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil { + log.Error("Set cache(MailResendLimit) fail: %v", err) } ctx.Data["ResetPwdCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ResetPwdCodeLives, ctx.Locale) diff --git a/routers/web/healthcheck/check.go b/routers/web/healthcheck/check.go index ecb73a928fd66..85f47613f0db7 100644 --- a/routers/web/healthcheck/check.go +++ b/routers/web/healthcheck/check.go @@ -121,10 +121,6 @@ func checkDatabase(ctx context.Context, checks checks) status { // cache checks gitea cache status func checkCache(checks checks) status { - if !setting.CacheService.Enabled { - return pass - } - st := componentStatus{} if err := cache.GetCache().Ping(); err != nil { st.Status = fail diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go index 5c14f3ad4b522..6d61d8021cc30 100644 --- a/routers/web/user/setting/account.go +++ b/routers/web/user/setting/account.go @@ -105,7 +105,7 @@ func EmailPost(ctx *context.Context) { // Send activation Email if ctx.FormString("_method") == "SENDACTIVATION" { var address string - if setting.CacheService.Enabled && ctx.Cache.IsExist("MailResendLimit_"+ctx.Doer.LowerName) { + if ctx.Cache.IsExist("MailResendLimit_" + ctx.Doer.LowerName) { log.Error("Send activation: activation still pending") ctx.Redirect(setting.AppSubURL + "/user/settings/account") return @@ -141,11 +141,10 @@ func EmailPost(ctx *context.Context) { } address = email.Email - if setting.CacheService.Enabled { - if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil { - log.Error("Set cache(MailResendLimit) fail: %v", err) - } + if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil { + log.Error("Set cache(MailResendLimit) fail: %v", err) } + ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", address, timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale))) ctx.Redirect(setting.AppSubURL + "/user/settings/account") return @@ -204,11 +203,10 @@ func EmailPost(ctx *context.Context) { // Send confirmation email if setting.Service.RegisterEmailConfirm { mailer.SendActivateEmailMail(ctx.Doer, email) - if setting.CacheService.Enabled { - if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil { - log.Error("Set cache(MailResendLimit) fail: %v", err) - } + if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil { + log.Error("Set cache(MailResendLimit) fail: %v", err) } + ctx.Flash.Info(ctx.Tr("settings.add_email_confirmation_sent", email.Email, timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale))) } else { ctx.Flash.Success(ctx.Tr("settings.add_email_success")) @@ -276,7 +274,7 @@ func loadAccountData(ctx *context.Context) { user_model.EmailAddress CanBePrimary bool } - pendingActivation := setting.CacheService.Enabled && ctx.Cache.IsExist("MailResendLimit_"+ctx.Doer.LowerName) + pendingActivation := ctx.Cache.IsExist("MailResendLimit_" + ctx.Doer.LowerName) emails := make([]*UserEmail, len(emlist)) for i, em := range emlist { var email UserEmail diff --git a/services/repository/cache.go b/services/repository/cache.go index 91351cbf491ae..b0811a99fc03b 100644 --- a/services/repository/cache.go +++ b/services/repository/cache.go @@ -9,15 +9,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/setting" ) // CacheRef cachhe last commit information of the branch or the tag func CacheRef(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, fullRefName git.RefName) error { - if !setting.CacheService.LastCommit.Enabled { - return nil - } - commit, err := gitRepo.GetCommit(fullRefName.String()) if err != nil { return err From 6a725b6f9cde28862869befb9d2b101d9e342427 Mon Sep 17 00:00:00 2001 From: Nanguan Lin <70063547+lng2020@users.noreply.github.com> Date: Wed, 20 Dec 2023 03:12:02 +0800 Subject: [PATCH 48/60] Remove deadcode under models/issues (#28536) Using the Go Official tool `golang.org/x/tools/cmd/deadcode@latest` mentioned by [go blog](https://go.dev/blog/deadcode). Just use `deadcode .` in the project root folder and it gives a list of unused functions. Though it has some false alarms. This PR removes dead code detected in `models/issues`. --- models/issues/assignees_test.go | 5 ++++- models/issues/issue.go | 9 --------- models/issues/issue_search.go | 20 -------------------- models/issues/issue_test.go | 30 ------------------------------ models/issues/label.go | 16 ---------------- models/issues/label_test.go | 24 ------------------------ models/issues/milestone_list.go | 26 -------------------------- models/issues/milestone_test.go | 29 ----------------------------- models/issues/pull.go | 30 ------------------------------ models/issues/stopwatch.go | 14 -------------- services/issue/assignee_test.go | 6 +++++- 11 files changed, 9 insertions(+), 200 deletions(-) diff --git a/models/issues/assignees_test.go b/models/issues/assignees_test.go index 3898e814c3137..2c33efd99e665 100644 --- a/models/issues/assignees_test.go +++ b/models/issues/assignees_test.go @@ -18,7 +18,10 @@ func TestUpdateAssignee(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // Fake issue with assignees - issue, err := issues_model.GetIssueWithAttrsByID(db.DefaultContext, 1) + issue, err := issues_model.GetIssueByID(db.DefaultContext, 1) + assert.NoError(t, err) + + err = issue.LoadAttributes(db.DefaultContext) assert.NoError(t, err) // Assign multiple users diff --git a/models/issues/issue.go b/models/issues/issue.go index b0ff0adddda18..90aad10bb9001 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -534,15 +534,6 @@ func GetIssueByID(ctx context.Context, id int64) (*Issue, error) { return issue, nil } -// GetIssueWithAttrsByID returns an issue with attributes by given ID. -func GetIssueWithAttrsByID(ctx context.Context, id int64) (*Issue, error) { - issue, err := GetIssueByID(ctx, id) - if err != nil { - return nil, err - } - return issue, issue.LoadAttributes(ctx) -} - // GetIssuesByIDs return issues with the given IDs. // If keepOrder is true, the order of the returned issues will be the same as the given IDs. func GetIssuesByIDs(ctx context.Context, issueIDs []int64, keepOrder ...bool) (IssueList, error) { diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go index 65ad3c81355a8..7dc277327a89c 100644 --- a/models/issues/issue_search.go +++ b/models/issues/issue_search.go @@ -455,26 +455,6 @@ func applySubscribedCondition(sess *xorm.Session, subscriberID int64) *xorm.Sess ) } -// GetRepoIDsForIssuesOptions find all repo ids for the given options -func GetRepoIDsForIssuesOptions(ctx context.Context, opts *IssuesOptions, user *user_model.User) ([]int64, error) { - repoIDs := make([]int64, 0, 5) - e := db.GetEngine(ctx) - - sess := e.Join("INNER", "repository", "`issue`.repo_id = `repository`.id") - - applyConditions(sess, opts) - - accessCond := repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid) - if err := sess.Where(accessCond). - Distinct("issue.repo_id"). - Table("issue"). - Find(&repoIDs); err != nil { - return nil, fmt.Errorf("unable to GetRepoIDsForIssuesOptions: %w", err) - } - - return repoIDs, nil -} - // Issues returns a list of issues by given conditions. func Issues(ctx context.Context, opts *IssuesOptions) (IssueList, error) { sess := db.GetEngine(ctx). diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go index 4393d18bcf49d..723fa27b1be2f 100644 --- a/models/issues/issue_test.go +++ b/models/issues/issue_test.go @@ -216,36 +216,6 @@ func TestIssue_loadTotalTimes(t *testing.T) { assert.Equal(t, int64(3682), ms.TotalTrackedTime) } -func TestGetRepoIDsForIssuesOptions(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - for _, test := range []struct { - Opts issues_model.IssuesOptions - ExpectedRepoIDs []int64 - }{ - { - issues_model.IssuesOptions{ - AssigneeID: 2, - }, - []int64{3, 32}, - }, - { - issues_model.IssuesOptions{ - RepoCond: builder.In("repo_id", 1, 2), - }, - []int64{1, 2}, - }, - } { - repoIDs, err := issues_model.GetRepoIDsForIssuesOptions(db.DefaultContext, &test.Opts, user) - assert.NoError(t, err) - if assert.Len(t, repoIDs, len(test.ExpectedRepoIDs)) { - for i, repoID := range repoIDs { - assert.EqualValues(t, test.ExpectedRepoIDs[i], repoID) - } - } - } -} - func testInsertIssue(t *testing.T, title, content string, expectIndex int64) *issues_model.Issue { var newIssue issues_model.Issue t.Run(title, func(t *testing.T) { diff --git a/models/issues/label.go b/models/issues/label.go index 5c6b8e08d72fc..3b811c1529a55 100644 --- a/models/issues/label.go +++ b/models/issues/label.go @@ -424,22 +424,6 @@ func GetLabelInOrgByID(ctx context.Context, orgID, labelID int64) (*Label, error return l, nil } -// GetLabelIDsInOrgByNames returns a list of labelIDs by names in a given -// organization. -func GetLabelIDsInOrgByNames(ctx context.Context, orgID int64, labelNames []string) ([]int64, error) { - if orgID <= 0 { - return nil, ErrOrgLabelNotExist{0, orgID} - } - labelIDs := make([]int64, 0, len(labelNames)) - - return labelIDs, db.GetEngine(ctx).Table("label"). - Where("org_id = ?", orgID). - In("name", labelNames). - Asc("name"). - Cols("id"). - Find(&labelIDs) -} - // GetLabelsInOrgByIDs returns a list of labels by IDs in given organization, // it silently ignores label IDs that do not belong to the organization. func GetLabelsInOrgByIDs(ctx context.Context, orgID int64, labelIDs []int64) ([]*Label, error) { diff --git a/models/issues/label_test.go b/models/issues/label_test.go index 3a8db6ceec5ab..517a3cf1abd40 100644 --- a/models/issues/label_test.go +++ b/models/issues/label_test.go @@ -164,30 +164,6 @@ func TestGetLabelInOrgByName(t *testing.T) { assert.True(t, issues_model.IsErrOrgLabelNotExist(err)) } -func TestGetLabelInOrgByNames(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - labelIDs, err := issues_model.GetLabelIDsInOrgByNames(db.DefaultContext, 3, []string{"orglabel3", "orglabel4"}) - assert.NoError(t, err) - - assert.Len(t, labelIDs, 2) - - assert.Equal(t, int64(3), labelIDs[0]) - assert.Equal(t, int64(4), labelIDs[1]) -} - -func TestGetLabelInOrgByNamesDiscardsNonExistentLabels(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - // orglabel99 doesn't exists.. See labels.yml - labelIDs, err := issues_model.GetLabelIDsInOrgByNames(db.DefaultContext, 3, []string{"orglabel3", "orglabel4", "orglabel99"}) - assert.NoError(t, err) - - assert.Len(t, labelIDs, 2) - - assert.Equal(t, int64(3), labelIDs[0]) - assert.Equal(t, int64(4), labelIDs[1]) - assert.NoError(t, err) -} - func TestGetLabelInOrgByID(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) label, err := issues_model.GetLabelInOrgByID(db.DefaultContext, 3, 3) diff --git a/models/issues/milestone_list.go b/models/issues/milestone_list.go index f331b2590faa4..a73bf73c17c9f 100644 --- a/models/issues/milestone_list.go +++ b/models/issues/milestone_list.go @@ -160,32 +160,6 @@ func (m MilestonesStats) Total() int64 { return m.OpenCount + m.ClosedCount } -// GetMilestonesStatsByRepoCond returns milestone statistic information for dashboard by given conditions. -func GetMilestonesStatsByRepoCond(ctx context.Context, repoCond builder.Cond) (*MilestonesStats, error) { - var err error - stats := &MilestonesStats{} - - sess := db.GetEngine(ctx).Where("is_closed = ?", false) - if repoCond.IsValid() { - sess.And(builder.In("repo_id", builder.Select("id").From("repository").Where(repoCond))) - } - stats.OpenCount, err = sess.Count(new(Milestone)) - if err != nil { - return nil, err - } - - sess = db.GetEngine(ctx).Where("is_closed = ?", true) - if repoCond.IsValid() { - sess.And(builder.In("repo_id", builder.Select("id").From("repository").Where(repoCond))) - } - stats.ClosedCount, err = sess.Count(new(Milestone)) - if err != nil { - return nil, err - } - - return stats, nil -} - // GetMilestonesStatsByRepoCondAndKw returns milestone statistic information for dashboard by given repo conditions and name keyword. func GetMilestonesStatsByRepoCondAndKw(ctx context.Context, repoCond builder.Cond, keyword string) (*MilestonesStats, error) { var err error diff --git a/models/issues/milestone_test.go b/models/issues/milestone_test.go index 0581d3d14881f..7477af92c8c49 100644 --- a/models/issues/milestone_test.go +++ b/models/issues/milestone_test.go @@ -17,7 +17,6 @@ import ( "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" - "xorm.io/builder" ) func TestMilestone_State(t *testing.T) { @@ -285,34 +284,6 @@ func TestGetMilestonesByRepoIDs(t *testing.T) { }) } -func TestGetMilestonesStats(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - test := func(repoID int64) { - repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}) - stats, err := issues_model.GetMilestonesStatsByRepoCond(db.DefaultContext, builder.And(builder.Eq{"repo_id": repoID})) - assert.NoError(t, err) - assert.EqualValues(t, repo.NumMilestones-repo.NumClosedMilestones, stats.OpenCount) - assert.EqualValues(t, repo.NumClosedMilestones, stats.ClosedCount) - } - test(1) - test(2) - test(3) - - stats, err := issues_model.GetMilestonesStatsByRepoCond(db.DefaultContext, builder.And(builder.Eq{"repo_id": unittest.NonexistentID})) - assert.NoError(t, err) - assert.EqualValues(t, 0, stats.OpenCount) - assert.EqualValues(t, 0, stats.ClosedCount) - - repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) - - milestoneStats, err := issues_model.GetMilestonesStatsByRepoCond(db.DefaultContext, builder.In("repo_id", []int64{repo1.ID, repo2.ID})) - assert.NoError(t, err) - assert.EqualValues(t, repo1.NumOpenMilestones+repo2.NumOpenMilestones, milestoneStats.OpenCount) - assert.EqualValues(t, repo1.NumClosedMilestones+repo2.NumClosedMilestones, milestoneStats.ClosedCount) -} - func TestNewMilestone(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) milestone := &issues_model.Milestone{ diff --git a/models/issues/pull.go b/models/issues/pull.go index c51a7daf4eca1..34bea921a0d26 100644 --- a/models/issues/pull.go +++ b/models/issues/pull.go @@ -78,24 +78,6 @@ func (err ErrPullRequestAlreadyExists) Unwrap() error { return util.ErrAlreadyExist } -// ErrPullRequestHeadRepoMissing represents a "ErrPullRequestHeadRepoMissing" error -type ErrPullRequestHeadRepoMissing struct { - ID int64 - HeadRepoID int64 -} - -// IsErrErrPullRequestHeadRepoMissing checks if an error is a ErrPullRequestHeadRepoMissing. -func IsErrErrPullRequestHeadRepoMissing(err error) bool { - _, ok := err.(ErrPullRequestHeadRepoMissing) - return ok -} - -// Error does pretty-printing :D -func (err ErrPullRequestHeadRepoMissing) Error() string { - return fmt.Sprintf("pull request head repo missing [id: %d, head_repo_id: %d]", - err.ID, err.HeadRepoID) -} - // ErrPullWasClosed is used close a closed pull request type ErrPullWasClosed struct { ID int64 @@ -758,18 +740,6 @@ func (pr *PullRequest) IsSameRepo() bool { return pr.BaseRepoID == pr.HeadRepoID } -// GetPullRequestsByHeadBranch returns all prs by head branch -// Since there could be multiple prs with the same head branch, this function returns a slice of prs -func GetPullRequestsByHeadBranch(ctx context.Context, headBranch string, headRepoID int64) ([]*PullRequest, error) { - log.Trace("GetPullRequestsByHeadBranch: headBranch: '%s', headRepoID: '%d'", headBranch, headRepoID) - prs := make([]*PullRequest, 0, 2) - if err := db.GetEngine(ctx).Where(builder.Eq{"head_branch": headBranch, "head_repo_id": headRepoID}). - Find(&prs); err != nil { - return nil, err - } - return prs, nil -} - // GetBaseBranchLink returns the relative URL of the base branch func (pr *PullRequest) GetBaseBranchLink(ctx context.Context) string { if err := pr.LoadBaseRepo(ctx); err != nil { diff --git a/models/issues/stopwatch.go b/models/issues/stopwatch.go index 2c662bdb06a80..fd9c7d7875524 100644 --- a/models/issues/stopwatch.go +++ b/models/issues/stopwatch.go @@ -29,20 +29,6 @@ func (err ErrIssueStopwatchNotExist) Unwrap() error { return util.ErrNotExist } -// ErrIssueStopwatchAlreadyExist represents an error that stopwatch is already exist -type ErrIssueStopwatchAlreadyExist struct { - UserID int64 - IssueID int64 -} - -func (err ErrIssueStopwatchAlreadyExist) Error() string { - return fmt.Sprintf("issue stopwatch already exists[uid: %d, issue_id: %d", err.UserID, err.IssueID) -} - -func (err ErrIssueStopwatchAlreadyExist) Unwrap() error { - return util.ErrAlreadyExist -} - // Stopwatch represents a stopwatch for time tracking. type Stopwatch struct { ID int64 `xorm:"pk autoincr"` diff --git a/services/issue/assignee_test.go b/services/issue/assignee_test.go index e16b012a1742d..da25da60ee176 100644 --- a/services/issue/assignee_test.go +++ b/services/issue/assignee_test.go @@ -18,8 +18,12 @@ func TestDeleteNotPassedAssignee(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // Fake issue with assignees - issue, err := issues_model.GetIssueWithAttrsByID(db.DefaultContext, 1) + issue, err := issues_model.GetIssueByID(db.DefaultContext, 1) assert.NoError(t, err) + + err = issue.LoadAttributes(db.DefaultContext) + assert.NoError(t, err) + assert.Len(t, issue.Assignees, 1) user1, err := user_model.GetUserByID(db.DefaultContext, 1) // This user is already assigned (see the definition in fixtures), so running UpdateAssignee should unassign him From 9483ccd463d31d465599eb4a0cc5621bc2caaf70 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Wed, 20 Dec 2023 00:20:44 +0000 Subject: [PATCH 49/60] [skip ci] Updated translations via Crowdin --- options/locale/locale_ja-JP.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index c2557b180e7ce..871a9d6809e73 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -91,6 +91,7 @@ remove=除去 remove_all=すべて除去 remove_label_str=アイテム「%s」を削除 edit=編集 +view=表示 enabled=有効 disabled=無効 @@ -3531,6 +3532,9 @@ runs.status=ステータス runs.actors_no_select=すべてのアクター runs.status_no_select=すべてのステータス runs.no_results=一致する結果はありません。 +runs.no_workflows=ワークフローはまだありません。 +runs.no_workflows.quick_start=Gitea Action の始め方がわからない? クイックスタートガイドをご覧ください。 +runs.no_workflows.documentation=Gitea Action の詳細については、ドキュメントを参照してください。 runs.no_runs=ワークフローはまだ実行されていません。 runs.empty_commit_message=(空のコミットメッセージ) From 577421691b5bca38b9116eb36efcfc9b1dfe2043 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 20 Dec 2023 19:54:34 +0800 Subject: [PATCH 50/60] Add missing head of lfs client batch (#28550) ref https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md#git-lfs-batch-api --- modules/lfs/http_client.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/lfs/http_client.go b/modules/lfs/http_client.go index de0b1e4fede49..4177473362387 100644 --- a/modules/lfs/http_client.go +++ b/modules/lfs/http_client.go @@ -79,7 +79,10 @@ func (c *HTTPClient) batch(ctx context.Context, operation string, objects []Poin return nil, err } - req, err := createRequest(ctx, http.MethodPost, url, map[string]string{"Content-Type": MediaType}, payload) + req, err := createRequest(ctx, http.MethodPost, url, map[string]string{ + "Content-Type": MediaType, + "Accept": MediaType, + }, payload) if err != nil { return nil, err } From e4a24d6727e70a8a7f4688d738c36db1f0fcbcc4 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 20 Dec 2023 22:11:59 +0800 Subject: [PATCH 51/60] Fix the issue ref rendering for wiki (#28556) Fix #28526, regression of * #26365 (although the author of #26365 has recent activities, but there is no response for the regression, so I proposed this quick fix and keep the fix simple to make it easier to backport to 1.21) --- modules/markup/html.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/markup/html.go b/modules/markup/html.go index 774cbe1557e44..03168b6946814 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -852,7 +852,9 @@ func fullIssuePatternProcessor(ctx *RenderContext, node *html.Node) { } func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) { - if ctx.Metas == nil || ctx.Metas["mode"] == "document" { + // FIXME: the use of "mode" is quite dirty and hacky, for example: what is a "document"? how should it be rendered? + // The "mode" approach should be refactored to some other more clear&reliable way. + if ctx.Metas == nil || (ctx.Metas["mode"] == "document" && !ctx.IsWiki) { return } var ( From 2c48733afea30a5e25fc1a6b3054f0ae907f990b Mon Sep 17 00:00:00 2001 From: 6543 Date: Wed, 20 Dec 2023 16:19:58 +0100 Subject: [PATCH 52/60] Fix inperformant query on retrifing review from database. (#28552) can we please PLEAS PLEASE only use raw SQL statements if it is relay needed!!! source is https://github.com/go-gitea/gitea/pull/28544 (before refactoring) --- models/issues/review.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/models/issues/review.go b/models/issues/review.go index 3db73a09ebcb7..e2f65e369f1cb 100644 --- a/models/issues/review.go +++ b/models/issues/review.go @@ -460,8 +460,10 @@ func SubmitReview(ctx context.Context, doer *user_model.User, issue *Issue, revi func GetReviewByIssueIDAndUserID(ctx context.Context, issueID, userID int64) (*Review, error) { review := new(Review) - has, err := db.GetEngine(ctx).SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_id = ? AND original_author_id = 0 AND type in (?, ?, ?))", - issueID, userID, ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest). + has, err := db.GetEngine(ctx).Where( + builder.In("type", ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest). + And(builder.Eq{"issue_id": issueID, "reviewer_id": userID, "original_author_id": 0})). + Desc("id"). Get(review) if err != nil { return nil, err @@ -475,13 +477,13 @@ func GetReviewByIssueIDAndUserID(ctx context.Context, issueID, userID int64) (*R } // GetTeamReviewerByIssueIDAndTeamID get the latest review request of reviewer team for a pull request -func GetTeamReviewerByIssueIDAndTeamID(ctx context.Context, issueID, teamID int64) (review *Review, err error) { - review = new(Review) +func GetTeamReviewerByIssueIDAndTeamID(ctx context.Context, issueID, teamID int64) (*Review, error) { + review := new(Review) - var has bool - if has, err = db.GetEngine(ctx).SQL("SELECT * FROM review WHERE id IN (SELECT max(id) as id FROM review WHERE issue_id = ? AND reviewer_team_id = ?)", - issueID, teamID). - Get(review); err != nil { + has, err := db.GetEngine(ctx).Where(builder.Eq{"issue_id": issueID, "reviewer_team_id": teamID}). + Desc("id"). + Get(review) + if err != nil { return nil, err } From 3d98d99e27dfbe86227b0557d04b5e4ea1c6e946 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 21 Dec 2023 04:12:25 +0800 Subject: [PATCH 53/60] Update actions document about comparsion as Github Actions (#28560) --- docs/content/usage/actions/comparison.en-us.md | 8 ++++++++ docs/content/usage/actions/comparison.zh-cn.md | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/docs/content/usage/actions/comparison.en-us.md b/docs/content/usage/actions/comparison.en-us.md index be40657bed70c..4d725f7a7e888 100644 --- a/docs/content/usage/actions/comparison.en-us.md +++ b/docs/content/usage/actions/comparison.en-us.md @@ -29,6 +29,10 @@ Like `uses: https://github.com/actions/checkout@v3` or `uses: http://your_gitea. Gitea Actions supports writing actions in Go. See [Creating Go Actions](https://blog.gitea.com/creating-go-actions/). +### Support the non-standard syntax @yearly, @monthly, @weekly, @daily, @hourly on schedule + +Github Actions doesn't support that. https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule + ## Unsupported workflows syntax ### `concurrency` @@ -110,6 +114,10 @@ It's ignored by Gitea Actions now. Pre and Post steps don't have their own section in the job log user interface. +### Services steps + +Services steps don't have their own section in the job log user interface. + ## Different behavior ### Downloading actions diff --git a/docs/content/usage/actions/comparison.zh-cn.md b/docs/content/usage/actions/comparison.zh-cn.md index 1ef7d3ca9892e..da3abfe01e988 100644 --- a/docs/content/usage/actions/comparison.zh-cn.md +++ b/docs/content/usage/actions/comparison.zh-cn.md @@ -29,6 +29,10 @@ Gitea Actions支持通过URL绝对路径定义actions,这意味着您可以使 Gitea Actions支持使用Go编写Actions。 请参阅[创建Go Actions](https://blog.gitea.com/creating-go-actions/)。 +### 支持非标准的调度语法 @yearly, @monthly, @weekly, @daily, @hourly + +Github Actions 不支持这些语法,详见: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule + ## 不支持的工作流语法 ### `concurrency` @@ -116,6 +120,10 @@ Gitea Actions目前不支持此功能。 预处理和后处理步骤在Job日志用户界面中没有自己的用户界面。 +### 服务步骤 + +服务步骤在Job日志用户界面中没有自己的用户界面。 + ## 不一样的行为 ### 下载Actions From caceb43313a586842e208249b2c67f90d4bf7139 Mon Sep 17 00:00:00 2001 From: Rui Chen Date: Thu, 21 Dec 2023 00:31:04 -0500 Subject: [PATCH 54/60] feat: bump `dessant/lock-threads` and `actions/setup-go` to use nodejs20 runtime (#28565) Update more actions to use nodejs20 runtime and also update the docs for checkout action usage. similar to: - #27836 - #27096 --------- Signed-off-by: Rui Chen --- .github/workflows/cron-licenses.yml | 2 +- .github/workflows/cron-lock.yml | 2 +- .github/workflows/pull-compliance.yml | 12 ++++++------ .github/workflows/pull-db-tests.yml | 10 +++++----- .github/workflows/pull-e2e-tests.yml | 2 +- .github/workflows/release-nightly.yml | 6 +++--- .github/workflows/release-tag-rc.yml | 2 +- .github/workflows/release-tag-version.yml | 2 +- .../administration/config-cheat-sheet.en-us.md | 6 +++--- .../administration/config-cheat-sheet.zh-cn.md | 6 +++--- docs/content/usage/actions/comparison.en-us.md | 6 +++--- docs/content/usage/actions/comparison.zh-cn.md | 8 ++++---- docs/content/usage/actions/design.en-us.md | 6 +++--- docs/content/usage/actions/design.zh-cn.md | 6 +++--- docs/content/usage/actions/faq.en-us.md | 4 ++-- docs/content/usage/actions/faq.zh-cn.md | 4 ++-- docs/content/usage/actions/overview.en-us.md | 2 +- docs/content/usage/actions/overview.zh-cn.md | 2 +- docs/content/usage/actions/quickstart.en-us.md | 2 +- docs/content/usage/actions/quickstart.zh-cn.md | 2 +- 20 files changed, 46 insertions(+), 46 deletions(-) diff --git a/.github/workflows/cron-licenses.yml b/.github/workflows/cron-licenses.yml index 6ef5813a64fc7..cd8386ecc5211 100644 --- a/.github/workflows/cron-licenses.yml +++ b/.github/workflows/cron-licenses.yml @@ -11,7 +11,7 @@ jobs: if: github.repository == 'go-gitea/gitea' steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true diff --git a/.github/workflows/cron-lock.yml b/.github/workflows/cron-lock.yml index 935f926cce9cd..746ec49bc63e8 100644 --- a/.github/workflows/cron-lock.yml +++ b/.github/workflows/cron-lock.yml @@ -17,6 +17,6 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'go-gitea/gitea' steps: - - uses: dessant/lock-threads@v4 + - uses: dessant/lock-threads@v5 with: issue-inactive-days: 45 diff --git a/.github/workflows/pull-compliance.yml b/.github/workflows/pull-compliance.yml index 6977dc32b2917..0472d9a9f07e8 100644 --- a/.github/workflows/pull-compliance.yml +++ b/.github/workflows/pull-compliance.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true @@ -70,7 +70,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true @@ -87,7 +87,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true @@ -102,7 +102,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true @@ -130,7 +130,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true @@ -175,7 +175,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true diff --git a/.github/workflows/pull-db-tests.yml b/.github/workflows/pull-db-tests.yml index 97446e6cd3b2f..a3886bf618075 100644 --- a/.github/workflows/pull-db-tests.yml +++ b/.github/workflows/pull-db-tests.yml @@ -39,7 +39,7 @@ jobs: - "9000:9000" steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true @@ -64,7 +64,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true @@ -115,7 +115,7 @@ jobs: - "9000:9000" steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true @@ -165,7 +165,7 @@ jobs: - "993:993" steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true @@ -198,7 +198,7 @@ jobs: - "1433:1433" steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true diff --git a/.github/workflows/pull-e2e-tests.yml b/.github/workflows/pull-e2e-tests.yml index 540263788d46a..5a249db9f8dd5 100644 --- a/.github/workflows/pull-e2e-tests.yml +++ b/.github/workflows/pull-e2e-tests.yml @@ -17,7 +17,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml index ef1e63df2ffc0..80e6683919fc7 100644 --- a/.github/workflows/release-nightly.yml +++ b/.github/workflows/release-nightly.yml @@ -18,7 +18,7 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true @@ -64,7 +64,7 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true @@ -101,7 +101,7 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true diff --git a/.github/workflows/release-tag-rc.yml b/.github/workflows/release-tag-rc.yml index d73d67aede761..12d1e1e4bebe7 100644 --- a/.github/workflows/release-tag-rc.yml +++ b/.github/workflows/release-tag-rc.yml @@ -17,7 +17,7 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true diff --git a/.github/workflows/release-tag-version.yml b/.github/workflows/release-tag-version.yml index 0379350900a9e..e0e93633e8abe 100644 --- a/.github/workflows/release-tag-version.yml +++ b/.github/workflows/release-tag-version.yml @@ -19,7 +19,7 @@ jobs: # fetch all commits instead of only the last as some branches are long lived and could have many between versions # fetch all tags to ensure that "git describe" reports expected Gitea version, eg. v1.21.0-dev-1-g1234567 - run: git fetch --unshallow --quiet --tags --force - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version-file: go.mod check-latest: true diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 93a19cec4e7bb..64c2fa475cf7d 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -1399,8 +1399,8 @@ PROXY_HOSTS = *.github.com - `SKIP_WORKFLOW_STRINGS`: **[skip ci],[ci skip],[no ci],[skip actions],[actions skip]**: Strings committers can place inside a commit message to skip executing the corresponding actions workflow `DEFAULT_ACTIONS_URL` indicates where the Gitea Actions runners should find the actions with relative path. -For example, `uses: actions/checkout@v3` means `https://github.com/actions/checkout@v3` since the value of `DEFAULT_ACTIONS_URL` is `github`. -And it can be changed to `self` to make it `root_url_of_your_gitea/actions/checkout@v3`. +For example, `uses: actions/checkout@v4` means `https://github.com/actions/checkout@v4` since the value of `DEFAULT_ACTIONS_URL` is `github`. +And it can be changed to `self` to make it `root_url_of_your_gitea/actions/checkout@v4`. Please note that using `self` is not recommended for most cases, as it could make names globally ambiguous. Additionally, it requires you to mirror all the actions you need to your Gitea instance, which may not be worth it. @@ -1409,7 +1409,7 @@ Therefore, please use `self` only if you understand what you are doing. In earlier versions (`<= 1.19`), `DEFAULT_ACTIONS_URL` could be set to any custom URLs like `https://gitea.com` or `http://your-git-server,https://gitea.com`, and the default value was `https://gitea.com`. However, later updates removed those options, and now the only options are `github` and `self`, with the default value being `github`. However, if you want to use actions from other git server, you can use a complete URL in `uses` field, it's supported by Gitea (but not GitHub). -Like `uses: https://gitea.com/actions/checkout@v3` or `uses: http://your-git-server/actions/checkout@v3`. +Like `uses: https://gitea.com/actions/checkout@v4` or `uses: http://your-git-server/actions/checkout@v4`. ## Other (`other`) diff --git a/docs/content/administration/config-cheat-sheet.zh-cn.md b/docs/content/administration/config-cheat-sheet.zh-cn.md index 596e82a12a0e1..befce0a1b71ab 100644 --- a/docs/content/administration/config-cheat-sheet.zh-cn.md +++ b/docs/content/administration/config-cheat-sheet.zh-cn.md @@ -1335,8 +1335,8 @@ PROXY_HOSTS = *.github.com - `MINIO_BASE_PATH`: **actions_log/**:Minio存储桶上的基本路径,仅在`STORAGE_TYPE`为`minio`时可用。 `DEFAULT_ACTIONS_URL` 指示 Gitea 操作运行程序应该在哪里找到带有相对路径的操作。 -例如,`uses: actions/checkout@v3` 表示 `https://github.com/actions/checkout@v3`,因为 `DEFAULT_ACTIONS_URL` 的值为 `github`。 -它可以更改为 `self`,以使其成为 `root_url_of_your_gitea/actions/checkout@v3`。 +例如,`uses: actions/checkout@v4` 表示 `https://github.com/actions/checkout@v4`,因为 `DEFAULT_ACTIONS_URL` 的值为 `github`。 +它可以更改为 `self`,以使其成为 `root_url_of_your_gitea/actions/checkout@v4`。 请注意,对于大多数情况,不建议使用 `self`,因为它可能使名称在全局范围内产生歧义。 此外,它要求您将所有所需的操作镜像到您的 Gitea 实例,这可能不值得。 @@ -1345,7 +1345,7 @@ PROXY_HOSTS = *.github.com 在早期版本(`<= 1.19`)中,`DEFAULT_ACTIONS_URL` 可以设置为任何自定义 URL,例如 `https://gitea.com` 或 `http://your-git-server,https://gitea.com`,默认值为 `https://gitea.com`。 然而,后来的更新删除了这些选项,现在唯一的选项是 `github` 和 `self`,默认值为 `github`。 但是,如果您想要使用其他 Git 服务器中的操作,您可以在 `uses` 字段中使用完整的 URL,Gitea 支持此功能(GitHub 不支持)。 -例如 `uses: https://gitea.com/actions/checkout@v3` 或 `uses: http://your-git-server/actions/checkout@v3`。 +例如 `uses: https://gitea.com/actions/checkout@v4` 或 `uses: http://your-git-server/actions/checkout@v4`。 ## 其他 (`other`) diff --git a/docs/content/usage/actions/comparison.en-us.md b/docs/content/usage/actions/comparison.en-us.md index 4d725f7a7e888..1ea3afac5bf48 100644 --- a/docs/content/usage/actions/comparison.en-us.md +++ b/docs/content/usage/actions/comparison.en-us.md @@ -22,7 +22,7 @@ Even though Gitea Actions is designed to be compatible with GitHub Actions, ther ### Absolute action URLs Gitea Actions supports defining actions via absolute URL, which means that you can use actions from any git repository. -Like `uses: https://github.com/actions/checkout@v3` or `uses: http://your_gitea.com/owner/repo@branch`. +Like `uses: https://github.com/actions/checkout@v4` or `uses: http://your_gitea.com/owner/repo@branch`. ### Actions written in Go @@ -125,9 +125,9 @@ Services steps don't have their own section in the job log user interface. Previously (Pre 1.21.0), `[actions].DEFAULT_ACTIONS_URL` defaulted to `https://gitea.com`. We have since restricted this option to only allow two values (`github` and `self`). When set to `github`, the new default, Gitea will download non-fully-qualified actions from `https://github.com`. -For example, if you use `uses: actions/checkout@v3`, it will download the checkout repository from `https://github.com/actions/checkout.git`. +For example, if you use `uses: actions/checkout@v4`, it will download the checkout repository from `https://github.com/actions/checkout.git`. -If you want to download an action from another git hoster, you can use an absolute URL, e.g. `uses: https://gitea.com/actions/checkout@v3`. +If you want to download an action from another git hoster, you can use an absolute URL, e.g. `uses: https://gitea.com/actions/checkout@v4`. If your Gitea instance is in an intranet or a restricted area, you can set the URL to `self` to only download actions from your own instance by default. Of course, you can still use absolute URLs in workflows. diff --git a/docs/content/usage/actions/comparison.zh-cn.md b/docs/content/usage/actions/comparison.zh-cn.md index da3abfe01e988..006fc8de3f537 100644 --- a/docs/content/usage/actions/comparison.zh-cn.md +++ b/docs/content/usage/actions/comparison.zh-cn.md @@ -22,7 +22,7 @@ menu: ### Action URL绝对路径 Gitea Actions支持通过URL绝对路径定义actions,这意味着您可以使用来自任何Git存储库的Actions。 -例如,`uses: https://github.com/actions/checkout@v3`或`uses: http://your_gitea.com/owner/repo@branch`。 +例如,`uses: https://github.com/actions/checkout@v4`或`uses: http://your_gitea.com/owner/repo@branch`。 ### 使用Go编写Actions @@ -129,10 +129,10 @@ Gitea Actions目前不支持此功能。 ### 下载Actions 当 `[actions].DEFAULT_ACTIONS_URL` 保持默认值为 `github` 时,Gitea将会从 https://github.com 下载相对路径的actions。比如: -如果你使用 `uses: actions/checkout@v3`,Gitea将会从 https://github.com/actions/checkout.git 下载这个 actions 项目。 -如果你想要从另外一个 Git服务下载actions,你只需要使用绝对URL `uses: https://gitea.com/actions/checkout@v3` 来下载。 +如果你使用 `uses: actions/checkout@v4`,Gitea将会从 https://github.com/actions/checkout.git 下载这个 actions 项目。 +如果你想要从另外一个 Git服务下载actions,你只需要使用绝对URL `uses: https://gitea.com/actions/checkout@v4` 来下载。 -如果你的 Gitea 实例是部署在一个互联网限制的网络中,有可以使用绝对地址来下载 actions。你也可以讲配置项修改为 `[actions].DEFAULT_ACTIONS_URL = self`。这样所有的相对路径的actions引用,将不再会从 github.com 去下载,而会从这个 Gitea 实例自己的仓库中去下载。例如: `uses: actions/checkout@v3` 将会从 `[server].ROOT_URL`/actions/checkout.git 这个地址去下载 actions。 +如果你的 Gitea 实例是部署在一个互联网限制的网络中,有可以使用绝对地址来下载 actions。你也可以讲配置项修改为 `[actions].DEFAULT_ACTIONS_URL = self`。这样所有的相对路径的actions引用,将不再会从 github.com 去下载,而会从这个 Gitea 实例自己的仓库中去下载。例如: `uses: actions/checkout@v4` 将会从 `[server].ROOT_URL`/actions/checkout.git 这个地址去下载 actions。 设置`[actions].DEFAULT_ACTIONS_URL`进行配置。请参阅[配置备忘单](administration/config-cheat-sheet.md#actions-actions)。 diff --git a/docs/content/usage/actions/design.en-us.md b/docs/content/usage/actions/design.en-us.md index 8394e822dc602..29fa433e59b59 100644 --- a/docs/content/usage/actions/design.en-us.md +++ b/docs/content/usage/actions/design.en-us.md @@ -95,7 +95,7 @@ The act runner must be able to connect to Gitea to receive tasks and send back t ### Connection 2, job containers to Gitea instance The job containers have different network namespaces than the runner, even if they are on the same machine. -They need to connect to Gitea to fetch codes if there is `actions/checkout@v3` in the workflow, for example. +They need to connect to Gitea to fetch codes if there is `actions/checkout@v4` in the workflow, for example. Fetching code is not always necessary to run some jobs, but it is required in most cases. If you use a loopback address to register a runner, the runner can connect to Gitea when it is on the same machine. @@ -103,7 +103,7 @@ However, if a job container tries to fetch code from localhost, it will fail bec ### Connection 3, act runner to internet -When you use some actions like `actions/checkout@v3`, the act runner downloads the scripts, not the job containers. +When you use some actions like `actions/checkout@v4`, the act runner downloads the scripts, not the job containers. By default, it downloads from [gitea.com](http://gitea.com/), so it requires access to the internet. It also downloads some docker images from Docker Hub by default, which also requires internet access. @@ -116,7 +116,7 @@ And [Gitea Container Registry](usage/packages/container.md) can be used as a Doc ### Connection 4, job containers to internet -When using actions such as `actions/setup-go@v4`, it may be necessary to download resources from the internet to set up the Go language environment in job containers. +When using actions such as `actions/setup-go@v5`, it may be necessary to download resources from the internet to set up the Go language environment in job containers. Therefore, access to the internet is required for the successful completion of these actions. However, it is optional as well. diff --git a/docs/content/usage/actions/design.zh-cn.md b/docs/content/usage/actions/design.zh-cn.md index 06f600f391525..8add1cf7c54a1 100644 --- a/docs/content/usage/actions/design.zh-cn.md +++ b/docs/content/usage/actions/design.zh-cn.md @@ -96,7 +96,7 @@ act runner 必须能够连接到Gitea以接收任务并发送执行结果回来 ### 连接 2,Job容器到Gitea实例 即使Job容器位于同一台机器上,它们的网络命名空间与Runner不同。 -举个例子,如果工作流中包含 `actions/checkout@v3`,Job容器需要连接到Gitea来获取代码。 +举个例子,如果工作流中包含 `actions/checkout@v4`,Job容器需要连接到Gitea来获取代码。 获取代码并不总是运行某些Job所必需的,但在大多数情况下是必需的。 如果您使用回环地址注册Runner,当Runner与Gitea在同一台机器上时,Runner可以连接到Gitea。 @@ -104,7 +104,7 @@ act runner 必须能够连接到Gitea以接收任务并发送执行结果回来 ### 连接 3,act runner到互联网 -当您使用诸如 `actions/checkout@v3` 的一些Actions时,act runner下载的是脚本,而不是Job容器。 +当您使用诸如 `actions/checkout@v4` 的一些Actions时,act runner下载的是脚本,而不是Job容器。 默认情况下,它从[gitea.com](http://gitea.com/)下载,因此需要访问互联网。 它还默认从Docker Hub下载一些Docker镜像,这也需要互联网访问。 @@ -117,7 +117,7 @@ act runner 必须能够连接到Gitea以接收任务并发送执行结果回来 ### 连接 4,Job容器到互联网 -当使用诸如`actions/setup-go@v4`的Actions时,可能需要从互联网下载资源,以设置Job容器中的Go语言环境。 +当使用诸如`actions/setup-go@v5`的Actions时,可能需要从互联网下载资源,以设置Job容器中的Go语言环境。 因此,成功完成这些Actions需要访问互联网。 然而,这也是可选的。 diff --git a/docs/content/usage/actions/faq.en-us.md b/docs/content/usage/actions/faq.en-us.md index 1d59872936a46..7ed59e02cdc0a 100644 --- a/docs/content/usage/actions/faq.en-us.md +++ b/docs/content/usage/actions/faq.en-us.md @@ -43,10 +43,10 @@ Still, this is completely optional since both options have the same effect at th Not yet. It is technically possible to implement, but we need to discuss whether it is necessary. -## Where will the runner download scripts when using actions such as `actions/checkout@v3`? +## Where will the runner download scripts when using actions such as `actions/checkout@v4`? You may be aware that there are tens of thousands of [marketplace actions](https://github.com/marketplace?type=actions) in GitHub. -However, when you write `uses: actions/checkout@v3`, it actually downloads the scripts from [gitea.com/actions/checkout](http://gitea.com/actions/checkout) by default (not GitHub). +However, when you write `uses: actions/checkout@v4`, it actually downloads the scripts from [gitea.com/actions/checkout](http://gitea.com/actions/checkout) by default (not GitHub). This is a mirror of [github.com/actions/checkout](http://github.com/actions/checkout), but it's impossible to mirror all of them. That's why you may encounter failures when trying to use some actions that haven't been mirrored. diff --git a/docs/content/usage/actions/faq.zh-cn.md b/docs/content/usage/actions/faq.zh-cn.md index 7bb79d02fc4a8..ba5f87bf0c4da 100644 --- a/docs/content/usage/actions/faq.zh-cn.md +++ b/docs/content/usage/actions/faq.zh-cn.md @@ -43,10 +43,10 @@ DEFAULT_REPO_UNITS = ...,repo.actions 目前还不可以。 从技术上讲是可以实现的,但我们需要讨论是否有必要。 -## 使用`actions/checkout@v3`等Actions时,Job容器会从何处下载脚本? +## 使用`actions/checkout@v4`等Actions时,Job容器会从何处下载脚本? 您可能知道GitHub上有成千上万个[Actions市场](https://github.com/marketplace?type=actions)。 -然而,当您编写`uses: actions/checkout@v3`时,它实际上默认从[gitea.com/actions/checkout](http://gitea.com/actions/checkout)下载脚本(而不是从GitHub下载)。 +然而,当您编写`uses: actions/checkout@v4`时,它实际上默认从[gitea.com/actions/checkout](http://gitea.com/actions/checkout)下载脚本(而不是从GitHub下载)。 这是[github.com/actions/checkout](http://github.com/actions/checkout)的镜像,但无法将它们全部镜像。 这就是为什么在尝试使用尚未镜像的某些Actions时可能会遇到失败的原因。 diff --git a/docs/content/usage/actions/overview.en-us.md b/docs/content/usage/actions/overview.en-us.md index 59e539f9c1ba6..135fdfd4337f3 100644 --- a/docs/content/usage/actions/overview.en-us.md +++ b/docs/content/usage/actions/overview.en-us.md @@ -25,7 +25,7 @@ To avoid confusion, we have clarified the spelling here: - "Gitea Actions" (with an "s", both words capitalized) is the name of the Gitea feature. - "GitHub Actions" is the name of the GitHub feature. - "Actions" could refer to either of the above, depending on the context. So it refers to "Gitea Actions" in this document. -- "action" or "actions" refer to some scripts/plugins to be used, like "actions/checkout@v3" or "actions/cache@v3". +- "action" or "actions" refer to some scripts/plugins to be used, like "actions/checkout@v4" or "actions/cache@v3". ## Runners diff --git a/docs/content/usage/actions/overview.zh-cn.md b/docs/content/usage/actions/overview.zh-cn.md index 0e57bf568f8b3..a2ec3070bcfe8 100644 --- a/docs/content/usage/actions/overview.zh-cn.md +++ b/docs/content/usage/actions/overview.zh-cn.md @@ -25,7 +25,7 @@ Gitea Actions与[GitHub Actions](https://github.com/features/actions)相似且 - "Gitea Actions"(两个单词都大写且带有"s")是Gitea功能的名称。 - "GitHub Actions"是GitHub功能的名称。 - "Actions"根据上下文的不同可以指代以上任意一个。在本文档中指代的是"Gitea Actions"。 -- "action"或"actions"指代一些要使用的脚本/插件,比如"actions/checkout@v3"或"actions/cache@v3"。 +- "action"或"actions"指代一些要使用的脚本/插件,比如"actions/checkout@v4"或"actions/cache@v3"。 ## Runner diff --git a/docs/content/usage/actions/quickstart.en-us.md b/docs/content/usage/actions/quickstart.en-us.md index f7f4ee2c3669a..2a2cf72584772 100644 --- a/docs/content/usage/actions/quickstart.en-us.md +++ b/docs/content/usage/actions/quickstart.en-us.md @@ -113,7 +113,7 @@ jobs: - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!" - run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}." - name: Check out repository code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner." - run: echo "🖥️ The workflow is now ready to test your code on the runner." - name: List files in the repository diff --git a/docs/content/usage/actions/quickstart.zh-cn.md b/docs/content/usage/actions/quickstart.zh-cn.md index ffc1f07df2576..8fccc6c909cde 100644 --- a/docs/content/usage/actions/quickstart.zh-cn.md +++ b/docs/content/usage/actions/quickstart.zh-cn.md @@ -112,7 +112,7 @@ jobs: - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!" - run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}." - name: Check out repository code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner." - run: echo "🖥️ The workflow is now ready to test your code on the runner." - name: List files in the repository From fe5a61639237138d6bb87cde17aedca3eb5bdd12 Mon Sep 17 00:00:00 2001 From: FuXiaoHei Date: Thu, 21 Dec 2023 15:04:50 +0800 Subject: [PATCH 55/60] Fix merging artifact chunks error when minio storage basepath is set (#28555) Related to https://github.com/go-gitea/gitea/issues/28279 When merging artifact chunks, it lists chunks from storage. When storage is minio, chunk's path contains `MINIO_BASE_PATH` that makes merging break. So trim the `MINIO_BASE_PATH` when handle chunks. Update the chunk file's basename to retain necessary information. It ensures that the directory in the chunk's path remains unaffected. --- routers/api/actions/artifacts_chunks.go | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/routers/api/actions/artifacts_chunks.go b/routers/api/actions/artifacts_chunks.go index c7ab70afa950e..36432a0ca084e 100644 --- a/routers/api/actions/artifacts_chunks.go +++ b/routers/api/actions/artifacts_chunks.go @@ -26,10 +26,11 @@ func saveUploadChunk(st storage.ObjectStorage, ctx *ArtifactContext, contentRange := ctx.Req.Header.Get("Content-Range") start, end, length := int64(0), int64(0), int64(0) if _, err := fmt.Sscanf(contentRange, "bytes %d-%d/%d", &start, &end, &length); err != nil { + log.Warn("parse content range error: %v, content-range: %s", err, contentRange) return -1, fmt.Errorf("parse content range error: %v", err) } // build chunk store path - storagePath := fmt.Sprintf("tmp%d/%d-%d-%d.chunk", runID, artifact.ID, start, end) + storagePath := fmt.Sprintf("tmp%d/%d-%d-%d-%d.chunk", runID, runID, artifact.ID, start, end) // use io.TeeReader to avoid reading all body to md5 sum. // it writes data to hasher after reading end // if hash is not matched, delete the read-end result @@ -58,6 +59,7 @@ func saveUploadChunk(st storage.ObjectStorage, ctx *ArtifactContext, } type chunkFileItem struct { + RunID int64 ArtifactID int64 Start int64 End int64 @@ -67,9 +69,12 @@ type chunkFileItem struct { func listChunksByRunID(st storage.ObjectStorage, runID int64) (map[int64][]*chunkFileItem, error) { storageDir := fmt.Sprintf("tmp%d", runID) var chunks []*chunkFileItem - if err := st.IterateObjects(storageDir, func(path string, obj storage.Object) error { - item := chunkFileItem{Path: path} - if _, err := fmt.Sscanf(path, filepath.Join(storageDir, "%d-%d-%d.chunk"), &item.ArtifactID, &item.Start, &item.End); err != nil { + if err := st.IterateObjects(storageDir, func(fpath string, obj storage.Object) error { + baseName := filepath.Base(fpath) + // when read chunks from storage, it only contains storage dir and basename, + // no matter the subdirectory setting in storage config + item := chunkFileItem{Path: storageDir + "/" + baseName} + if _, err := fmt.Sscanf(baseName, "%d-%d-%d-%d.chunk", &item.RunID, &item.ArtifactID, &item.Start, &item.End); err != nil { return fmt.Errorf("parse content range error: %v", err) } chunks = append(chunks, &item) From 177cea7c70473e375c1695f1e20fb9d538ff78fb Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 21 Dec 2023 15:42:16 +0800 Subject: [PATCH 56/60] Make offline mode as default to no connect external avatar service by default (#28548) To keep user's privacy, make offline mode as true by default. Users can still change it from installation ui and app.ini --- custom/conf/app.example.ini | 2 +- docs/content/administration/config-cheat-sheet.en-us.md | 2 +- docs/content/administration/config-cheat-sheet.zh-cn.md | 2 +- modules/repository/commits_test.go | 3 ++- modules/setting/server.go | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index f10a3f2edff37..f9111d541c738 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -234,7 +234,7 @@ RUN_USER = ; git ;MINIMUM_KEY_SIZE_CHECK = false ;; ;; Disable CDN even in "prod" mode -;OFFLINE_MODE = false +;OFFLINE_MODE = true ;; ;; TLS Settings: Either ACME or manual ;; (Other common TLS configuration are found before) diff --git a/docs/content/administration/config-cheat-sheet.en-us.md b/docs/content/administration/config-cheat-sheet.en-us.md index 64c2fa475cf7d..1ba5dd04cc406 100644 --- a/docs/content/administration/config-cheat-sheet.en-us.md +++ b/docs/content/administration/config-cheat-sheet.en-us.md @@ -357,7 +357,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `SSH_PER_WRITE_PER_KB_TIMEOUT`: **10s**: Timeout per Kb written to SSH connections. - `MINIMUM_KEY_SIZE_CHECK`: **true**: Indicate whether to check minimum key size with corresponding type. -- `OFFLINE_MODE`: **false**: Disables use of CDN for static files and Gravatar for profile pictures. +- `OFFLINE_MODE`: **true**: Disables use of CDN for static files and Gravatar for profile pictures. - `CERT_FILE`: **https/cert.pem**: Cert file path used for HTTPS. When chaining, the server certificate must come first, then intermediate CA certificates (if any). This is ignored if `ENABLE_ACME=true`. Paths are relative to `CUSTOM_PATH`. - `KEY_FILE`: **https/key.pem**: Key file path used for HTTPS. This is ignored if `ENABLE_ACME=true`. Paths are relative to `CUSTOM_PATH`. - `STATIC_ROOT_PATH`: **_`StaticRootPath`_**: Upper level of template and static files path. diff --git a/docs/content/administration/config-cheat-sheet.zh-cn.md b/docs/content/administration/config-cheat-sheet.zh-cn.md index befce0a1b71ab..434d69815b19e 100644 --- a/docs/content/administration/config-cheat-sheet.zh-cn.md +++ b/docs/content/administration/config-cheat-sheet.zh-cn.md @@ -346,7 +346,7 @@ menu: - `SSH_PER_WRITE_TIMEOUT`: **30s**:对 SSH 连接的任何写入设置超时。(将其设置为 -1 可以禁用所有超时。) - `SSH_PER_WRITE_PER_KB_TIMEOUT`: **10s**:对写入 SSH 连接的每 KB 设置超时。 - `MINIMUM_KEY_SIZE_CHECK`: **true**:指示是否检查最小密钥大小与相应类型。 -- `OFFLINE_MODE`: **false**:禁用 CDN 用于静态文件和 Gravatar 用于个人资料图片。 +- `OFFLINE_MODE`: **true**:禁用 CDN 用于静态文件和 Gravatar 用于个人资料图片。 - `CERT_FILE`: **https/cert.pem**:用于 HTTPS 的证书文件路径。在链接时,服务器证书必须首先出现,然后是中间 CA 证书(如果有)。如果 `ENABLE_ACME=true`,则此设置会被忽略。路径相对于 `CUSTOM_PATH`。 - `KEY_FILE`: **https/key.pem**:用于 HTTPS 的密钥文件路径。如果 `ENABLE_ACME=true`,则此设置会被忽略。路径相对于 `CUSTOM_PATH`。 - `STATIC_ROOT_PATH`: **_`StaticRootPath`_**:模板和静态文件路径的上一级。 diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go index 827b2a98493b0..248673a907d47 100644 --- a/modules/repository/commits_test.go +++ b/modules/repository/commits_test.go @@ -126,9 +126,10 @@ func TestPushCommits_AvatarLink(t *testing.T) { } setting.GravatarSource = "https://secure.gravatar.com/avatar" + setting.OfflineMode = true assert.Equal(t, - "https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?d=identicon&s="+strconv.Itoa(28*setting.Avatar.RenderedSizeFactor), + "/avatars/avatar2?size="+strconv.Itoa(28*setting.Avatar.RenderedSizeFactor), pushCommits.AvatarLink(db.DefaultContext, "user2@example.com")) assert.Equal(t, diff --git a/modules/setting/server.go b/modules/setting/server.go index d053fee5e76bb..80b85eeebdda7 100644 --- a/modules/setting/server.go +++ b/modules/setting/server.go @@ -315,7 +315,7 @@ func loadServerFrom(rootCfg ConfigProvider) { RedirectOtherPort = sec.Key("REDIRECT_OTHER_PORT").MustBool(false) PortToRedirect = sec.Key("PORT_TO_REDIRECT").MustString("80") RedirectorUseProxyProtocol = sec.Key("REDIRECTOR_USE_PROXY_PROTOCOL").MustBool(UseProxyProtocol) - OfflineMode = sec.Key("OFFLINE_MODE").MustBool() + OfflineMode = sec.Key("OFFLINE_MODE").MustBool(true) if len(StaticRootPath) == 0 { StaticRootPath = AppWorkPath } From 31426938928c89a9441dcf04b767db60c666e09a Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Thu, 21 Dec 2023 22:48:18 +0100 Subject: [PATCH 57/60] Use information from previous blame parts (#28572) Fixes #28545 `git blame` output can contain blocks without commit information if it was outputted before (the `0dafa97ea3f6d9662299579e5be1875cd28baaae 48 26 1` line): ``` fec25436488499df7231f63b857f66457c193d5c 24 25 1 author Bastien Montagne author-mail author-time 1660731031 author-tz +0200 committer Bastien Montagne committer-mail committer-time 1660731031 committer-tz +0200 summary LibOverride: Add Make/Reset/Clear entries to IDTemplate contextual menu. previous 839ece6477203382b7a7483062961540180ff1cd source/blender/editors/interface/interface_ops.c filename source/blender/editors/interface/interface_ops.c #include "BLT_translation.h" 0dafa97ea3f6d9662299579e5be1875cd28baaae 48 26 1 3d57bc4397fca53bc9702a27bbf50102827829b0 27 27 1 author Hans Goudey author-mail author-time 1700131315 author-tz +0100 committer Hans Goudey committer-mail committer-time 1700131315 committer-tz +0100 summary Cleanup: Move several blenkernel headers to C++ previous 451c054d9b7d3148a646caa5a72fb127a5b5c408 source/blender/editors/interface/interface_ops.cc filename source/blender/editors/interface/interface_ops.cc #include "BKE_context.hh" ``` This PR reuses data from the previous blame part to fill these gaps. --- routers/web/repo/blame.go | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go index b2374e32c2849..d414779a14ec7 100644 --- a/routers/web/repo/blame.go +++ b/routers/web/repo/blame.go @@ -125,7 +125,7 @@ func RefBlame(ctx *context.Context) { } type blameResult struct { - Parts []git.BlamePart + Parts []*git.BlamePart UsesIgnoreRevs bool FaultyIgnoreRevsFile bool } @@ -175,7 +175,9 @@ func performBlame(ctx *context.Context, repoPath string, commit *git.Commit, fil func fillBlameResult(br *git.BlameReader, r *blameResult) error { r.UsesIgnoreRevs = br.UsesIgnoreRevs() - r.Parts = make([]git.BlamePart, 0, 5) + previousHelper := make(map[string]*git.BlamePart) + + r.Parts = make([]*git.BlamePart, 0, 5) for { blamePart, err := br.NextPart() if err != nil { @@ -184,13 +186,23 @@ func fillBlameResult(br *git.BlameReader, r *blameResult) error { if blamePart == nil { break } - r.Parts = append(r.Parts, *blamePart) + + if prev, ok := previousHelper[blamePart.Sha]; ok { + if blamePart.PreviousSha == "" { + blamePart.PreviousSha = prev.PreviousSha + blamePart.PreviousPath = prev.PreviousPath + } + } else { + previousHelper[blamePart.Sha] = blamePart + } + + r.Parts = append(r.Parts, blamePart) } return nil } -func processBlameParts(ctx *context.Context, blameParts []git.BlamePart) map[string]*user_model.UserCommit { +func processBlameParts(ctx *context.Context, blameParts []*git.BlamePart) map[string]*user_model.UserCommit { // store commit data by SHA to look up avatar info etc commitNames := make(map[string]*user_model.UserCommit) // and as blameParts can reference the same commits multiple @@ -232,7 +244,7 @@ func processBlameParts(ctx *context.Context, blameParts []git.BlamePart) map[str return commitNames } -func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames map[string]*user_model.UserCommit) { +func renderBlame(ctx *context.Context, blameParts []*git.BlamePart, commitNames map[string]*user_model.UserCommit) { repoLink := ctx.Repo.RepoLink language := "" From b35d3fddfac389a7be401a63b4e1283dd74af681 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 22 Dec 2023 06:25:57 +0800 Subject: [PATCH 58/60] improve possible performance bottleneck (#28547) Replace #28500 --------- Co-authored-by: Giteabot --- models/issues/comment.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/models/issues/comment.go b/models/issues/comment.go index ba5aed9c652e9..ce5cf5902d776 100644 --- a/models/issues/comment.go +++ b/models/issues/comment.go @@ -1161,14 +1161,9 @@ func DeleteComment(ctx context.Context, comment *Comment) error { // UpdateCommentsMigrationsByType updates comments' migrations information via given git service type and original id and poster id func UpdateCommentsMigrationsByType(ctx context.Context, tp structs.GitServiceType, originalAuthorID string, posterID int64) error { _, err := db.GetEngine(ctx).Table("comment"). - Where(builder.In("issue_id", - builder.Select("issue.id"). - From("issue"). - InnerJoin("repository", "issue.repo_id = repository.id"). - Where(builder.Eq{ - "repository.original_service_type": tp, - }), - )). + Join("INNER", "issue", "issue.id = comment.issue_id"). + Join("INNER", "repository", "issue.repo_id = repository.id"). + Where("repository.original_service_type = ?", tp). And("comment.original_author_id = ?", originalAuthorID). Update(map[string]any{ "poster_id": posterID, From 04b235d094218b780b62f024b7ae9716ad2e633f Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 22 Dec 2023 07:09:14 +0800 Subject: [PATCH 59/60] Fix 500 error of searching commits (#28576) Regression of #28454 . Now the string is escaped HTML, so it doesn't need `| Safe`. Fix #28575 --- templates/code/searchresults.tmpl | 2 +- templates/repo/search.tmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/code/searchresults.tmpl b/templates/code/searchresults.tmpl index 28c33a26de92a..bb21a5e0dcadf 100644 --- a/templates/code/searchresults.tmpl +++ b/templates/code/searchresults.tmpl @@ -31,7 +31,7 @@ {{.}} {{end}} - {{.FormattedLines | Safe}} + {{.FormattedLines}} diff --git a/templates/repo/search.tmpl b/templates/repo/search.tmpl index b6c90de32f63c..b616b4de32312 100644 --- a/templates/repo/search.tmpl +++ b/templates/repo/search.tmpl @@ -53,7 +53,7 @@ {{.}} {{end}} - {{.FormattedLines | Safe}} + {{.FormattedLines}} From 838db2f8911690fa2115c6827ed73687db71bef1 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Fri, 22 Dec 2023 00:59:59 +0100 Subject: [PATCH 60/60] Convert to url auth to header auth in tests (#28484) Related #28390 --- .../integration/api_actions_artifact_test.go | 89 ++++---- .../api_activitypub_person_test.go | 4 +- tests/integration/api_admin_org_test.go | 9 +- tests/integration/api_admin_test.go | 89 ++++---- tests/integration/api_branch_test.go | 23 +- .../api_comment_attachment_test.go | 31 +-- tests/integration/api_comment_test.go | 36 +-- tests/integration/api_gpg_keys_test.go | 36 +-- .../api_helper_for_declarative_test.go | 108 ++++----- tests/integration/api_httpsig_test.go | 14 +- .../integration/api_issue_attachment_test.go | 26 +-- tests/integration/api_issue_label_test.go | 58 ++--- tests/integration/api_issue_milestone_test.go | 23 +- tests/integration/api_issue_pin_test.go | 62 ++---- tests/integration/api_issue_reaction_test.go | 34 +-- tests/integration/api_issue_stopwatch_test.go | 12 +- .../api_issue_subscription_test.go | 20 +- tests/integration/api_issue_test.go | 12 +- .../api_issue_tracked_time_test.go | 19 +- tests/integration/api_keys_test.go | 54 ++--- tests/integration/api_nodeinfo_test.go | 2 +- tests/integration/api_notification_test.go | 45 ++-- tests/integration/api_oauth2_apps_test.go | 24 +- tests/integration/api_org_avatar_test.go | 12 +- tests/integration/api_org_test.go | 34 +-- tests/integration/api_packages_alpine_test.go | 12 +- tests/integration/api_packages_cargo_test.go | 36 +-- tests/integration/api_packages_chef_test.go | 83 +++---- .../integration/api_packages_composer_test.go | 32 +-- tests/integration/api_packages_conan_test.go | 112 +++++----- tests/integration/api_packages_conda_test.go | 16 +- .../api_packages_container_test.go | 210 +++++++++--------- tests/integration/api_packages_cran_test.go | 45 ++-- tests/integration/api_packages_debian_test.go | 28 +-- .../integration/api_packages_generic_test.go | 48 ++-- .../integration/api_packages_goproxy_test.go | 16 +- tests/integration/api_packages_helm_test.go | 16 +- tests/integration/api_packages_maven_test.go | 36 +-- tests/integration/api_packages_npm_test.go | 56 ++--- tests/integration/api_packages_nuget_test.go | 137 ++++++------ tests/integration/api_packages_pub_test.go | 14 +- tests/integration/api_packages_pypi_test.go | 14 +- tests/integration/api_packages_rpm_test.go | 16 +- .../integration/api_packages_rubygems_test.go | 22 +- tests/integration/api_packages_swift_test.go | 70 +++--- tests/integration/api_packages_test.go | 65 +++--- .../integration/api_packages_vagrant_test.go | 12 +- tests/integration/api_pull_review_test.go | 95 ++++---- tests/integration/api_pull_test.go | 34 +-- tests/integration/api_releases_test.go | 47 ++-- tests/integration/api_repo_avatar_test.go | 12 +- .../integration/api_repo_collaborator_test.go | 24 +- tests/integration/api_repo_edit_test.go | 79 ++++--- .../integration/api_repo_file_create_test.go | 42 ++-- .../integration/api_repo_file_delete_test.go | 38 ++-- .../integration/api_repo_file_update_test.go | 42 ++-- .../integration/api_repo_files_change_test.go | 40 ++-- .../api_repo_get_contents_list_test.go | 9 +- .../integration/api_repo_get_contents_test.go | 9 +- tests/integration/api_repo_git_blobs_test.go | 9 +- .../integration/api_repo_git_commits_test.go | 39 ++-- tests/integration/api_repo_git_hook_test.go | 47 ++-- tests/integration/api_repo_git_notes_test.go | 9 +- tests/integration/api_repo_git_ref_test.go | 9 +- tests/integration/api_repo_git_tags_test.go | 17 +- tests/integration/api_repo_git_trees_test.go | 6 +- tests/integration/api_repo_hook_test.go | 7 +- .../integration/api_repo_lfs_migrate_test.go | 4 +- tests/integration/api_repo_lfs_test.go | 23 +- tests/integration/api_repo_raw_test.go | 6 +- tests/integration/api_repo_secrets_test.go | 23 +- tests/integration/api_repo_tags_test.go | 13 +- tests/integration/api_repo_teams_test.go | 24 +- tests/integration/api_repo_test.go | 82 ++++--- tests/integration/api_repo_topic_test.go | 51 +++-- tests/integration/api_team_test.go | 54 +++-- tests/integration/api_team_user_test.go | 6 +- tests/integration/api_token_test.go | 46 ++-- tests/integration/api_twofa_test.go | 12 +- tests/integration/api_user_avatar_test.go | 12 +- tests/integration/api_user_email_test.go | 21 +- tests/integration/api_user_follow_test.go | 30 ++- tests/integration/api_user_heatmap_test.go | 4 +- tests/integration/api_user_info_test.go | 9 +- tests/integration/api_user_org_perm_test.go | 9 +- tests/integration/api_user_orgs_test.go | 7 +- tests/integration/api_user_search_test.go | 7 +- tests/integration/api_user_secrets_test.go | 23 +- tests/integration/api_user_star_test.go | 18 +- tests/integration/api_user_watch_test.go | 18 +- tests/integration/api_wiki_test.go | 8 +- tests/integration/cors_test.go | 2 +- tests/integration/empty_repo_test.go | 9 +- tests/integration/eventsource_test.go | 9 +- tests/integration/integration_test.go | 81 ++++--- tests/integration/org_test.go | 8 +- tests/integration/privateactivity_test.go | 7 +- tests/integration/pull_merge_test.go | 8 +- tests/integration/pull_status_test.go | 6 +- tests/integration/pull_update_test.go | 6 +- tests/integration/repo_search_test.go | 2 +- tests/integration/user_test.go | 2 +- 102 files changed, 1714 insertions(+), 1522 deletions(-) diff --git a/tests/integration/api_actions_artifact_test.go b/tests/integration/api_actions_artifact_test.go index 101bedde02788..2597d103746e6 100644 --- a/tests/integration/api_actions_artifact_test.go +++ b/tests/integration/api_actions_artifact_test.go @@ -30,8 +30,7 @@ func TestActionsArtifactUploadSingleFile(t *testing.T) { req := NewRequestWithJSON(t, "POST", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts", getUploadArtifactRequest{ Type: "actions_storage", Name: "artifact", - }) - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + }).AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") resp := MakeRequest(t, req, http.StatusOK) var uploadResp uploadArtifactResponse DecodeJSON(t, resp, &uploadResp) @@ -43,18 +42,18 @@ func TestActionsArtifactUploadSingleFile(t *testing.T) { // upload artifact chunk body := strings.Repeat("A", 1024) - req = NewRequestWithBody(t, "PUT", url, strings.NewReader(body)) - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") - req.Header.Add("Content-Range", "bytes 0-1023/1024") - req.Header.Add("x-tfs-filelength", "1024") - req.Header.Add("x-actions-results-md5", "1HsSe8LeLWh93ILaw1TEFQ==") // base64(md5(body)) + req = NewRequestWithBody(t, "PUT", url, strings.NewReader(body)). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a"). + SetHeader("Content-Range", "bytes 0-1023/1024"). + SetHeader("x-tfs-filelength", "1024"). + SetHeader("x-actions-results-md5", "1HsSe8LeLWh93ILaw1TEFQ==") // base64(md5(body)) MakeRequest(t, req, http.StatusOK) t.Logf("Create artifact confirm") // confirm artifact upload - req = NewRequest(t, "PATCH", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts?artifactName=artifact") - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + req = NewRequest(t, "PATCH", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts?artifactName=artifact"). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") MakeRequest(t, req, http.StatusOK) } @@ -64,11 +63,11 @@ func TestActionsArtifactUploadInvalidHash(t *testing.T) { // artifact id 54321 not exist url := "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts/8e5b948a454515dbabfc7eb718ddddddd/upload?itemPath=artifact/abc.txt" body := strings.Repeat("A", 1024) - req := NewRequestWithBody(t, "PUT", url, strings.NewReader(body)) - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") - req.Header.Add("Content-Range", "bytes 0-1023/1024") - req.Header.Add("x-tfs-filelength", "1024") - req.Header.Add("x-actions-results-md5", "1HsSe8LeLWh93ILaw1TEFQ==") // base64(md5(body)) + req := NewRequestWithBody(t, "PUT", url, strings.NewReader(body)). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a"). + SetHeader("Content-Range", "bytes 0-1023/1024"). + SetHeader("x-tfs-filelength", "1024"). + SetHeader("x-actions-results-md5", "1HsSe8LeLWh93ILaw1TEFQ==") // base64(md5(body)) resp := MakeRequest(t, req, http.StatusBadRequest) assert.Contains(t, resp.Body.String(), "Invalid artifact hash") } @@ -76,8 +75,8 @@ func TestActionsArtifactUploadInvalidHash(t *testing.T) { func TestActionsArtifactConfirmUploadWithoutName(t *testing.T) { defer tests.PrepareTestEnv(t)() - req := NewRequest(t, "PATCH", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts") - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + req := NewRequest(t, "PATCH", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts"). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") resp := MakeRequest(t, req, http.StatusBadRequest) assert.Contains(t, resp.Body.String(), "artifact name is empty") } @@ -111,8 +110,8 @@ type ( func TestActionsArtifactDownload(t *testing.T) { defer tests.PrepareTestEnv(t)() - req := NewRequest(t, "GET", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts") - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + req := NewRequest(t, "GET", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts"). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") resp := MakeRequest(t, req, http.StatusOK) var listResp listArtifactsResponse DecodeJSON(t, resp, &listResp) @@ -122,8 +121,8 @@ func TestActionsArtifactDownload(t *testing.T) { idx := strings.Index(listResp.Value[0].FileContainerResourceURL, "/api/actions_pipeline/_apis/pipelines/") url := listResp.Value[0].FileContainerResourceURL[idx+1:] + "?itemPath=artifact" - req = NewRequest(t, "GET", url) - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + req = NewRequest(t, "GET", url). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") resp = MakeRequest(t, req, http.StatusOK) var downloadResp downloadArtifactResponse DecodeJSON(t, resp, &downloadResp) @@ -134,8 +133,8 @@ func TestActionsArtifactDownload(t *testing.T) { idx = strings.Index(downloadResp.Value[0].ContentLocation, "/api/actions_pipeline/_apis/pipelines/") url = downloadResp.Value[0].ContentLocation[idx:] - req = NewRequest(t, "GET", url) - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + req = NewRequest(t, "GET", url). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") resp = MakeRequest(t, req, http.StatusOK) body := strings.Repeat("A", 1024) assert.Equal(t, resp.Body.String(), body) @@ -150,8 +149,7 @@ func TestActionsArtifactUploadMultipleFile(t *testing.T) { req := NewRequestWithJSON(t, "POST", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts", getUploadArtifactRequest{ Type: "actions_storage", Name: testArtifactName, - }) - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + }).AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") resp := MakeRequest(t, req, http.StatusOK) var uploadResp uploadArtifactResponse DecodeJSON(t, resp, &uploadResp) @@ -182,19 +180,19 @@ func TestActionsArtifactUploadMultipleFile(t *testing.T) { url := uploadResp.FileContainerResourceURL[idx:] + "?itemPath=" + testArtifactName + "/" + f.Path // upload artifact chunk - req = NewRequestWithBody(t, "PUT", url, strings.NewReader(f.Content)) - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") - req.Header.Add("Content-Range", "bytes 0-1023/1024") - req.Header.Add("x-tfs-filelength", "1024") - req.Header.Add("x-actions-results-md5", f.MD5) // base64(md5(body)) + req = NewRequestWithBody(t, "PUT", url, strings.NewReader(f.Content)). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a"). + SetHeader("Content-Range", "bytes 0-1023/1024"). + SetHeader("x-tfs-filelength", "1024"). + SetHeader("x-actions-results-md5", f.MD5) // base64(md5(body)) MakeRequest(t, req, http.StatusOK) } t.Logf("Create artifact confirm") // confirm artifact upload - req = NewRequest(t, "PATCH", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts?artifactName="+testArtifactName) - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + req = NewRequest(t, "PATCH", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts?artifactName="+testArtifactName). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") MakeRequest(t, req, http.StatusOK) } @@ -203,8 +201,8 @@ func TestActionsArtifactDownloadMultiFiles(t *testing.T) { const testArtifactName = "multi-files" - req := NewRequest(t, "GET", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts") - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + req := NewRequest(t, "GET", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts"). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") resp := MakeRequest(t, req, http.StatusOK) var listResp listArtifactsResponse DecodeJSON(t, resp, &listResp) @@ -221,8 +219,8 @@ func TestActionsArtifactDownloadMultiFiles(t *testing.T) { idx := strings.Index(fileContainerResourceURL, "/api/actions_pipeline/_apis/pipelines/") url := fileContainerResourceURL[idx+1:] + "?itemPath=" + testArtifactName - req = NewRequest(t, "GET", url) - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + req = NewRequest(t, "GET", url). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") resp = MakeRequest(t, req, http.StatusOK) var downloadResp downloadArtifactResponse DecodeJSON(t, resp, &downloadResp) @@ -246,8 +244,8 @@ func TestActionsArtifactDownloadMultiFiles(t *testing.T) { idx = strings.Index(value.ContentLocation, "/api/actions_pipeline/_apis/pipelines/") url = value.ContentLocation[idx:] - req = NewRequest(t, "GET", url) - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + req = NewRequest(t, "GET", url). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") resp = MakeRequest(t, req, http.StatusOK) body := strings.Repeat(bodyChar, 1024) assert.Equal(t, resp.Body.String(), body) @@ -262,8 +260,7 @@ func TestActionsArtifactUploadWithRetentionDays(t *testing.T) { Type: "actions_storage", Name: "artifact-retention-days", RetentionDays: 9, - }) - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + }).AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") resp := MakeRequest(t, req, http.StatusOK) var uploadResp uploadArtifactResponse DecodeJSON(t, resp, &uploadResp) @@ -276,17 +273,17 @@ func TestActionsArtifactUploadWithRetentionDays(t *testing.T) { // upload artifact chunk body := strings.Repeat("A", 1024) - req = NewRequestWithBody(t, "PUT", url, strings.NewReader(body)) - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") - req.Header.Add("Content-Range", "bytes 0-1023/1024") - req.Header.Add("x-tfs-filelength", "1024") - req.Header.Add("x-actions-results-md5", "1HsSe8LeLWh93ILaw1TEFQ==") // base64(md5(body)) + req = NewRequestWithBody(t, "PUT", url, strings.NewReader(body)). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a"). + SetHeader("Content-Range", "bytes 0-1023/1024"). + SetHeader("x-tfs-filelength", "1024"). + SetHeader("x-actions-results-md5", "1HsSe8LeLWh93ILaw1TEFQ==") // base64(md5(body)) MakeRequest(t, req, http.StatusOK) t.Logf("Create artifact confirm") // confirm artifact upload - req = NewRequest(t, "PATCH", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts?artifactName=artifact-retention-days") - req = addTokenAuthHeader(req, "Bearer 8061e833a55f6fc0157c98b883e91fcfeeb1a71a") + req = NewRequest(t, "PATCH", "/api/actions_pipeline/_apis/pipelines/workflows/791/artifacts?artifactName=artifact-retention-days"). + AddTokenAuth("8061e833a55f6fc0157c98b883e91fcfeeb1a71a") MakeRequest(t, req, http.StatusOK) } diff --git a/tests/integration/api_activitypub_person_test.go b/tests/integration/api_activitypub_person_test.go index 3222dfc807134..42a2a09072761 100644 --- a/tests/integration/api_activitypub_person_test.go +++ b/tests/integration/api_activitypub_person_test.go @@ -32,7 +32,7 @@ func TestActivityPubPerson(t *testing.T) { onGiteaRun(t, func(*testing.T, *url.URL) { userID := 2 username := "user2" - req := NewRequestf(t, "GET", fmt.Sprintf("/api/v1/activitypub/user-id/%v", userID)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/activitypub/user-id/%v", userID)) resp := MakeRequest(t, req, http.StatusOK) body := resp.Body.Bytes() assert.Contains(t, string(body), "@context") @@ -68,7 +68,7 @@ func TestActivityPubMissingPerson(t *testing.T) { }() onGiteaRun(t, func(*testing.T, *url.URL) { - req := NewRequestf(t, "GET", "/api/v1/activitypub/user-id/999999999") + req := NewRequest(t, "GET", "/api/v1/activitypub/user-id/999999999") resp := MakeRequest(t, req, http.StatusNotFound) assert.Contains(t, resp.Body.String(), "user does not exist") }) diff --git a/tests/integration/api_admin_org_test.go b/tests/integration/api_admin_org_test.go index 0bf4b1f7cba03..a29d0ba1d7467 100644 --- a/tests/integration/api_admin_org_test.go +++ b/tests/integration/api_admin_org_test.go @@ -31,7 +31,8 @@ func TestAPIAdminOrgCreate(t *testing.T) { Location: "Shanghai", Visibility: "private", } - req := NewRequestWithJSON(t, "POST", "/api/v1/admin/users/user2/orgs?token="+token, &org) + req := NewRequestWithJSON(t, "POST", "/api/v1/admin/users/user2/orgs", &org). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var apiOrg api.Organization @@ -65,7 +66,8 @@ func TestAPIAdminOrgCreateBadVisibility(t *testing.T) { Location: "Shanghai", Visibility: "notvalid", } - req := NewRequestWithJSON(t, "POST", "/api/v1/admin/users/user2/orgs?token="+token, &org) + req := NewRequestWithJSON(t, "POST", "/api/v1/admin/users/user2/orgs", &org). + AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) }) } @@ -83,6 +85,7 @@ func TestAPIAdminOrgCreateNotAdmin(t *testing.T) { Location: "Shanghai", Visibility: "public", } - req := NewRequestWithJSON(t, "POST", "/api/v1/admin/users/user2/orgs?token="+token, &org) + req := NewRequestWithJSON(t, "POST", "/api/v1/admin/users/user2/orgs", &org). + AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) } diff --git a/tests/integration/api_admin_test.go b/tests/integration/api_admin_test.go index aae9ec4a24a2d..ff7c2ddca39b7 100644 --- a/tests/integration/api_admin_test.go +++ b/tests/integration/api_admin_test.go @@ -27,11 +27,11 @@ func TestAPIAdminCreateAndDeleteSSHKey(t *testing.T) { keyOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"}) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin) - urlStr := fmt.Sprintf("/api/v1/admin/users/%s/keys?token=%s", keyOwner.Name, token) + urlStr := fmt.Sprintf("/api/v1/admin/users/%s/keys", keyOwner.Name) req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n", "title": "test-key", - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var newPublicKey api.PublicKey @@ -43,8 +43,8 @@ func TestAPIAdminCreateAndDeleteSSHKey(t *testing.T) { OwnerID: keyOwner.ID, }) - req = NewRequestf(t, "DELETE", "/api/v1/admin/users/%s/keys/%d?token=%s", - keyOwner.Name, newPublicKey.ID, token) + req = NewRequestf(t, "DELETE", "/api/v1/admin/users/%s/keys/%d", keyOwner.Name, newPublicKey.ID). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) unittest.AssertNotExistsBean(t, &asymkey_model.PublicKey{ID: newPublicKey.ID}) } @@ -54,7 +54,8 @@ func TestAPIAdminDeleteMissingSSHKey(t *testing.T) { // user1 is an admin user token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteAdmin) - req := NewRequestf(t, "DELETE", "/api/v1/admin/users/user1/keys/%d?token=%s", unittest.NonexistentID, token) + req := NewRequestf(t, "DELETE", "/api/v1/admin/users/user1/keys/%d", unittest.NonexistentID). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) } @@ -64,18 +65,18 @@ func TestAPIAdminDeleteUnauthorizedKey(t *testing.T) { normalUsername := "user2" token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) - urlStr := fmt.Sprintf("/api/v1/admin/users/%s/keys?token=%s", adminUsername, token) + urlStr := fmt.Sprintf("/api/v1/admin/users/%s/keys", adminUsername) req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n", "title": "test-key", - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var newPublicKey api.PublicKey DecodeJSON(t, resp, &newPublicKey) token = getUserToken(t, normalUsername) - req = NewRequestf(t, "DELETE", "/api/v1/admin/users/%s/keys/%d?token=%s", - adminUsername, newPublicKey.ID, token) + req = NewRequestf(t, "DELETE", "/api/v1/admin/users/%s/keys/%d", adminUsername, newPublicKey.ID). + AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) } @@ -85,8 +86,8 @@ func TestAPISudoUser(t *testing.T) { normalUsername := "user2" token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeReadUser) - urlStr := fmt.Sprintf("/api/v1/user?sudo=%s&token=%s", normalUsername, token) - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user?sudo=%s", normalUsername)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var user api.User DecodeJSON(t, resp, &user) @@ -100,8 +101,8 @@ func TestAPISudoUserForbidden(t *testing.T) { normalUsername := "user2" token := getUserToken(t, normalUsername, auth_model.AccessTokenScopeReadAdmin) - urlStr := fmt.Sprintf("/api/v1/user?sudo=%s&token=%s", adminUsername, token) - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user?sudo=%s", adminUsername)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) } @@ -110,8 +111,8 @@ func TestAPIListUsers(t *testing.T) { adminUsername := "user1" token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeReadAdmin) - urlStr := fmt.Sprintf("/api/v1/admin/users?token=%s", token) - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", "/api/v1/admin/users"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var users []api.User DecodeJSON(t, resp, &users) @@ -137,7 +138,8 @@ func TestAPIListUsersNonAdmin(t *testing.T) { defer tests.PrepareTestEnv(t)() nonAdminUsername := "user2" token := getUserToken(t, nonAdminUsername) - req := NewRequestf(t, "GET", "/api/v1/admin/users?token=%s", token) + req := NewRequest(t, "GET", "/api/v1/admin/users"). + AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) } @@ -145,8 +147,7 @@ func TestAPICreateUserInvalidEmail(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) - urlStr := fmt.Sprintf("/api/v1/admin/users?token=%s", token) - req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ + req := NewRequestWithValues(t, "POST", "/api/v1/admin/users", map[string]string{ "email": "invalid_email@domain.com\r\n", "full_name": "invalid user", "login_name": "invalidUser", @@ -155,7 +156,7 @@ func TestAPICreateUserInvalidEmail(t *testing.T) { "send_notify": "true", "source_id": "0", "username": "invalidUser", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) } @@ -167,7 +168,7 @@ func TestAPICreateAndDeleteUser(t *testing.T) { req := NewRequestWithValues( t, "POST", - fmt.Sprintf("/api/v1/admin/users?token=%s", token), + "/api/v1/admin/users", map[string]string{ "email": "deleteme@domain.com", "full_name": "delete me", @@ -178,10 +179,11 @@ func TestAPICreateAndDeleteUser(t *testing.T) { "source_id": "0", "username": "deleteme", }, - ) + ).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) - req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/admin/users/deleteme?token=%s", token)) + req = NewRequest(t, "DELETE", "/api/v1/admin/users/deleteme"). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) } @@ -189,7 +191,7 @@ func TestAPIEditUser(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) - urlStr := fmt.Sprintf("/api/v1/admin/users/%s?token=%s", "user2", token) + urlStr := fmt.Sprintf("/api/v1/admin/users/%s", "user2") req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{ // required @@ -197,7 +199,7 @@ func TestAPIEditUser(t *testing.T) { "source_id": "0", // to change "full_name": "Full Name User 2", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) empty := "" @@ -205,7 +207,7 @@ func TestAPIEditUser(t *testing.T) { LoginName: "user2", SourceID: 0, Email: &empty, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusUnprocessableEntity) errMap := make(map[string]any) @@ -221,7 +223,7 @@ func TestAPIEditUser(t *testing.T) { SourceID: 0, // to change Restricted: &bTrue, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"}) assert.True(t, user2.IsRestricted) @@ -235,11 +237,11 @@ func TestAPICreateRepoForUser(t *testing.T) { req := NewRequestWithJSON( t, "POST", - fmt.Sprintf("/api/v1/admin/users/%s/repos?token=%s", adminUsername, token), + fmt.Sprintf("/api/v1/admin/users/%s/repos", adminUsername), &api.CreateRepoOption{ Name: "admincreatedrepo", }, - ) + ).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) } @@ -247,40 +249,38 @@ func TestAPIRenameUser(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) - urlStr := fmt.Sprintf("/api/v1/admin/users/%s/rename?token=%s", "user2", token) + urlStr := fmt.Sprintf("/api/v1/admin/users/%s/rename", "user2") req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ // required "new_name": "User2", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) - urlStr = fmt.Sprintf("/api/v1/admin/users/%s/rename?token=%s", "User2", token) + urlStr = fmt.Sprintf("/api/v1/admin/users/%s/rename", "User2") req = NewRequestWithValues(t, "POST", urlStr, map[string]string{ // required "new_name": "User2-2-2", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) - urlStr = fmt.Sprintf("/api/v1/admin/users/%s/rename?token=%s", "User2", token) req = NewRequestWithValues(t, "POST", urlStr, map[string]string{ // required "new_name": "user1", - }) + }).AddTokenAuth(token) // the old user name still be used by with a redirect MakeRequest(t, req, http.StatusTemporaryRedirect) - urlStr = fmt.Sprintf("/api/v1/admin/users/%s/rename?token=%s", "User2-2-2", token) + urlStr = fmt.Sprintf("/api/v1/admin/users/%s/rename", "User2-2-2") req = NewRequestWithValues(t, "POST", urlStr, map[string]string{ // required "new_name": "user1", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) - urlStr = fmt.Sprintf("/api/v1/admin/users/%s/rename?token=%s", "User2-2-2", token) req = NewRequestWithValues(t, "POST", urlStr, map[string]string{ // required "new_name": "user2", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) } @@ -294,8 +294,9 @@ func TestAPICron(t *testing.T) { defer tests.PrintCurrentTest(t)() token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadAdmin) - urlStr := fmt.Sprintf("/api/v1/admin/cron?token=%s", token) - req := NewRequest(t, "GET", urlStr) + + req := NewRequest(t, "GET", "/api/v1/admin/cron"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "28", resp.Header().Get("X-Total-Count")) @@ -313,13 +314,13 @@ func TestAPICron(t *testing.T) { // Archive cleanup is harmless, because in the test environment there are none // and is thus an NOOP operation and therefore doesn't interfere with any other // tests. - urlStr := fmt.Sprintf("/api/v1/admin/cron/archive_cleanup?token=%s", token) - req := NewRequest(t, "POST", urlStr) + req := NewRequest(t, "POST", "/api/v1/admin/cron/archive_cleanup"). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // Check for the latest run time for this cron, to ensure it has been run. - urlStr = fmt.Sprintf("/api/v1/admin/cron?token=%s", token) - req = NewRequest(t, "GET", urlStr) + req = NewRequest(t, "GET", "/api/v1/admin/cron"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var crons []api.Cron diff --git a/tests/integration/api_branch_test.go b/tests/integration/api_branch_test.go index bc026c117f66e..28e690b356890 100644 --- a/tests/integration/api_branch_test.go +++ b/tests/integration/api_branch_test.go @@ -17,7 +17,8 @@ import ( func testAPIGetBranch(t *testing.T, branchName string, exists bool) { token := getUserToken(t, "user2", auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/branches/%s?token=%s", branchName, token) + req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/branches/%s", branchName). + AddTokenAuth(token) resp := MakeRequest(t, req, NoExpectedStatus) if !exists { assert.EqualValues(t, http.StatusNotFound, resp.Code) @@ -33,7 +34,8 @@ func testAPIGetBranch(t *testing.T, branchName string, exists bool) { func testAPIGetBranchProtection(t *testing.T, branchName string, expectedHTTPStatus int) *api.BranchProtection { token := getUserToken(t, "user2", auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/branch_protections/%s?token=%s", branchName, token) + req := NewRequestf(t, "GET", "/api/v1/repos/user2/repo1/branch_protections/%s", branchName). + AddTokenAuth(token) resp := MakeRequest(t, req, expectedHTTPStatus) if resp.Code == http.StatusOK { @@ -47,9 +49,9 @@ func testAPIGetBranchProtection(t *testing.T, branchName string, expectedHTTPSta func testAPICreateBranchProtection(t *testing.T, branchName string, expectedHTTPStatus int) { token := getUserToken(t, "user2", auth_model.AccessTokenScopeWriteRepository) - req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo1/branch_protections?token="+token, &api.BranchProtection{ + req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo1/branch_protections", &api.BranchProtection{ RuleName: branchName, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, expectedHTTPStatus) if resp.Code == http.StatusCreated { @@ -61,7 +63,8 @@ func testAPICreateBranchProtection(t *testing.T, branchName string, expectedHTTP func testAPIEditBranchProtection(t *testing.T, branchName string, body *api.BranchProtection, expectedHTTPStatus int) { token := getUserToken(t, "user2", auth_model.AccessTokenScopeWriteRepository) - req := NewRequestWithJSON(t, "PATCH", "/api/v1/repos/user2/repo1/branch_protections/"+branchName+"?token="+token, body) + req := NewRequestWithJSON(t, "PATCH", "/api/v1/repos/user2/repo1/branch_protections/"+branchName, body). + AddTokenAuth(token) resp := MakeRequest(t, req, expectedHTTPStatus) if resp.Code == http.StatusOK { @@ -73,13 +76,15 @@ func testAPIEditBranchProtection(t *testing.T, branchName string, body *api.Bran func testAPIDeleteBranchProtection(t *testing.T, branchName string, expectedHTTPStatus int) { token := getUserToken(t, "user2", auth_model.AccessTokenScopeWriteRepository) - req := NewRequestf(t, "DELETE", "/api/v1/repos/user2/repo1/branch_protections/%s?token=%s", branchName, token) + req := NewRequestf(t, "DELETE", "/api/v1/repos/user2/repo1/branch_protections/%s", branchName). + AddTokenAuth(token) MakeRequest(t, req, expectedHTTPStatus) } func testAPIDeleteBranch(t *testing.T, branchName string, expectedHTTPStatus int) { token := getUserToken(t, "user2", auth_model.AccessTokenScopeWriteRepository) - req := NewRequestf(t, "DELETE", "/api/v1/repos/user2/repo1/branches/%s?token=%s", branchName, token) + req := NewRequestf(t, "DELETE", "/api/v1/repos/user2/repo1/branches/%s", branchName). + AddTokenAuth(token) MakeRequest(t, req, expectedHTTPStatus) } @@ -152,10 +157,10 @@ func testAPICreateBranches(t *testing.T, giteaURL *url.URL) { func testAPICreateBranch(t testing.TB, session *TestSession, user, repo, oldBranch, newBranch string, status int) bool { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestWithJSON(t, "POST", "/api/v1/repos/"+user+"/"+repo+"/branches?token="+token, &api.CreateBranchRepoOption{ + req := NewRequestWithJSON(t, "POST", "/api/v1/repos/"+user+"/"+repo+"/branches", &api.CreateBranchRepoOption{ BranchName: newBranch, OldBranchName: oldBranch, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, status) var branch api.Branch diff --git a/tests/integration/api_comment_attachment_test.go b/tests/integration/api_comment_attachment_test.go index 95a7a81eb4040..e5e62a86b7be7 100644 --- a/tests/integration/api_comment_attachment_test.go +++ b/tests/integration/api_comment_attachment_test.go @@ -39,15 +39,18 @@ func TestAPIGetCommentAttachment(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, attachment.ID, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d", repoOwner.Name, repo.Name, comment.ID, attachment.ID). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) }) session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, attachment.ID, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d", repoOwner.Name, repo.Name, comment.ID, attachment.ID). + AddTokenAuth(token) session.MakeRequest(t, req, http.StatusOK) - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, attachment.ID, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets/%d", repoOwner.Name, repo.Name, comment.ID, attachment.ID). + AddTokenAuth(token) resp := session.MakeRequest(t, req, http.StatusOK) var apiAttachment api.Attachment @@ -71,8 +74,8 @@ func TestAPIListCommentAttachments(t *testing.T) { session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets?token=%s", - repoOwner.Name, repo.Name, comment.ID, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d/assets", repoOwner.Name, repo.Name, comment.ID). + AddTokenAuth(token) resp := session.MakeRequest(t, req, http.StatusOK) var apiAttachments []*api.Attachment @@ -93,8 +96,6 @@ func TestAPICreateCommentAttachment(t *testing.T) { session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/assets?token=%s", - repoOwner.Name, repo.Name, comment.ID, token) filename := "image.png" buff := generateImg() @@ -109,8 +110,9 @@ func TestAPICreateCommentAttachment(t *testing.T) { err = writer.Close() assert.NoError(t, err) - req := NewRequestWithBody(t, "POST", urlStr, body) - req.Header.Add("Content-Type", writer.FormDataContentType()) + req := NewRequestWithBody(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/assets", repoOwner.Name, repo.Name, comment.ID), body). + AddTokenAuth(token). + SetHeader("Content-Type", writer.FormDataContentType()) resp := session.MakeRequest(t, req, http.StatusCreated) apiAttachment := new(api.Attachment) @@ -132,11 +134,11 @@ func TestAPIEditCommentAttachment(t *testing.T) { session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/assets/%d?token=%s", - repoOwner.Name, repo.Name, comment.ID, attachment.ID, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/assets/%d", + repoOwner.Name, repo.Name, comment.ID, attachment.ID) req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{ "name": newAttachmentName, - }) + }).AddTokenAuth(token) resp := session.MakeRequest(t, req, http.StatusCreated) apiAttachment := new(api.Attachment) DecodeJSON(t, resp, &apiAttachment) @@ -155,10 +157,9 @@ func TestAPIDeleteCommentAttachment(t *testing.T) { session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/assets/%d?token=%s", - repoOwner.Name, repo.Name, comment.ID, attachment.ID, token) - req := NewRequestf(t, "DELETE", urlStr) + req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/assets/%d", repoOwner.Name, repo.Name, comment.ID, attachment.ID)). + AddTokenAuth(token) session.MakeRequest(t, req, http.StatusNoContent) unittest.AssertNotExistsBean(t, &repo_model.Attachment{ID: attachment.ID, CommentID: comment.ID}) diff --git a/tests/integration/api_comment_test.go b/tests/integration/api_comment_test.go index fe272cf926932..a9c5228a16c17 100644 --- a/tests/integration/api_comment_test.go +++ b/tests/integration/api_comment_test.go @@ -77,8 +77,8 @@ func TestAPIListIssueComments(t *testing.T) { repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeReadIssue) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/comments?token=%s", - repoOwner.Name, repo.Name, issue.Index, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/comments", repoOwner.Name, repo.Name, issue.Index). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var comments []*api.Comment @@ -97,11 +97,11 @@ func TestAPICreateComment(t *testing.T) { repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments?token=%s", - repoOwner.Name, repo.Name, issue.Index, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/comments", + repoOwner.Name, repo.Name, issue.Index) req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ "body": commentBody, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var updatedComment api.Comment @@ -121,7 +121,8 @@ func TestAPIGetComment(t *testing.T) { token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeReadIssue) req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d", repoOwner.Name, repo.Name, comment.ID) MakeRequest(t, req, http.StatusOK) - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d?token=%s", repoOwner.Name, repo.Name, comment.ID, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/comments/%d", repoOwner.Name, repo.Name, comment.ID). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiComment api.Comment @@ -188,20 +189,20 @@ func TestAPIEditComment(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d?token=%s", - repoOwner.Name, repo.Name, comment.ID, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d", + repoOwner.Name, repo.Name, comment.ID) req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{ "body": newCommentBody, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) }) token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d?token=%s", - repoOwner.Name, repo.Name, comment.ID, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d", + repoOwner.Name, repo.Name, comment.ID) req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{ "body": newCommentBody, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var updatedComment api.Comment @@ -225,14 +226,14 @@ func TestAPIDeleteComment(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) - req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/comments/%d?token=%s", - repoOwner.Name, repo.Name, comment.ID, token) + req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/comments/%d", repoOwner.Name, repo.Name, comment.ID). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) }) token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) - req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/comments/%d?token=%s", - repoOwner.Name, repo.Name, comment.ID, token) + req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/comments/%d", repoOwner.Name, repo.Name, comment.ID). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) unittest.AssertNotExistsBean(t, &issues_model.Comment{ID: comment.ID}) @@ -247,8 +248,7 @@ func TestAPIListIssueTimeline(t *testing.T) { repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) // make request - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/timeline", - repoOwner.Name, repo.Name, issue.Index) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/timeline", repoOwner.Name, repo.Name, issue.Index) resp := MakeRequest(t, req, http.StatusOK) // check if lens of list returned by API and diff --git a/tests/integration/api_gpg_keys_test.go b/tests/integration/api_gpg_keys_test.go index a4545bd0bbd55..ec0dafc2d6dd2 100644 --- a/tests/integration/api_gpg_keys_test.go +++ b/tests/integration/api_gpg_keys_test.go @@ -16,7 +16,7 @@ import ( "github.com/stretchr/testify/assert" ) -type makeRequestFunc func(testing.TB, *http.Request, int) *httptest.ResponseRecorder +type makeRequestFunc func(testing.TB, *RequestWrapper, int) *httptest.ResponseRecorder func TestGPGKeys(t *testing.T) { defer tests.PrepareTestEnv(t)() @@ -79,7 +79,8 @@ func TestGPGKeys(t *testing.T) { t.Run("CheckState", func(t *testing.T) { var keys []*api.GPGKey - req := NewRequest(t, "GET", "/api/v1/user/gpg_keys?token="+tokenWithGPGKeyScope) // GET all keys + req := NewRequest(t, "GET", "/api/v1/user/gpg_keys"). // GET all keys + AddTokenAuth(tokenWithGPGKeyScope) resp := MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &keys) assert.Len(t, keys, 1) @@ -95,7 +96,8 @@ func TestGPGKeys(t *testing.T) { assert.Empty(t, subKey.Emails) var key api.GPGKey - req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(primaryKey1.ID, 10)+"?token="+tokenWithGPGKeyScope) // Primary key 1 + req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(primaryKey1.ID, 10)). // Primary key 1 + AddTokenAuth(tokenWithGPGKeyScope) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &key) assert.EqualValues(t, "38EA3BCED732982C", key.KeyID) @@ -103,7 +105,8 @@ func TestGPGKeys(t *testing.T) { assert.EqualValues(t, "user2@example.com", key.Emails[0].Email) assert.True(t, key.Emails[0].Verified) - req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(subKey.ID, 10)+"?token="+tokenWithGPGKeyScope) // Subkey of 38EA3BCED732982C + req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(subKey.ID, 10)). // Subkey of 38EA3BCED732982C + AddTokenAuth(tokenWithGPGKeyScope) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &key) assert.EqualValues(t, "70D7C694D17D03AD", key.KeyID) @@ -114,7 +117,8 @@ func TestGPGKeys(t *testing.T) { t.Run("CheckCommits", func(t *testing.T) { t.Run("NotSigned", func(t *testing.T) { var branch api.Branch - req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/not-signed?token="+token) + req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/not-signed"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &branch) assert.False(t, branch.Commit.Verification.Verified) @@ -122,7 +126,8 @@ func TestGPGKeys(t *testing.T) { t.Run("SignedWithNotValidatedEmail", func(t *testing.T) { var branch api.Branch - req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/good-sign-not-yet-validated?token="+token) + req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/good-sign-not-yet-validated"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &branch) assert.False(t, branch.Commit.Verification.Verified) @@ -130,7 +135,8 @@ func TestGPGKeys(t *testing.T) { t.Run("SignedWithValidEmail", func(t *testing.T) { var branch api.Branch - req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/good-sign?token="+token) + req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/good-sign"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &branch) assert.True(t, branch.Commit.Verification.Verified) @@ -139,29 +145,33 @@ func TestGPGKeys(t *testing.T) { } func testViewOwnGPGKeys(t *testing.T, makeRequest makeRequestFunc, token string, expected int) { - req := NewRequest(t, "GET", "/api/v1/user/gpg_keys?token="+token) + req := NewRequest(t, "GET", "/api/v1/user/gpg_keys"). + AddTokenAuth(token) makeRequest(t, req, expected) } func testViewGPGKeys(t *testing.T, makeRequest makeRequestFunc, token string, expected int) { - req := NewRequest(t, "GET", "/api/v1/users/user2/gpg_keys?token="+token) + req := NewRequest(t, "GET", "/api/v1/users/user2/gpg_keys"). + AddTokenAuth(token) makeRequest(t, req, expected) } func testGetGPGKey(t *testing.T, makeRequest makeRequestFunc, token string, expected int) { - req := NewRequest(t, "GET", "/api/v1/user/gpg_keys/1?token="+token) + req := NewRequest(t, "GET", "/api/v1/user/gpg_keys/1"). + AddTokenAuth(token) makeRequest(t, req, expected) } func testDeleteGPGKey(t *testing.T, makeRequest makeRequestFunc, token string, expected int) { - req := NewRequest(t, "DELETE", "/api/v1/user/gpg_keys/1?token="+token) + req := NewRequest(t, "DELETE", "/api/v1/user/gpg_keys/1"). + AddTokenAuth(token) makeRequest(t, req, expected) } func testCreateGPGKey(t *testing.T, makeRequest makeRequestFunc, token string, expected int, publicKey string) { - req := NewRequestWithJSON(t, "POST", "/api/v1/user/gpg_keys?token="+token, api.CreateGPGKeyOption{ + req := NewRequestWithJSON(t, "POST", "/api/v1/user/gpg_keys", api.CreateGPGKeyOption{ ArmoredKey: publicKey, - }) + }).AddTokenAuth(token) makeRequest(t, req, expected) } diff --git a/tests/integration/api_helper_for_declarative_test.go b/tests/integration/api_helper_for_declarative_test.go index 3524ce9834add..7755b9861ae30 100644 --- a/tests/integration/api_helper_for_declarative_test.go +++ b/tests/integration/api_helper_for_declarative_test.go @@ -59,7 +59,8 @@ func doAPICreateRepository(ctx APITestContext, empty bool, callback ...func(*tes License: "WTFPL", Readme: "Default", } - req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos?token="+ctx.Token, createRepoOption) + req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos", createRepoOption). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -76,7 +77,8 @@ func doAPICreateRepository(ctx APITestContext, empty bool, callback ...func(*tes func doAPIEditRepository(ctx APITestContext, editRepoOption *api.EditRepoOption, callback ...func(*testing.T, api.Repository)) func(*testing.T) { return func(t *testing.T) { - req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame), ctx.Token), editRepoOption) + req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", url.PathEscape(ctx.Username), url.PathEscape(ctx.Reponame)), editRepoOption). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -103,7 +105,8 @@ func doAPIAddCollaborator(ctx APITestContext, username string, mode perm.AccessM addCollaboratorOption := &api.AddCollaboratorOption{ Permission: &permission, } - req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/collaborators/%s?token=%s", ctx.Username, ctx.Reponame, username, ctx.Token), addCollaboratorOption) + req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/collaborators/%s", ctx.Username, ctx.Reponame, username), addCollaboratorOption). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -115,7 +118,8 @@ func doAPIAddCollaborator(ctx APITestContext, username string, mode perm.AccessM func doAPIForkRepository(ctx APITestContext, username string, callback ...func(*testing.T, api.Repository)) func(*testing.T) { return func(t *testing.T) { createForkOption := &api.CreateForkOption{} - req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/forks?token=%s", username, ctx.Reponame, ctx.Token), createForkOption) + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/forks", username, ctx.Reponame), createForkOption). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -131,9 +135,8 @@ func doAPIForkRepository(ctx APITestContext, username string, callback ...func(* func doAPIGetRepository(ctx APITestContext, callback ...func(*testing.T, api.Repository)) func(*testing.T) { return func(t *testing.T) { - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", ctx.Username, ctx.Reponame, ctx.Token) - - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s", ctx.Username, ctx.Reponame)). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -150,9 +153,8 @@ func doAPIGetRepository(ctx APITestContext, callback ...func(*testing.T, api.Rep func doAPIDeleteRepository(ctx APITestContext) func(*testing.T) { return func(t *testing.T) { - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", ctx.Username, ctx.Reponame, ctx.Token) - - req := NewRequest(t, "DELETE", urlStr) + req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s", ctx.Username, ctx.Reponame)). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -163,14 +165,12 @@ func doAPIDeleteRepository(ctx APITestContext) func(*testing.T) { func doAPICreateUserKey(ctx APITestContext, keyname, keyFile string, callback ...func(*testing.T, api.PublicKey)) func(*testing.T) { return func(t *testing.T) { - urlStr := fmt.Sprintf("/api/v1/user/keys?token=%s", ctx.Token) - dataPubKey, err := os.ReadFile(keyFile + ".pub") assert.NoError(t, err) - req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateKeyOption{ + req := NewRequestWithJSON(t, "POST", "/api/v1/user/keys", &api.CreateKeyOption{ Title: keyname, Key: string(dataPubKey), - }) + }).AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -186,9 +186,8 @@ func doAPICreateUserKey(ctx APITestContext, keyname, keyFile string, callback .. func doAPIDeleteUserKey(ctx APITestContext, keyID int64) func(*testing.T) { return func(t *testing.T) { - urlStr := fmt.Sprintf("/api/v1/user/keys/%d?token=%s", keyID, ctx.Token) - - req := NewRequest(t, "DELETE", urlStr) + req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/keys/%d", keyID)). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -199,15 +198,13 @@ func doAPIDeleteUserKey(ctx APITestContext, keyID int64) func(*testing.T) { func doAPICreateDeployKey(ctx APITestContext, keyname, keyFile string, readOnly bool) func(*testing.T) { return func(t *testing.T) { - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", ctx.Username, ctx.Reponame, ctx.Token) - dataPubKey, err := os.ReadFile(keyFile + ".pub") assert.NoError(t, err) - req := NewRequestWithJSON(t, "POST", urlStr, api.CreateKeyOption{ + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/keys", ctx.Username, ctx.Reponame), api.CreateKeyOption{ Title: keyname, Key: string(dataPubKey), ReadOnly: readOnly, - }) + }).AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) @@ -219,13 +216,11 @@ func doAPICreateDeployKey(ctx APITestContext, keyname, keyFile string, readOnly func doAPICreatePullRequest(ctx APITestContext, owner, repo, baseBranch, headBranch string) func(*testing.T) (api.PullRequest, error) { return func(t *testing.T) (api.PullRequest, error) { - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", - owner, repo, ctx.Token) - req := NewRequestWithJSON(t, http.MethodPost, urlStr, &api.CreatePullRequestOption{ + req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner, repo), &api.CreatePullRequestOption{ Head: headBranch, Base: baseBranch, Title: fmt.Sprintf("create a pr from %s to %s", headBranch, baseBranch), - }) + }).AddTokenAuth(ctx.Token) expected := http.StatusCreated if ctx.ExpectedCode != 0 { @@ -242,9 +237,8 @@ func doAPICreatePullRequest(ctx APITestContext, owner, repo, baseBranch, headBra func doAPIGetPullRequest(ctx APITestContext, owner, repo string, index int64) func(*testing.T) (api.PullRequest, error) { return func(t *testing.T) (api.PullRequest, error) { - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d?token=%s", - owner, repo, index, ctx.Token) - req := NewRequest(t, http.MethodGet, urlStr) + req := NewRequest(t, http.MethodGet, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d", owner, repo, index)). + AddTokenAuth(ctx.Token) expected := http.StatusOK if ctx.ExpectedCode != 0 { @@ -261,17 +255,16 @@ func doAPIGetPullRequest(ctx APITestContext, owner, repo string, index int64) fu func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64) func(*testing.T) { return func(t *testing.T) { - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s", - owner, repo, index, ctx.Token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge", owner, repo, index) - var req *http.Request + var req *RequestWrapper var resp *httptest.ResponseRecorder for i := 0; i < 6; i++ { req = NewRequestWithJSON(t, http.MethodPost, urlStr, &forms.MergePullRequestForm{ MergeMessageField: "doAPIMergePullRequest Merge", Do: string(repo_model.MergeStyleMerge), - }) + }).AddTokenAuth(ctx.Token) resp = ctx.Session.MakeRequest(t, req, NoExpectedStatus) @@ -299,12 +292,11 @@ func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64) func doAPIManuallyMergePullRequest(ctx APITestContext, owner, repo, commitID string, index int64) func(*testing.T) { return func(t *testing.T) { - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s", - owner, repo, index, ctx.Token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge", owner, repo, index) req := NewRequestWithJSON(t, http.MethodPost, urlStr, &forms.MergePullRequestForm{ Do: string(repo_model.MergeStyleManuallyMerged), MergeCommitID: commitID, - }) + }).AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) @@ -316,38 +308,37 @@ func doAPIManuallyMergePullRequest(ctx APITestContext, owner, repo, commitID str func doAPIAutoMergePullRequest(ctx APITestContext, owner, repo string, index int64) func(*testing.T) { return func(t *testing.T) { - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s", - owner, repo, index, ctx.Token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge", owner, repo, index) req := NewRequestWithJSON(t, http.MethodPost, urlStr, &forms.MergePullRequestForm{ MergeMessageField: "doAPIMergePullRequest Merge", Do: string(repo_model.MergeStyleMerge), MergeWhenChecksSucceed: true, - }) + }).AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return } - ctx.Session.MakeRequest(t, req, 200) + ctx.Session.MakeRequest(t, req, http.StatusOK) } } func doAPICancelAutoMergePullRequest(ctx APITestContext, owner, repo string, index int64) func(*testing.T) { return func(t *testing.T) { - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s", - owner, repo, index, ctx.Token) - req := NewRequest(t, http.MethodDelete, urlStr) + req := NewRequest(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge", owner, repo, index)). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return } - ctx.Session.MakeRequest(t, req, 204) + ctx.Session.MakeRequest(t, req, http.StatusNoContent) } } func doAPIGetBranch(ctx APITestContext, branch string, callback ...func(*testing.T, api.Branch)) func(*testing.T) { return func(t *testing.T) { - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/branches/%s?token=%s", ctx.Username, ctx.Reponame, branch, ctx.Token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/branches/%s", ctx.Username, ctx.Reponame, branch). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -364,8 +355,8 @@ func doAPIGetBranch(ctx APITestContext, branch string, callback ...func(*testing func doAPICreateFile(ctx APITestContext, treepath string, options *api.CreateFileOptions, callback ...func(*testing.T, api.FileResponse)) func(*testing.T) { return func(t *testing.T) { - url := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", ctx.Username, ctx.Reponame, treepath, ctx.Token) - req := NewRequestWithJSON(t, "POST", url, &options) + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", ctx.Username, ctx.Reponame, treepath), &options). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -382,9 +373,8 @@ func doAPICreateFile(ctx APITestContext, treepath string, options *api.CreateFil func doAPICreateOrganization(ctx APITestContext, options *api.CreateOrgOption, callback ...func(*testing.T, api.Organization)) func(t *testing.T) { return func(t *testing.T) { - url := fmt.Sprintf("/api/v1/orgs?token=%s", ctx.Token) - - req := NewRequestWithJSON(t, "POST", url, &options) + req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &options). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -401,9 +391,8 @@ func doAPICreateOrganization(ctx APITestContext, options *api.CreateOrgOption, c func doAPICreateOrganizationRepository(ctx APITestContext, orgName string, options *api.CreateRepoOption, callback ...func(*testing.T, api.Repository)) func(t *testing.T) { return func(t *testing.T) { - url := fmt.Sprintf("/api/v1/orgs/%s/repos?token=%s", orgName, ctx.Token) - - req := NewRequestWithJSON(t, "POST", url, &options) + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/repos", orgName), &options). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -420,9 +409,8 @@ func doAPICreateOrganizationRepository(ctx APITestContext, orgName string, optio func doAPICreateOrganizationTeam(ctx APITestContext, orgName string, options *api.CreateTeamOption, callback ...func(*testing.T, api.Team)) func(t *testing.T) { return func(t *testing.T) { - url := fmt.Sprintf("/api/v1/orgs/%s/teams?token=%s", orgName, ctx.Token) - - req := NewRequestWithJSON(t, "POST", url, &options) + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams", orgName), &options). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -439,9 +427,8 @@ func doAPICreateOrganizationTeam(ctx APITestContext, orgName string, options *ap func doAPIAddUserToOrganizationTeam(ctx APITestContext, teamID int64, username string) func(t *testing.T) { return func(t *testing.T) { - url := fmt.Sprintf("/api/v1/teams/%d/members/%s?token=%s", teamID, username, ctx.Token) - - req := NewRequest(t, "PUT", url) + req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/teams/%d/members/%s", teamID, username)). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return @@ -452,9 +439,8 @@ func doAPIAddUserToOrganizationTeam(ctx APITestContext, teamID int64, username s func doAPIAddRepoToOrganizationTeam(ctx APITestContext, teamID int64, orgName, repoName string) func(t *testing.T) { return func(t *testing.T) { - url := fmt.Sprintf("/api/v1/teams/%d/repos/%s/%s?token=%s", teamID, orgName, repoName, ctx.Token) - - req := NewRequest(t, "PUT", url) + req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/teams/%d/repos/%s/%s", teamID, orgName, repoName)). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return diff --git a/tests/integration/api_httpsig_test.go b/tests/integration/api_httpsig_test.go index 675ec54ff58f7..30aed3cacceb6 100644 --- a/tests/integration/api_httpsig_test.go +++ b/tests/integration/api_httpsig_test.go @@ -5,7 +5,6 @@ package integration import ( "encoding/base64" - "fmt" "net/http" "net/url" "testing" @@ -57,14 +56,14 @@ func TestHTTPSigPubKey(t *testing.T) { defer test.MockVariableValue(&setting.SSH.MinimumKeySizeCheck, false)() session := loginUser(t, "user1") token := url.QueryEscape(getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser)) - keysURL := fmt.Sprintf("/api/v1/user/keys?token=%s", token) keyType := "ssh-rsa" keyContent := "AAAAB3NzaC1yc2EAAAADAQABAAABAQCqOZB5vkRvXFXups1/0StDRdG8plbNSwsWEnNnP4Bvurxa0+z3W9B8GLKnDiLw5MbpbMNyBlpXw13GfuIeciy10DWTz0xUbiy3J3KabCaT36asIw2y7k6Z0jL0UBnrVENwq5/lUbZYqSZ4rRU744wkhh8TULpzM14npQCZwg6aEbG+MwjzddQ72fR+3BPBrKn5dTmmu8rH99O+U+Nuto81Tg7PA+NUupcHOmhdiEGq49plgVFXK98Vks5tiybL4GuzFyWgyX73Dg/QBMn2eMHt1EMv5Gs3i6GFhKKGo4rjDi9qI6PX5oDR4LTNe6cR8td8YhVD8WFZwLLl/vaYyIqd" rawKeyBody := api.CreateKeyOption{ Title: "test-key", Key: keyType + " " + keyContent, } - req := NewRequestWithJSON(t, "POST", keysURL, rawKeyBody) + req := NewRequestWithJSON(t, "POST", "/api/v1/user/keys", rawKeyBody). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) // parse our private key and create the httpsig request @@ -73,7 +72,8 @@ func TestHTTPSigPubKey(t *testing.T) { // create the request token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadAdmin) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/admin/users?token=%s", token)) + req = NewRequest(t, "GET", "/api/v1/admin/users"). + AddTokenAuth(token) signer, _, err := httpsig.NewSSHSigner(sshSigner, httpsig.DigestSha512, []string{httpsig.RequestTarget, "(created)", "(expires)"}, httpsig.Signature, 10) if err != nil { @@ -81,7 +81,7 @@ func TestHTTPSigPubKey(t *testing.T) { } // sign the request - err = signer.SignRequest(keyID, req, nil) + err = signer.SignRequest(keyID, req.Request, nil) if err != nil { t.Fatal(err) } @@ -124,7 +124,7 @@ func TestHTTPSigCert(t *testing.T) { // add our cert to the request certString := base64.RawStdEncoding.EncodeToString(pkcert.(*ssh.Certificate).Marshal()) - req.Header.Add("x-ssh-certificate", certString) + req.SetHeader("x-ssh-certificate", certString) signer, _, err := httpsig.NewSSHSigner(certSigner, httpsig.DigestSha512, []string{httpsig.RequestTarget, "(created)", "(expires)", "x-ssh-certificate"}, httpsig.Signature, 10) if err != nil { @@ -132,7 +132,7 @@ func TestHTTPSigCert(t *testing.T) { } // sign the request - err = signer.SignRequest(keyID, req, nil) + err = signer.SignRequest(keyID, req.Request, nil) if err != nil { t.Fatal(err) } diff --git a/tests/integration/api_issue_attachment_test.go b/tests/integration/api_issue_attachment_test.go index 3b43ba2c412c4..4b57d387d875d 100644 --- a/tests/integration/api_issue_attachment_test.go +++ b/tests/integration/api_issue_attachment_test.go @@ -33,10 +33,9 @@ func TestAPIGetIssueAttachment(t *testing.T) { session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets/%d?token=%s", - repoOwner.Name, repo.Name, issue.Index, attachment.ID, token) - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets/%d", repoOwner.Name, repo.Name, issue.Index, attachment.ID)). + AddTokenAuth(token) resp := session.MakeRequest(t, req, http.StatusOK) apiAttachment := new(api.Attachment) DecodeJSON(t, resp, &apiAttachment) @@ -54,10 +53,9 @@ func TestAPIListIssueAttachments(t *testing.T) { session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets?token=%s", - repoOwner.Name, repo.Name, issue.Index, token) - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets", repoOwner.Name, repo.Name, issue.Index)). + AddTokenAuth(token) resp := session.MakeRequest(t, req, http.StatusOK) apiAttachment := new([]api.Attachment) DecodeJSON(t, resp, &apiAttachment) @@ -74,8 +72,6 @@ func TestAPICreateIssueAttachment(t *testing.T) { session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets?token=%s", - repoOwner.Name, repo.Name, issue.Index, token) filename := "image.png" buff := generateImg() @@ -90,7 +86,8 @@ func TestAPICreateIssueAttachment(t *testing.T) { err = writer.Close() assert.NoError(t, err) - req := NewRequestWithBody(t, "POST", urlStr, body) + req := NewRequestWithBody(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets", repoOwner.Name, repo.Name, issue.Index), body). + AddTokenAuth(token) req.Header.Add("Content-Type", writer.FormDataContentType()) resp := session.MakeRequest(t, req, http.StatusCreated) @@ -112,11 +109,11 @@ func TestAPIEditIssueAttachment(t *testing.T) { session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets/%d?token=%s", - repoOwner.Name, repo.Name, issue.Index, attachment.ID, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets/%d", + repoOwner.Name, repo.Name, issue.Index, attachment.ID) req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{ "name": newAttachmentName, - }) + }).AddTokenAuth(token) resp := session.MakeRequest(t, req, http.StatusCreated) apiAttachment := new(api.Attachment) DecodeJSON(t, resp, &apiAttachment) @@ -134,10 +131,9 @@ func TestAPIDeleteIssueAttachment(t *testing.T) { session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets/%d?token=%s", - repoOwner.Name, repo.Name, issue.Index, attachment.ID, token) - req := NewRequest(t, "DELETE", urlStr) + req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/assets/%d", repoOwner.Name, repo.Name, issue.Index, attachment.ID)). + AddTokenAuth(token) session.MakeRequest(t, req, http.StatusNoContent) unittest.AssertNotExistsBean(t, &repo_model.Attachment{ID: attachment.ID, IssueID: issue.ID}) diff --git a/tests/integration/api_issue_label_test.go b/tests/integration/api_issue_label_test.go index d2d8af102b3bb..35c07182634e2 100644 --- a/tests/integration/api_issue_label_test.go +++ b/tests/integration/api_issue_label_test.go @@ -26,14 +26,14 @@ func TestAPIModifyLabels(t *testing.T) { owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/labels?token=%s", owner.Name, repo.Name, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/labels", owner.Name, repo.Name) // CreateLabel req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateLabelOption{ Name: "TestL 1", Color: "abcdef", Description: "test label", - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) apiLabel := new(api.Label) DecodeJSON(t, resp, &apiLabel) @@ -45,24 +45,26 @@ func TestAPIModifyLabels(t *testing.T) { Name: "TestL 2", Color: "#123456", Description: "jet another test label", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) req = NewRequestWithJSON(t, "POST", urlStr, &api.CreateLabelOption{ Name: "WrongTestL", Color: "#12345g", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) // ListLabels - req = NewRequest(t, "GET", urlStr) + req = NewRequest(t, "GET", urlStr). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var apiLabels []*api.Label DecodeJSON(t, resp, &apiLabels) assert.Len(t, apiLabels, 2) // GetLabel - singleURLStr := fmt.Sprintf("/api/v1/repos/%s/%s/labels/%d?token=%s", owner.Name, repo.Name, dbLabel.ID, token) - req = NewRequest(t, "GET", singleURLStr) + singleURLStr := fmt.Sprintf("/api/v1/repos/%s/%s/labels/%d", owner.Name, repo.Name, dbLabel.ID) + req = NewRequest(t, "GET", singleURLStr). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiLabel) assert.EqualValues(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) @@ -74,17 +76,18 @@ func TestAPIModifyLabels(t *testing.T) { req = NewRequestWithJSON(t, "PATCH", singleURLStr, &api.EditLabelOption{ Name: &newName, Color: &newColor, - }) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiLabel) assert.EqualValues(t, newColor, apiLabel.Color) req = NewRequestWithJSON(t, "PATCH", singleURLStr, &api.EditLabelOption{ Color: &newColorWrong, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) // DeleteLabel - req = NewRequest(t, "DELETE", singleURLStr) + req = NewRequest(t, "DELETE", singleURLStr). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) } @@ -98,11 +101,11 @@ func TestAPIAddIssueLabels(t *testing.T) { session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels?token=%s", - repo.OwnerName, repo.Name, issue.Index, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels", + repo.OwnerName, repo.Name, issue.Index) req := NewRequestWithJSON(t, "POST", urlStr, &api.IssueLabelsOption{ Labels: []int64{1, 2}, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiLabels []*api.Label DecodeJSON(t, resp, &apiLabels) @@ -121,11 +124,11 @@ func TestAPIReplaceIssueLabels(t *testing.T) { session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels?token=%s", - owner.Name, repo.Name, issue.Index, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/labels", + owner.Name, repo.Name, issue.Index) req := NewRequestWithJSON(t, "PUT", urlStr, &api.IssueLabelsOption{ Labels: []int64{label.ID}, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiLabels []*api.Label DecodeJSON(t, resp, &apiLabels) @@ -145,14 +148,14 @@ func TestAPIModifyOrgLabels(t *testing.T) { user := "user1" session := loginUser(t, user) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteOrganization) - urlStr := fmt.Sprintf("/api/v1/orgs/%s/labels?token=%s", owner.Name, token) + urlStr := fmt.Sprintf("/api/v1/orgs/%s/labels", owner.Name) // CreateLabel req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateLabelOption{ Name: "TestL 1", Color: "abcdef", Description: "test label", - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) apiLabel := new(api.Label) DecodeJSON(t, resp, &apiLabel) @@ -164,24 +167,26 @@ func TestAPIModifyOrgLabels(t *testing.T) { Name: "TestL 2", Color: "#123456", Description: "jet another test label", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) req = NewRequestWithJSON(t, "POST", urlStr, &api.CreateLabelOption{ Name: "WrongTestL", Color: "#12345g", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) // ListLabels - req = NewRequest(t, "GET", urlStr) + req = NewRequest(t, "GET", urlStr). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var apiLabels []*api.Label DecodeJSON(t, resp, &apiLabels) assert.Len(t, apiLabels, 4) // GetLabel - singleURLStr := fmt.Sprintf("/api/v1/orgs/%s/labels/%d?token=%s", owner.Name, dbLabel.ID, token) - req = NewRequest(t, "GET", singleURLStr) + singleURLStr := fmt.Sprintf("/api/v1/orgs/%s/labels/%d", owner.Name, dbLabel.ID) + req = NewRequest(t, "GET", singleURLStr). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiLabel) assert.EqualValues(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) @@ -193,16 +198,17 @@ func TestAPIModifyOrgLabels(t *testing.T) { req = NewRequestWithJSON(t, "PATCH", singleURLStr, &api.EditLabelOption{ Name: &newName, Color: &newColor, - }) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiLabel) assert.EqualValues(t, newColor, apiLabel.Color) req = NewRequestWithJSON(t, "PATCH", singleURLStr, &api.EditLabelOption{ Color: &newColorWrong, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) // DeleteLabel - req = NewRequest(t, "DELETE", singleURLStr) + req = NewRequest(t, "DELETE", singleURLStr). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) } diff --git a/tests/integration/api_issue_milestone_test.go b/tests/integration/api_issue_milestone_test.go index 3bd763f4b52cf..32ac56298fab4 100644 --- a/tests/integration/api_issue_milestone_test.go +++ b/tests/integration/api_issue_milestone_test.go @@ -34,48 +34,53 @@ func TestAPIIssuesMilestone(t *testing.T) { // update values of issue milestoneState := "closed" - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%d?token=%s", owner.Name, repo.Name, milestone.ID, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%d", owner.Name, repo.Name, milestone.ID) req := NewRequestWithJSON(t, "PATCH", urlStr, structs.EditMilestoneOption{ State: &milestoneState, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiMilestone structs.Milestone DecodeJSON(t, resp, &apiMilestone) assert.EqualValues(t, "closed", apiMilestone.State) - req = NewRequest(t, "GET", urlStr) + req = NewRequest(t, "GET", urlStr). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var apiMilestone2 structs.Milestone DecodeJSON(t, resp, &apiMilestone2) assert.EqualValues(t, "closed", apiMilestone2.State) - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?token=%s", owner.Name, repo.Name, token), structs.CreateMilestoneOption{ + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/milestones", owner.Name, repo.Name), structs.CreateMilestoneOption{ Title: "wow", Description: "closed one", State: "closed", - }) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, &apiMilestone) assert.Equal(t, "wow", apiMilestone.Title) assert.Equal(t, structs.StateClosed, apiMilestone.State) var apiMilestones []structs.Milestone - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?state=%s&token=%s", owner.Name, repo.Name, "all", token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?state=%s", owner.Name, repo.Name, "all")). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiMilestones) assert.Len(t, apiMilestones, 4) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%s?token=%s", owner.Name, repo.Name, apiMilestones[2].Title, token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%s", owner.Name, repo.Name, apiMilestones[2].Title)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiMilestone) assert.EqualValues(t, apiMilestones[2], apiMilestone) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?state=%s&name=%s&token=%s", owner.Name, repo.Name, "all", "milestone2", token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?state=%s&name=%s", owner.Name, repo.Name, "all", "milestone2")). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiMilestones) assert.Len(t, apiMilestones, 1) assert.Equal(t, int64(2), apiMilestones[0].ID) - req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%d?token=%s", owner.Name, repo.Name, apiMilestone.ID, token)) + req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/milestones/%d", owner.Name, repo.Name, apiMilestone.ID)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) } diff --git a/tests/integration/api_issue_pin_test.go b/tests/integration/api_issue_pin_test.go index 5a9efc058bfba..1cff937254b85 100644 --- a/tests/integration/api_issue_pin_test.go +++ b/tests/integration/api_issue_pin_test.go @@ -32,14 +32,12 @@ func TestAPIPinIssue(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) // Pin the Issue - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin?token=%s", - repo.OwnerName, repo.Name, issue.Index, token) - req := NewRequest(t, "POST", urlStr) + req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin", repo.OwnerName, repo.Name, issue.Index)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // Check if the Issue is pinned - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", repo.OwnerName, repo.Name, issue.Index) - req = NewRequest(t, "GET", urlStr) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", repo.OwnerName, repo.Name, issue.Index)) resp := MakeRequest(t, req, http.StatusOK) var issueAPI api.Issue DecodeJSON(t, resp, &issueAPI) @@ -59,28 +57,24 @@ func TestAPIUnpinIssue(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) // Pin the Issue - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin?token=%s", - repo.OwnerName, repo.Name, issue.Index, token) - req := NewRequest(t, "POST", urlStr) + req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin", repo.OwnerName, repo.Name, issue.Index)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // Check if the Issue is pinned - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", repo.OwnerName, repo.Name, issue.Index) - req = NewRequest(t, "GET", urlStr) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", repo.OwnerName, repo.Name, issue.Index)) resp := MakeRequest(t, req, http.StatusOK) var issueAPI api.Issue DecodeJSON(t, resp, &issueAPI) assert.Equal(t, 1, issueAPI.PinOrder) // Unpin the Issue - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin?token=%s", - repo.OwnerName, repo.Name, issue.Index, token) - req = NewRequest(t, "DELETE", urlStr) + req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin", repo.OwnerName, repo.Name, issue.Index)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // Check if the Issue is no longer pinned - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", repo.OwnerName, repo.Name, issue.Index) - req = NewRequest(t, "GET", urlStr) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", repo.OwnerName, repo.Name, issue.Index)) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &issueAPI) assert.Equal(t, 0, issueAPI.PinOrder) @@ -100,42 +94,36 @@ func TestAPIMoveIssuePin(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) // Pin the first Issue - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin?token=%s", - repo.OwnerName, repo.Name, issue.Index, token) - req := NewRequest(t, "POST", urlStr) + req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin", repo.OwnerName, repo.Name, issue.Index)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // Check if the first Issue is pinned at position 1 - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", repo.OwnerName, repo.Name, issue.Index) - req = NewRequest(t, "GET", urlStr) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", repo.OwnerName, repo.Name, issue.Index)) resp := MakeRequest(t, req, http.StatusOK) var issueAPI api.Issue DecodeJSON(t, resp, &issueAPI) assert.Equal(t, 1, issueAPI.PinOrder) // Pin the second Issue - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin?token=%s", - repo.OwnerName, repo.Name, issue2.Index, token) - req = NewRequest(t, "POST", urlStr) + req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin", repo.OwnerName, repo.Name, issue2.Index)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // Move the first Issue to position 2 - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin/2?token=%s", - repo.OwnerName, repo.Name, issue.Index, token) - req = NewRequest(t, "PATCH", urlStr) + req = NewRequest(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin/2", repo.OwnerName, repo.Name, issue.Index)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // Check if the first Issue is pinned at position 2 - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", repo.OwnerName, repo.Name, issue.Index) - req = NewRequest(t, "GET", urlStr) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", repo.OwnerName, repo.Name, issue.Index)) resp = MakeRequest(t, req, http.StatusOK) var issueAPI3 api.Issue DecodeJSON(t, resp, &issueAPI3) assert.Equal(t, 2, issueAPI3.PinOrder) // Check if the second Issue is pinned at position 1 - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", repo.OwnerName, repo.Name, issue2.Index) - req = NewRequest(t, "GET", urlStr) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", repo.OwnerName, repo.Name, issue2.Index)) resp = MakeRequest(t, req, http.StatusOK) var issueAPI4 api.Issue DecodeJSON(t, resp, &issueAPI4) @@ -155,14 +143,12 @@ func TestAPIListPinnedIssues(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) // Pin the Issue - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin?token=%s", - repo.OwnerName, repo.Name, issue.Index, token) - req := NewRequest(t, "POST", urlStr) + req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/pin", repo.OwnerName, repo.Name, issue.Index)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // Check if the Issue is in the List - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/pinned", repo.OwnerName, repo.Name) - req = NewRequest(t, "GET", urlStr) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/issues/pinned", repo.OwnerName, repo.Name)) resp := MakeRequest(t, req, http.StatusOK) var issueList []api.Issue DecodeJSON(t, resp, &issueList) @@ -178,8 +164,7 @@ func TestAPIListPinnedPullrequests(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/pinned", repo.OwnerName, repo.Name) - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/pulls/pinned", repo.OwnerName, repo.Name)) resp := MakeRequest(t, req, http.StatusOK) var prList []api.PullRequest DecodeJSON(t, resp, &prList) @@ -193,8 +178,7 @@ func TestAPINewPinAllowed(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/new_pin_allowed", owner.Name, repo.Name) - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/new_pin_allowed", owner.Name, repo.Name)) resp := MakeRequest(t, req, http.StatusOK) var newPinsAllowed api.NewIssuePinsAllowed diff --git a/tests/integration/api_issue_reaction_test.go b/tests/integration/api_issue_reaction_test.go index 124d729353ca7..4ca909f2812b9 100644 --- a/tests/integration/api_issue_reaction_test.go +++ b/tests/integration/api_issue_reaction_test.go @@ -33,25 +33,24 @@ func TestAPIIssuesReactions(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/reactions?token=%s", - owner.Name, issue.Repo.Name, issue.Index, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/reactions", owner.Name, issue.Repo.Name, issue.Index) // Try to add not allowed reaction req := NewRequestWithJSON(t, "POST", urlStr, &api.EditReactionOption{ Reaction: "wrong", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) // Delete not allowed reaction req = NewRequestWithJSON(t, "DELETE", urlStr, &api.EditReactionOption{ Reaction: "zzz", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) // Add allowed reaction req = NewRequestWithJSON(t, "POST", urlStr, &api.EditReactionOption{ Reaction: "rocket", - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var apiNewReaction api.Reaction DecodeJSON(t, resp, &apiNewReaction) @@ -60,7 +59,8 @@ func TestAPIIssuesReactions(t *testing.T) { MakeRequest(t, req, http.StatusForbidden) // Get end result of reaction list of issue #1 - req = NewRequestf(t, "GET", urlStr) + req = NewRequest(t, "GET", urlStr). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var apiReactions []*api.Reaction DecodeJSON(t, resp, &apiReactions) @@ -93,19 +93,18 @@ func TestAPICommentReactions(t *testing.T) { user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/reactions?token=%s", - owner.Name, issue.Repo.Name, comment.ID, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/reactions", owner.Name, issue.Repo.Name, comment.ID) // Try to add not allowed reaction req := NewRequestWithJSON(t, "POST", urlStr, &api.EditReactionOption{ Reaction: "wrong", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) // Delete none existing reaction req = NewRequestWithJSON(t, "DELETE", urlStr, &api.EditReactionOption{ Reaction: "eyes", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) t.Run("UnrelatedCommentID", func(t *testing.T) { @@ -113,25 +112,25 @@ func TestAPICommentReactions(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}) repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) token := getUserToken(t, repoOwner.Name, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/reactions?token=%s", - repoOwner.Name, repo.Name, comment.ID, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/reactions", repoOwner.Name, repo.Name, comment.ID) req = NewRequestWithJSON(t, "POST", urlStr, &api.EditReactionOption{ Reaction: "+1", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) req = NewRequestWithJSON(t, "DELETE", urlStr, &api.EditReactionOption{ Reaction: "+1", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequestf(t, "GET", urlStr) + req = NewRequest(t, "GET", urlStr). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) }) // Add allowed reaction req = NewRequestWithJSON(t, "POST", urlStr, &api.EditReactionOption{ Reaction: "+1", - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var apiNewReaction api.Reaction DecodeJSON(t, resp, &apiNewReaction) @@ -140,7 +139,8 @@ func TestAPICommentReactions(t *testing.T) { MakeRequest(t, req, http.StatusForbidden) // Get end result of reaction list of issue #1 - req = NewRequestf(t, "GET", urlStr) + req = NewRequest(t, "GET", urlStr). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var apiReactions []*api.Reaction DecodeJSON(t, resp, &apiReactions) diff --git a/tests/integration/api_issue_stopwatch_test.go b/tests/integration/api_issue_stopwatch_test.go index 09d404ce4e231..23066782173ac 100644 --- a/tests/integration/api_issue_stopwatch_test.go +++ b/tests/integration/api_issue_stopwatch_test.go @@ -27,7 +27,8 @@ func TestAPIListStopWatches(t *testing.T) { session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository, auth_model.AccessTokenScopeReadUser) - req := NewRequestf(t, "GET", "/api/v1/user/stopwatches?token=%s", token) + req := NewRequest(t, "GET", "/api/v1/user/stopwatches"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiWatches []*api.StopWatch DecodeJSON(t, resp, &apiWatches) @@ -54,7 +55,8 @@ func TestAPIStopStopWatches(t *testing.T) { session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/issues/%d/stopwatch/stop?token=%s", owner.Name, issue.Repo.Name, issue.Index, token) + req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/issues/%d/stopwatch/stop", owner.Name, issue.Repo.Name, issue.Index). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) MakeRequest(t, req, http.StatusConflict) } @@ -70,7 +72,8 @@ func TestAPICancelStopWatches(t *testing.T) { session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/stopwatch/delete?token=%s", owner.Name, issue.Repo.Name, issue.Index, token) + req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/stopwatch/delete", owner.Name, issue.Repo.Name, issue.Index). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) MakeRequest(t, req, http.StatusConflict) } @@ -86,7 +89,8 @@ func TestAPIStartStopWatches(t *testing.T) { session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/issues/%d/stopwatch/start?token=%s", owner.Name, issue.Repo.Name, issue.Index, token) + req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/issues/%d/stopwatch/start", owner.Name, issue.Repo.Name, issue.Index). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) MakeRequest(t, req, http.StatusConflict) } diff --git a/tests/integration/api_issue_subscription_test.go b/tests/integration/api_issue_subscription_test.go index 28650a337523f..7a716301c4667 100644 --- a/tests/integration/api_issue_subscription_test.go +++ b/tests/integration/api_issue_subscription_test.go @@ -37,8 +37,8 @@ func TestAPIIssueSubscriptions(t *testing.T) { testSubscription := func(issue *issues_model.Issue, isWatching bool) { issueRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/check?token=%s", issueRepo.OwnerName, issueRepo.Name, issue.Index, token) - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/check", issueRepo.OwnerName, issueRepo.Name, issue.Index)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) wi := new(api.WatchInfo) DecodeJSON(t, resp, wi) @@ -57,22 +57,26 @@ func TestAPIIssueSubscriptions(t *testing.T) { testSubscription(issue5, false) issue1Repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue1.RepoID}) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/%s?token=%s", issue1Repo.OwnerName, issue1Repo.Name, issue1.Index, owner.Name, token) - req := NewRequest(t, "DELETE", urlStr) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/%s", issue1Repo.OwnerName, issue1Repo.Name, issue1.Index, owner.Name) + req := NewRequest(t, "DELETE", urlStr). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) testSubscription(issue1, false) - req = NewRequest(t, "DELETE", urlStr) + req = NewRequest(t, "DELETE", urlStr). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) testSubscription(issue1, false) issue5Repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue5.RepoID}) - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/%s?token=%s", issue5Repo.OwnerName, issue5Repo.Name, issue5.Index, owner.Name, token) - req = NewRequest(t, "PUT", urlStr) + urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/%s", issue5Repo.OwnerName, issue5Repo.Name, issue5.Index, owner.Name) + req = NewRequest(t, "PUT", urlStr). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) testSubscription(issue5, true) - req = NewRequest(t, "PUT", urlStr) + req = NewRequest(t, "PUT", urlStr). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) testSubscription(issue5, true) } diff --git a/tests/integration/api_issue_test.go b/tests/integration/api_issue_test.go index 29f09fa09e747..dcccafb0f29b3 100644 --- a/tests/integration/api_issue_test.go +++ b/tests/integration/api_issue_test.go @@ -84,12 +84,12 @@ func TestAPICreateIssue(t *testing.T) { session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues?state=all&token=%s", owner.Name, repoBefore.Name, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues?state=all", owner.Name, repoBefore.Name) req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueOption{ Body: body, Title: title, Assignee: owner.Name, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var apiIssue api.Issue DecodeJSON(t, resp, &apiIssue) @@ -117,7 +117,7 @@ func TestAPICreateIssueParallel(t *testing.T) { session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues?state=all&token=%s", owner.Name, repoBefore.Name, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues?state=all", owner.Name, repoBefore.Name) var wg sync.WaitGroup for i := 0; i < 10; i++ { @@ -130,7 +130,7 @@ func TestAPICreateIssueParallel(t *testing.T) { Body: newBody, Title: newTitle, Assignee: owner.Name, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var apiIssue api.Issue DecodeJSON(t, resp, &apiIssue) @@ -171,7 +171,7 @@ func TestAPIEditIssue(t *testing.T) { body := "new content!" title := "new title from api set" - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d?token=%s", owner.Name, repoBefore.Name, issueBefore.Index, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d", owner.Name, repoBefore.Name, issueBefore.Index) req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditIssueOption{ State: &issueState, RemoveDeadline: &removeDeadline, @@ -180,7 +180,7 @@ func TestAPIEditIssue(t *testing.T) { Title: title, // ToDo change more - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var apiIssue api.Issue DecodeJSON(t, resp, &apiIssue) diff --git a/tests/integration/api_issue_tracked_time_test.go b/tests/integration/api_issue_tracked_time_test.go index d3e45456a6c61..fd2c452b20682 100644 --- a/tests/integration/api_issue_tracked_time_test.go +++ b/tests/integration/api_issue_tracked_time_test.go @@ -30,7 +30,8 @@ func TestAPIGetTrackedTimes(t *testing.T) { session := loginUser(t, user2.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadIssue) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/times?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/times", user2.Name, issue2.Repo.Name, issue2.Index). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiTimes api.TrackedTimeList DecodeJSON(t, resp, &apiTimes) @@ -53,7 +54,8 @@ func TestAPIGetTrackedTimes(t *testing.T) { since := "2000-01-01T00%3A00%3A02%2B00%3A00" // 946684802 before := "2000-01-01T00%3A00%3A12%2B00%3A00" // 946684812 - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/times?since=%s&before=%s&token=%s", user2.Name, issue2.Repo.Name, issue2.Index, since, before, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/times?since=%s&before=%s", user2.Name, issue2.Repo.Name, issue2.Index, since, before). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var filterAPITimes api.TrackedTimeList DecodeJSON(t, resp, &filterAPITimes) @@ -74,11 +76,13 @@ func TestAPIDeleteTrackedTime(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) // Deletion not allowed - req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time6.ID, token) + req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d", user2.Name, issue2.Repo.Name, issue2.Index, time6.ID). + AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) time3 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 3}) - req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time3.ID, token) + req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d", user2.Name, issue2.Repo.Name, issue2.Index, time3.ID). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // Delete non existing time MakeRequest(t, req, http.StatusNotFound) @@ -88,7 +92,8 @@ func TestAPIDeleteTrackedTime(t *testing.T) { assert.NoError(t, err) assert.Equal(t, int64(3661), trackedSeconds) - req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, token) + req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times", user2.Name, issue2.Repo.Name, issue2.Index). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) MakeRequest(t, req, http.StatusNotFound) @@ -108,13 +113,13 @@ func TestAPIAddTrackedTimes(t *testing.T) { session := loginUser(t, admin.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/times?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/times", user2.Name, issue2.Repo.Name, issue2.Index) req := NewRequestWithJSON(t, "POST", urlStr, &api.AddTimeOption{ Time: 33, User: user2.Name, Created: time.Unix(947688818, 0), - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiNewTime api.TrackedTime DecodeJSON(t, resp, &apiNewTime) diff --git a/tests/integration/api_keys_test.go b/tests/integration/api_keys_test.go index 03d28c9126656..89ad1ec0df510 100644 --- a/tests/integration/api_keys_test.go +++ b/tests/integration/api_keys_test.go @@ -55,13 +55,14 @@ func TestCreateReadOnlyDeployKey(t *testing.T) { session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - keysURL := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", repoOwner.Name, repo.Name, token) + keysURL := fmt.Sprintf("/api/v1/repos/%s/%s/keys", repoOwner.Name, repo.Name) rawKeyBody := api.CreateKeyOption{ Title: "read-only", Key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n", ReadOnly: true, } - req := NewRequestWithJSON(t, "POST", keysURL, rawKeyBody) + req := NewRequestWithJSON(t, "POST", keysURL, rawKeyBody). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var newDeployKey api.DeployKey @@ -75,12 +76,14 @@ func TestCreateReadOnlyDeployKey(t *testing.T) { // Using the ID of a key that does not belong to the repository must fail { - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/keys/%d?token=%s", repoOwner.Name, repo.Name, newDeployKey.ID, token)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/keys/%d", repoOwner.Name, repo.Name, newDeployKey.ID)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) session5 := loginUser(t, "user5") token5 := getTokenForLoggedInUser(t, session5, auth_model.AccessTokenScopeWriteRepository) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/user5/repo4/keys/%d?token=%s", newDeployKey.ID, token5)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/user5/repo4/keys/%d", newDeployKey.ID)). + AddTokenAuth(token5) MakeRequest(t, req, http.StatusNotFound) } } @@ -92,12 +95,13 @@ func TestCreateReadWriteDeployKey(t *testing.T) { session := loginUser(t, repoOwner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - keysURL := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", repoOwner.Name, repo.Name, token) + keysURL := fmt.Sprintf("/api/v1/repos/%s/%s/keys", repoOwner.Name, repo.Name) rawKeyBody := api.CreateKeyOption{ Title: "read-write", Key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n", } - req := NewRequestWithJSON(t, "POST", keysURL, rawKeyBody) + req := NewRequestWithJSON(t, "POST", keysURL, rawKeyBody). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var newDeployKey api.DeployKey @@ -116,14 +120,14 @@ func TestCreateUserKey(t *testing.T) { session := loginUser(t, "user1") token := url.QueryEscape(getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser)) - keysURL := fmt.Sprintf("/api/v1/user/keys?token=%s", token) keyType := "ssh-rsa" keyContent := "AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=" rawKeyBody := api.CreateKeyOption{ Title: "test-key", Key: keyType + " " + keyContent, } - req := NewRequestWithJSON(t, "POST", keysURL, rawKeyBody) + req := NewRequestWithJSON(t, "POST", "/api/v1/user/keys", rawKeyBody). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var newPublicKey api.PublicKey @@ -139,9 +143,8 @@ func TestCreateUserKey(t *testing.T) { }) // Search by fingerprint - fingerprintURL := fmt.Sprintf("/api/v1/user/keys?token=%s&fingerprint=%s", token, newPublicKey.Fingerprint) - - req = NewRequest(t, "GET", fingerprintURL) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/keys?fingerprint=%s", newPublicKey.Fingerprint)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var fingerprintPublicKeys []api.PublicKey @@ -150,9 +153,8 @@ func TestCreateUserKey(t *testing.T) { assert.Equal(t, newPublicKey.ID, fingerprintPublicKeys[0].ID) assert.Equal(t, user.ID, fingerprintPublicKeys[0].Owner.ID) - fingerprintURL = fmt.Sprintf("/api/v1/users/%s/keys?token=%s&fingerprint=%s", user.Name, token, newPublicKey.Fingerprint) - - req = NewRequest(t, "GET", fingerprintURL) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/keys?fingerprint=%s", user.Name, newPublicKey.Fingerprint)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &fingerprintPublicKeys) @@ -161,17 +163,16 @@ func TestCreateUserKey(t *testing.T) { assert.Equal(t, user.ID, fingerprintPublicKeys[0].Owner.ID) // Fail search by fingerprint - fingerprintURL = fmt.Sprintf("/api/v1/user/keys?token=%s&fingerprint=%sA", token, newPublicKey.Fingerprint) - - req = NewRequest(t, "GET", fingerprintURL) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/keys?fingerprint=%sA", newPublicKey.Fingerprint)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &fingerprintPublicKeys) assert.Len(t, fingerprintPublicKeys, 0) // Fail searching for wrong users key - fingerprintURL = fmt.Sprintf("/api/v1/users/%s/keys?token=%s&fingerprint=%s", "user2", token, newPublicKey.Fingerprint) - req = NewRequest(t, "GET", fingerprintURL) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/keys?fingerprint=%s", "user2", newPublicKey.Fingerprint)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &fingerprintPublicKeys) @@ -179,11 +180,11 @@ func TestCreateUserKey(t *testing.T) { // Now login as user 2 session2 := loginUser(t, "user2") - token2 := url.QueryEscape(getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeWriteUser)) + token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeWriteUser) // Should find key even though not ours, but we shouldn't know whose it is - fingerprintURL = fmt.Sprintf("/api/v1/user/keys?token=%s&fingerprint=%s", token2, newPublicKey.Fingerprint) - req = NewRequest(t, "GET", fingerprintURL) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/keys?fingerprint=%s", newPublicKey.Fingerprint)). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &fingerprintPublicKeys) @@ -192,9 +193,8 @@ func TestCreateUserKey(t *testing.T) { assert.Nil(t, fingerprintPublicKeys[0].Owner) // Should find key even though not ours, but we shouldn't know whose it is - fingerprintURL = fmt.Sprintf("/api/v1/users/%s/keys?token=%s&fingerprint=%s", user.Name, token2, newPublicKey.Fingerprint) - - req = NewRequest(t, "GET", fingerprintURL) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/keys?fingerprint=%s", user.Name, newPublicKey.Fingerprint)). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &fingerprintPublicKeys) @@ -203,8 +203,8 @@ func TestCreateUserKey(t *testing.T) { assert.Nil(t, fingerprintPublicKeys[0].Owner) // Fail when searching for key if it is not ours - fingerprintURL = fmt.Sprintf("/api/v1/users/%s/keys?token=%s&fingerprint=%s", "user2", token2, newPublicKey.Fingerprint) - req = NewRequest(t, "GET", fingerprintURL) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/keys?fingerprint=%s", "user2", newPublicKey.Fingerprint)). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &fingerprintPublicKeys) diff --git a/tests/integration/api_nodeinfo_test.go b/tests/integration/api_nodeinfo_test.go index fb35d72ac2ffc..a727aea3ce8df 100644 --- a/tests/integration/api_nodeinfo_test.go +++ b/tests/integration/api_nodeinfo_test.go @@ -24,7 +24,7 @@ func TestNodeinfo(t *testing.T) { }() onGiteaRun(t, func(*testing.T, *url.URL) { - req := NewRequestf(t, "GET", "/api/v1/nodeinfo") + req := NewRequest(t, "GET", "/api/v1/nodeinfo") resp := MakeRequest(t, req, http.StatusOK) VerifyJSONSchema(t, resp, "nodeinfo_2.1.json") diff --git a/tests/integration/api_notification_test.go b/tests/integration/api_notification_test.go index c6ee576e5921c..528890ca22bd0 100644 --- a/tests/integration/api_notification_test.go +++ b/tests/integration/api_notification_test.go @@ -35,7 +35,8 @@ func TestAPINotification(t *testing.T) { // -- GET /notifications -- // test filter since := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801 - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?since=%s&token=%s", since, token)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?since=%s", since)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiNL []api.NotificationThread DecodeJSON(t, resp, &apiNL) @@ -46,7 +47,8 @@ func TestAPINotification(t *testing.T) { // test filter before := "2000-01-01T01%3A06%3A59%2B00%3A00" // 946688819 - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?all=%s&before=%s&token=%s", "true", before, token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?all=%s&before=%s", "true", before)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) @@ -62,7 +64,8 @@ func TestAPINotification(t *testing.T) { assert.False(t, apiNL[2].Pinned) // -- GET /repos/{owner}/{repo}/notifications -- - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?status-types=unread&token=%s", user2.Name, repo1.Name, token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?status-types=unread", user2.Name, repo1.Name)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) @@ -70,7 +73,8 @@ func TestAPINotification(t *testing.T) { assert.EqualValues(t, 4, apiNL[0].ID) // -- GET /repos/{owner}/{repo}/notifications -- multiple status-types - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?status-types=unread&status-types=pinned&token=%s", user2.Name, repo1.Name, token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?status-types=unread&status-types=pinned", user2.Name, repo1.Name)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) @@ -86,11 +90,13 @@ func TestAPINotification(t *testing.T) { // -- GET /notifications/threads/{id} -- // get forbidden - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/threads/%d?token=%s", 1, token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/threads/%d", 1)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) // get own - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/threads/%d?token=%s", thread5.ID, token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/threads/%d", thread5.ID)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var apiN api.NotificationThread DecodeJSON(t, resp, &apiN) @@ -110,28 +116,33 @@ func TestAPINotification(t *testing.T) { }{} // -- check notifications -- - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/new?token=%s", token)) + req = NewRequest(t, "GET", "/api/v1/notifications/new"). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &new) assert.True(t, new.New > 0) // -- mark notifications as read -- - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?status-types=unread&token=%s", token)) + req = NewRequest(t, "GET", "/api/v1/notifications?status-types=unread"). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) assert.Len(t, apiNL, 2) lastReadAt := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801 <- only Notification 4 is in this filter ... - req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token)) + req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s", user2.Name, repo1.Name, lastReadAt)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusResetContent) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?status-types=unread&token=%s", token)) + req = NewRequest(t, "GET", "/api/v1/notifications?status-types=unread"). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) assert.Len(t, apiNL, 1) // -- PATCH /notifications/threads/{id} -- - req = NewRequest(t, "PATCH", fmt.Sprintf("/api/v1/notifications/threads/%d?token=%s", thread5.ID, token)) + req = NewRequest(t, "PATCH", fmt.Sprintf("/api/v1/notifications/threads/%d", thread5.ID)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusResetContent) assert.Equal(t, activities_model.NotificationStatusUnread, thread5.Status) @@ -139,7 +150,8 @@ func TestAPINotification(t *testing.T) { assert.Equal(t, activities_model.NotificationStatusRead, thread5.Status) // -- check notifications -- - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications/new?token=%s", token)) + req = NewRequest(t, "GET", "/api/v1/notifications/new"). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &new) assert.True(t, new.New == 0) @@ -155,7 +167,8 @@ func TestAPINotificationPUT(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteNotification) // Check notifications are as expected - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?all=true&token=%s", token)) + req := NewRequest(t, "GET", "/api/v1/notifications?all=true"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiNL []api.NotificationThread DecodeJSON(t, resp, &apiNL) @@ -178,7 +191,8 @@ func TestAPINotificationPUT(t *testing.T) { // Notification ID 2 is the only one with status-type read & pinned // change it to unread. // - req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/notifications?status-types=read&status-type=pinned&to-status=unread&token=%s", token)) + req = NewRequest(t, "PUT", "/api/v1/notifications?status-types=read&status-type=pinned&to-status=unread"). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusResetContent) DecodeJSON(t, resp, &apiNL) assert.Len(t, apiNL, 1) @@ -189,7 +203,8 @@ func TestAPINotificationPUT(t *testing.T) { // // Now nofication ID 2 is the first in the list and is unread. // - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?all=true&token=%s", token)) + req = NewRequest(t, "GET", "/api/v1/notifications?all=true"). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) diff --git a/tests/integration/api_oauth2_apps_test.go b/tests/integration/api_oauth2_apps_test.go index 72cdba2ea2f6e..0ea3dc72ff98a 100644 --- a/tests/integration/api_oauth2_apps_test.go +++ b/tests/integration/api_oauth2_apps_test.go @@ -36,8 +36,8 @@ func testAPICreateOAuth2Application(t *testing.T) { ConfidentialClient: true, } - req := NewRequestWithJSON(t, "POST", "/api/v1/user/applications/oauth2", &appBody) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithJSON(t, "POST", "/api/v1/user/applications/oauth2", &appBody). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusCreated) var createdApp *api.OAuth2Application @@ -66,8 +66,8 @@ func testAPIListOAuth2Applications(t *testing.T) { ConfidentialClient: true, }) - urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2?token=%s", token) - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", "/api/v1/user/applications/oauth2"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var appList api.OAuth2ApplicationList @@ -93,14 +93,16 @@ func testAPIDeleteOAuth2Application(t *testing.T) { Name: "test-app-1", }) - urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d?token=%s", oldApp.ID, token) - req := NewRequest(t, "DELETE", urlStr) + urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d", oldApp.ID) + req := NewRequest(t, "DELETE", urlStr). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) unittest.AssertNotExistsBean(t, &auth_model.OAuth2Application{UID: oldApp.UID, Name: oldApp.Name}) // Delete again will return not found - req = NewRequest(t, "DELETE", urlStr) + req = NewRequest(t, "DELETE", urlStr). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) } @@ -118,8 +120,8 @@ func testAPIGetOAuth2Application(t *testing.T) { ConfidentialClient: true, }) - urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d?token=%s", existApp.ID, token) - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/applications/oauth2/%d", existApp.ID)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var app api.OAuth2Application @@ -157,8 +159,8 @@ func testAPIUpdateOAuth2Application(t *testing.T) { } urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d", existApp.ID) - req := NewRequestWithJSON(t, "PATCH", urlStr, &appBody) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithJSON(t, "PATCH", urlStr, &appBody). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var app api.OAuth2Application diff --git a/tests/integration/api_org_avatar_test.go b/tests/integration/api_org_avatar_test.go index 91100c8eb7833..cc1452c1535da 100644 --- a/tests/integration/api_org_avatar_test.go +++ b/tests/integration/api_org_avatar_test.go @@ -34,7 +34,8 @@ func TestAPIUpdateOrgAvatar(t *testing.T) { Image: base64.StdEncoding.EncodeToString(avatar), } - req := NewRequestWithJSON(t, "POST", "/api/v1/orgs/org3/avatar?token="+token, &opts) + req := NewRequestWithJSON(t, "POST", "/api/v1/orgs/org3/avatar", &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // Test what happens if you don't have a valid Base64 string @@ -42,7 +43,8 @@ func TestAPIUpdateOrgAvatar(t *testing.T) { Image: "Invalid", } - req = NewRequestWithJSON(t, "POST", "/api/v1/orgs/org3/avatar?token="+token, &opts) + req = NewRequestWithJSON(t, "POST", "/api/v1/orgs/org3/avatar", &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusBadRequest) // Test what happens if you use a file that is not an image @@ -56,7 +58,8 @@ func TestAPIUpdateOrgAvatar(t *testing.T) { Image: base64.StdEncoding.EncodeToString(text), } - req = NewRequestWithJSON(t, "POST", "/api/v1/orgs/org3/avatar?token="+token, &opts) + req = NewRequestWithJSON(t, "POST", "/api/v1/orgs/org3/avatar", &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusInternalServerError) } @@ -67,6 +70,7 @@ func TestAPIDeleteOrgAvatar(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) - req := NewRequest(t, "DELETE", "/api/v1/orgs/org3/avatar?token="+token) + req := NewRequest(t, "DELETE", "/api/v1/orgs/org3/avatar"). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) } diff --git a/tests/integration/api_org_test.go b/tests/integration/api_org_test.go index f19b46c2f449e..1cd82fe4e09ca 100644 --- a/tests/integration/api_org_test.go +++ b/tests/integration/api_org_test.go @@ -36,7 +36,8 @@ func TestAPIOrgCreate(t *testing.T) { Location: "Shanghai", Visibility: "limited", } - req := NewRequestWithJSON(t, "POST", "/api/v1/orgs?token="+token, &org) + req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &org). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var apiOrg api.Organization @@ -71,12 +72,14 @@ func TestAPIOrgCreate(t *testing.T) { }) } - req = NewRequestf(t, "GET", "/api/v1/orgs/%s?token=%s", org.UserName, token) + req = NewRequestf(t, "GET", "/api/v1/orgs/%s", org.UserName). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiOrg) assert.EqualValues(t, org.UserName, apiOrg.Name) - req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos?token=%s", org.UserName, token) + req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", org.UserName). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var repos []*api.Repository @@ -85,7 +88,8 @@ func TestAPIOrgCreate(t *testing.T) { assert.False(t, repo.Private) } - req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members?token=%s", org.UserName, token) + req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members", org.UserName). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) // user1 on this org is public @@ -108,7 +112,8 @@ func TestAPIOrgEdit(t *testing.T) { Location: "Beijing", Visibility: "private", } - req := NewRequestWithJSON(t, "PATCH", "/api/v1/orgs/org3?token="+token, &org) + req := NewRequestWithJSON(t, "PATCH", "/api/v1/orgs/org3", &org). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiOrg api.Organization @@ -135,7 +140,8 @@ func TestAPIOrgEditBadVisibility(t *testing.T) { Location: "Beijing", Visibility: "badvisibility", } - req := NewRequestWithJSON(t, "PATCH", "/api/v1/orgs/org3?token="+token, &org) + req := NewRequestWithJSON(t, "PATCH", "/api/v1/orgs/org3", &org). + AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) }) } @@ -165,7 +171,8 @@ func TestAPIGetAll(t *testing.T) { token := getUserToken(t, "user1", auth_model.AccessTokenScopeReadOrganization) // accessing with a token will return all orgs - req := NewRequestf(t, "GET", "/api/v1/orgs?token=%s", token) + req := NewRequest(t, "GET", "/api/v1/orgs"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiOrgList []*api.Organization @@ -175,7 +182,7 @@ func TestAPIGetAll(t *testing.T) { assert.Equal(t, "limited", apiOrgList[1].Visibility) // accessing without a token will return only public orgs - req = NewRequestf(t, "GET", "/api/v1/orgs") + req = NewRequest(t, "GET", "/api/v1/orgs") resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiOrgList) @@ -190,22 +197,23 @@ func TestAPIOrgSearchEmptyTeam(t *testing.T) { orgName := "org_with_empty_team" // create org - req := NewRequestWithJSON(t, "POST", "/api/v1/orgs?token="+token, &api.CreateOrgOption{ + req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &api.CreateOrgOption{ UserName: orgName, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) // create team with no member - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams?token=%s", orgName, token), &api.CreateTeamOption{ + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams", orgName), &api.CreateTeamOption{ Name: "Empty", IncludesAllRepositories: true, Permission: "read", Units: []string{"repo.code", "repo.issues", "repo.ext_issues", "repo.wiki", "repo.pulls"}, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) // case-insensitive search for teams that have no members - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/orgs/%s/teams/search?q=%s&token=%s", orgName, "empty", token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/orgs/%s/teams/search?q=%s", orgName, "empty")). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) data := struct { Ok bool diff --git a/tests/integration/api_packages_alpine_test.go b/tests/integration/api_packages_alpine_test.go index 9a2acf854c4d8..3cc7178e028b4 100644 --- a/tests/integration/api_packages_alpine_test.go +++ b/tests/integration/api_packages_alpine_test.go @@ -85,12 +85,12 @@ Djfa/2q5bH4699v++uMAAAAAAAAAAAAAAAAAAAAAAHbgA/eXQh8AKAAA` req := NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader([]byte{})) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader([]byte{})) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader([]byte{})). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) - req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeAlpine) @@ -216,8 +216,8 @@ Djfa/2q5bH4699v++uMAAAAAAAAAAAAAAAAAAAAAAHbgA/eXQh8AKAAA` req := NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s/x86_64/%s-%s.apk", rootURL, branch, repository, packageName, packageVersion)) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s/x86_64/%s-%s.apk", rootURL, branch, repository, packageName, packageVersion)) - AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s/x86_64/%s-%s.apk", rootURL, branch, repository, packageName, packageVersion)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) // Deleting the last file of an architecture should remove that index diff --git a/tests/integration/api_packages_cargo_test.go b/tests/integration/api_packages_cargo_test.go index 03d8e0c5207e7..6b8154af457a6 100644 --- a/tests/integration/api_packages_cargo_test.go +++ b/tests/integration/api_packages_cargo_test.go @@ -132,8 +132,8 @@ func testPackageCargo(t *testing.T, _ *neturl.URL) { content := createPackage("0test", "1.0.0") - req := NewRequestWithBody(t, "PUT", url+"/new", content) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url+"/new", content). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusBadRequest) var status cargo_router.StatusResponse @@ -142,8 +142,8 @@ func testPackageCargo(t *testing.T, _ *neturl.URL) { content = createPackage("test", "-1.0.0") - req = NewRequestWithBody(t, "PUT", url+"/new", content) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", url+"/new", content). + AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusBadRequest) DecodeJSON(t, resp, &status) @@ -161,8 +161,8 @@ func testPackageCargo(t *testing.T, _ *neturl.URL) { binary.Write(&buf, binary.LittleEndian, uint32(4)) buf.WriteString("te") - req := NewRequestWithBody(t, "PUT", url+"/new", &buf) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url+"/new", &buf). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) }) @@ -172,8 +172,8 @@ func testPackageCargo(t *testing.T, _ *neturl.URL) { req := NewRequestWithBody(t, "PUT", url+"/new", createPackage(packageName, packageVersion)) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequestWithBody(t, "PUT", url+"/new", createPackage(packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", url+"/new", createPackage(packageName, packageVersion)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var status cargo_router.StatusResponse @@ -201,8 +201,8 @@ func testPackageCargo(t *testing.T, _ *neturl.URL) { assert.NoError(t, err) assert.EqualValues(t, 4, pb.Size) - req = NewRequestWithBody(t, "PUT", url+"/new", createPackage(packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", url+"/new", createPackage(packageName, packageVersion)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) t.Run("Index", func(t *testing.T) { @@ -288,8 +288,8 @@ func testPackageCargo(t *testing.T, _ *neturl.URL) { assert.NoError(t, err) assert.Len(t, pfs, 1) - req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s/download", url, neturl.PathEscape(packageName), neturl.PathEscape(pv.Version))) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s/download", url, neturl.PathEscape(packageName), neturl.PathEscape(pv.Version))). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "test", resp.Body.String()) @@ -318,8 +318,8 @@ func testPackageCargo(t *testing.T, _ *neturl.URL) { } for i, c := range cases { - req := NewRequest(t, "GET", fmt.Sprintf("%s?q=%s&page=%d&per_page=%d", url, c.Query, c.Page, c.PerPage)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s?q=%s&page=%d&per_page=%d", url, c.Query, c.Page, c.PerPage)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result cargo_router.SearchResult @@ -333,8 +333,8 @@ func testPackageCargo(t *testing.T, _ *neturl.URL) { t.Run("Yank", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s/yank", url, neturl.PathEscape(packageName), neturl.PathEscape(packageVersion))) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s/yank", url, neturl.PathEscape(packageName), neturl.PathEscape(packageVersion))). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var status cargo_router.StatusResponse @@ -353,8 +353,8 @@ func testPackageCargo(t *testing.T, _ *neturl.URL) { t.Run("Unyank", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "PUT", fmt.Sprintf("%s/%s/%s/unyank", url, neturl.PathEscape(packageName), neturl.PathEscape(packageVersion))) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "PUT", fmt.Sprintf("%s/%s/%s/unyank", url, neturl.PathEscape(packageName), neturl.PathEscape(packageVersion))). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var status cargo_router.StatusResponse diff --git a/tests/integration/api_packages_chef_test.go b/tests/integration/api_packages_chef_test.go index 7f55a84f09198..4123c7216c4dd 100644 --- a/tests/integration/api_packages_chef_test.go +++ b/tests/integration/api_packages_chef_test.go @@ -93,7 +93,7 @@ nwIDAQAB defer tests.PrintCurrentTest(t)() req := NewRequest(t, "POST", "/dummy") - u, err := auth.Verify(req, nil, nil, nil) + u, err := auth.Verify(req.Request, nil, nil, nil) assert.Nil(t, u) assert.NoError(t, err) }) @@ -101,9 +101,9 @@ nwIDAQAB t.Run("NotExistingUser", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "POST", "/dummy") - req.Header.Set("X-Ops-Userid", "not-existing-user") - u, err := auth.Verify(req, nil, nil, nil) + req := NewRequest(t, "POST", "/dummy"). + SetHeader("X-Ops-Userid", "not-existing-user") + u, err := auth.Verify(req.Request, nil, nil, nil) assert.Nil(t, u) assert.Error(t, err) }) @@ -111,14 +111,14 @@ nwIDAQAB t.Run("Timestamp", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "POST", "/dummy") - req.Header.Set("X-Ops-Userid", user.Name) - u, err := auth.Verify(req, nil, nil, nil) + req := NewRequest(t, "POST", "/dummy"). + SetHeader("X-Ops-Userid", user.Name) + u, err := auth.Verify(req.Request, nil, nil, nil) assert.Nil(t, u) assert.Error(t, err) - req.Header.Set("X-Ops-Timestamp", "2023-01-01T00:00:00Z") - u, err = auth.Verify(req, nil, nil, nil) + req.SetHeader("X-Ops-Timestamp", "2023-01-01T00:00:00Z") + u, err = auth.Verify(req.Request, nil, nil, nil) assert.Nil(t, u) assert.Error(t, err) }) @@ -126,30 +126,30 @@ nwIDAQAB t.Run("SigningVersion", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "POST", "/dummy") - req.Header.Set("X-Ops-Userid", user.Name) - req.Header.Set("X-Ops-Timestamp", time.Now().UTC().Format(time.RFC3339)) - u, err := auth.Verify(req, nil, nil, nil) + req := NewRequest(t, "POST", "/dummy"). + SetHeader("X-Ops-Userid", user.Name). + SetHeader("X-Ops-Timestamp", time.Now().UTC().Format(time.RFC3339)) + u, err := auth.Verify(req.Request, nil, nil, nil) assert.Nil(t, u) assert.Error(t, err) - req.Header.Set("X-Ops-Sign", "version=none") - u, err = auth.Verify(req, nil, nil, nil) + req.SetHeader("X-Ops-Sign", "version=none") + u, err = auth.Verify(req.Request, nil, nil, nil) assert.Nil(t, u) assert.Error(t, err) - req.Header.Set("X-Ops-Sign", "version=1.4") - u, err = auth.Verify(req, nil, nil, nil) + req.SetHeader("X-Ops-Sign", "version=1.4") + u, err = auth.Verify(req.Request, nil, nil, nil) assert.Nil(t, u) assert.Error(t, err) - req.Header.Set("X-Ops-Sign", "version=1.0;algorithm=sha2") - u, err = auth.Verify(req, nil, nil, nil) + req.SetHeader("X-Ops-Sign", "version=1.0;algorithm=sha2") + u, err = auth.Verify(req.Request, nil, nil, nil) assert.Nil(t, u) assert.Error(t, err) - req.Header.Set("X-Ops-Sign", "version=1.0;algorithm=sha256") - u, err = auth.Verify(req, nil, nil, nil) + req.SetHeader("X-Ops-Sign", "version=1.0;algorithm=sha256") + u, err = auth.Verify(req.Request, nil, nil, nil) assert.Nil(t, u) assert.Error(t, err) }) @@ -159,17 +159,18 @@ nwIDAQAB ts := time.Now().UTC().Format(time.RFC3339) - req := NewRequest(t, "POST", "/dummy") - req.Header.Set("X-Ops-Userid", user.Name) - req.Header.Set("X-Ops-Timestamp", ts) - req.Header.Set("X-Ops-Sign", "version=1.0;algorithm=sha1") - req.Header.Set("X-Ops-Content-Hash", "unused") - req.Header.Set("X-Ops-Authorization-4", "dummy") - u, err := auth.Verify(req, nil, nil, nil) + req := NewRequest(t, "POST", "/dummy"). + SetHeader("X-Ops-Userid", user.Name). + SetHeader("X-Ops-Timestamp", ts). + SetHeader("X-Ops-Sign", "version=1.0;algorithm=sha1"). + SetHeader("X-Ops-Content-Hash", "unused"). + SetHeader("X-Ops-Authorization-4", "dummy") + u, err := auth.Verify(req.Request, nil, nil, nil) assert.Nil(t, u) assert.Error(t, err) - signRequest := func(t *testing.T, req *http.Request, version string) { + signRequest := func(t *testing.T, rw *RequestWrapper, version string) { + req := rw.Request username := req.Header.Get("X-Ops-Userid") if version != "1.0" && version != "1.3" { sum := sha1.Sum([]byte(username)) @@ -255,7 +256,7 @@ nwIDAQAB defer tests.PrintCurrentTest(t)() signRequest(t, req, v) - u, err = auth.Verify(req, nil, nil, nil) + u, err = auth.Verify(req.Request, nil, nil, nil) assert.NotNil(t, u) assert.NoError(t, err) }) @@ -291,9 +292,9 @@ nwIDAQAB zw.Close() mpw.Close() - req := NewRequestWithBody(t, "POST", root+"/cookbooks", &body) - req.Header.Add("Content-Type", mpw.FormDataContentType()) - AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "POST", root+"/cookbooks", &body). + SetHeader("Content-Type", mpw.FormDataContentType()). + AddBasicAuth(user.Name) MakeRequest(t, req, expectedStatus) } @@ -394,8 +395,8 @@ nwIDAQAB } for i, c := range cases { - req := NewRequest(t, "GET", fmt.Sprintf("%s/search?q=%s&start=%d&items=%d", root, c.Query, c.Start, c.Items)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/search?q=%s&start=%d&items=%d", root, c.Query, c.Start, c.Items)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result Result @@ -445,8 +446,8 @@ nwIDAQAB } for i, c := range cases { - req := NewRequest(t, "GET", fmt.Sprintf("%s/cookbooks?start=%d&items=%d&sort=%s", root, c.Start, c.Items, c.Sort)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/cookbooks?start=%d&items=%d&sort=%s", root, c.Start, c.Items, c.Sort)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result Result @@ -533,8 +534,8 @@ nwIDAQAB req := NewRequest(t, "DELETE", fmt.Sprintf("%s/cookbooks/%s/versions/%s", root, packageName, "1.0.2")) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/cookbooks/%s/versions/%s", root, packageName, "1.0.2")) - AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/cookbooks/%s/versions/%s", root, packageName, "1.0.2")). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusOK) pv, err := packages.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages.TypeChef, packageName, "1.0.2") @@ -548,8 +549,8 @@ nwIDAQAB req := NewRequest(t, "DELETE", fmt.Sprintf("%s/cookbooks/%s", root, packageName)) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/cookbooks/%s", root, packageName)) - AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/cookbooks/%s", root, packageName)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusOK) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeChef) diff --git a/tests/integration/api_packages_composer_test.go b/tests/integration/api_packages_composer_test.go index 896462d9a9fd0..6e0d2eee1b347 100644 --- a/tests/integration/api_packages_composer_test.go +++ b/tests/integration/api_packages_composer_test.go @@ -59,8 +59,8 @@ func TestPackageComposer(t *testing.T) { t.Run("ServiceIndex", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/packages.json", url)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/packages.json", url)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result composer.ServiceIndexResponse @@ -75,8 +75,8 @@ func TestPackageComposer(t *testing.T) { t.Run("MissingVersion", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) }) @@ -85,8 +85,8 @@ func TestPackageComposer(t *testing.T) { uploadURL := url + "?version=" + packageVersion - req := NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeComposer) @@ -110,8 +110,8 @@ func TestPackageComposer(t *testing.T) { assert.NoError(t, err) assert.Equal(t, int64(len(content)), pb.Size) - req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) }) }) @@ -128,8 +128,8 @@ func TestPackageComposer(t *testing.T) { assert.NoError(t, err) assert.Len(t, pfs, 1) - req := NewRequest(t, "GET", fmt.Sprintf("%s/files/%s/%s/%s", url, neturl.PathEscape(packageName), neturl.PathEscape(pvs[0].LowerVersion), neturl.PathEscape(pfs[0].LowerName))) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/files/%s/%s/%s", url, neturl.PathEscape(packageName), neturl.PathEscape(pvs[0].LowerVersion), neturl.PathEscape(pfs[0].LowerName))). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, content, resp.Body.Bytes()) @@ -162,8 +162,8 @@ func TestPackageComposer(t *testing.T) { } for i, c := range cases { - req := NewRequest(t, "GET", fmt.Sprintf("%s/search.json?q=%s&type=%s&page=%d&per_page=%d", url, c.Query, c.Type, c.Page, c.PerPage)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/search.json?q=%s&type=%s&page=%d&per_page=%d", url, c.Query, c.Type, c.Page, c.PerPage)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result composer.SearchResultResponse @@ -177,8 +177,8 @@ func TestPackageComposer(t *testing.T) { t.Run("EnumeratePackages", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", url+"/list.json") - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", url+"/list.json"). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result map[string][]string @@ -193,8 +193,8 @@ func TestPackageComposer(t *testing.T) { t.Run("PackageMetadata", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/p2/%s/%s.json", url, vendorName, projectName)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/p2/%s/%s.json", url, vendorName, projectName)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result composer.PackageMetadataResponse diff --git a/tests/integration/api_packages_conan_test.go b/tests/integration/api_packages_conan_test.go index ab128bf4a5eb6..a25713f039ffd 100644 --- a/tests/integration/api_packages_conan_test.go +++ b/tests/integration/api_packages_conan_test.go @@ -62,11 +62,6 @@ const ( CC=gcc-10` ) -func addTokenAuthHeader(request *http.Request, token string) *http.Request { - request.Header.Set("Authorization", token) - return request -} - func buildConanfileContent(name, version string) string { return `from conans import ConanFile, CMake, tools @@ -90,16 +85,16 @@ func uploadConanPackageV1(t *testing.T, baseURL, token, name, version, user, cha recipeURL := fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s", baseURL, name, version, user, channel) - req := NewRequest(t, "GET", recipeURL) - req = addTokenAuthHeader(req, token) + req := NewRequest(t, "GET", recipeURL). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("%s/digest", recipeURL)) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", fmt.Sprintf("%s/digest", recipeURL)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("%s/download_urls", recipeURL)) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", fmt.Sprintf("%s/download_urls", recipeURL)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) req = NewRequest(t, "POST", fmt.Sprintf("%s/upload_urls", recipeURL)) @@ -108,8 +103,7 @@ func uploadConanPackageV1(t *testing.T, baseURL, token, name, version, user, cha req = NewRequestWithJSON(t, "POST", fmt.Sprintf("%s/upload_urls", recipeURL), map[string]int64{ conanfileName: int64(len(contentConanfile)), "removed.txt": 0, - }) - req = addTokenAuthHeader(req, token) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) uploadURLs := make(map[string]string) @@ -121,22 +115,22 @@ func uploadConanPackageV1(t *testing.T, baseURL, token, name, version, user, cha uploadURL := uploadURLs[conanfileName] assert.NotEmpty(t, uploadURL) - req = NewRequestWithBody(t, "PUT", uploadURL, strings.NewReader(contentConanfile)) - req = addTokenAuthHeader(req, token) + req = NewRequestWithBody(t, "PUT", uploadURL, strings.NewReader(contentConanfile)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) packageURL := fmt.Sprintf("%s/packages/%s", recipeURL, conanPackageReference) - req = NewRequest(t, "GET", packageURL) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", packageURL). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("%s/digest", packageURL)) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", fmt.Sprintf("%s/digest", packageURL)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("%s/download_urls", packageURL)) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", fmt.Sprintf("%s/download_urls", packageURL)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) req = NewRequest(t, "POST", fmt.Sprintf("%s/upload_urls", packageURL)) @@ -145,8 +139,7 @@ func uploadConanPackageV1(t *testing.T, baseURL, token, name, version, user, cha req = NewRequestWithJSON(t, "POST", fmt.Sprintf("%s/upload_urls", packageURL), map[string]int64{ conaninfoName: int64(len(contentConaninfo)), "removed.txt": 0, - }) - req = addTokenAuthHeader(req, token) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) uploadURLs = make(map[string]string) @@ -158,8 +151,8 @@ func uploadConanPackageV1(t *testing.T, baseURL, token, name, version, user, cha uploadURL = uploadURLs[conaninfoName] assert.NotEmpty(t, uploadURL) - req = NewRequestWithBody(t, "PUT", uploadURL, strings.NewReader(contentConaninfo)) - req = addTokenAuthHeader(req, token) + req = NewRequestWithBody(t, "PUT", uploadURL, strings.NewReader(contentConaninfo)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) } @@ -168,12 +161,12 @@ func uploadConanPackageV2(t *testing.T, baseURL, token, name, version, user, cha recipeURL := fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s", baseURL, name, version, user, channel, recipeRevision) - req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/files/%s", recipeURL, conanfileName), strings.NewReader(contentConanfile)) - req = addTokenAuthHeader(req, token) + req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/files/%s", recipeURL, conanfileName), strings.NewReader(contentConanfile)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) - req = NewRequest(t, "GET", fmt.Sprintf("%s/files", recipeURL)) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", fmt.Sprintf("%s/files", recipeURL)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var list *struct { @@ -185,16 +178,16 @@ func uploadConanPackageV2(t *testing.T, baseURL, token, name, version, user, cha packageURL := fmt.Sprintf("%s/packages/%s/revisions/%s", recipeURL, conanPackageReference, packageRevision) - req = NewRequest(t, "GET", fmt.Sprintf("%s/files", packageURL)) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", fmt.Sprintf("%s/files", packageURL)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/files/%s", packageURL, conaninfoName), strings.NewReader(contentConaninfo)) - req = addTokenAuthHeader(req, token) + req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/files/%s", packageURL, conaninfoName), strings.NewReader(contentConaninfo)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) - req = NewRequest(t, "GET", fmt.Sprintf("%s/files", packageURL)) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", fmt.Sprintf("%s/files", packageURL)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) list = nil @@ -235,21 +228,19 @@ func TestPackageConan(t *testing.T) { t.Run("Authenticate", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/users/authenticate", url)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/users/authenticate", url)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) - body := resp.Body.String() - assert.NotEmpty(t, body) - - token = fmt.Sprintf("Bearer %s", body) + token = resp.Body.String() + assert.NotEmpty(t, token) }) t.Run("CheckCredentials", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/users/check_credentials", url)) - req = addTokenAuthHeader(req, token) + req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/users/check_credentials", url)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) }) @@ -440,8 +431,7 @@ func TestPackageConan(t *testing.T) { req := NewRequestWithJSON(t, "POST", fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s/packages/delete", url, name, version1, user1, c.Channel), map[string][]string{ "package_ids": c.References, - }) - req = addTokenAuthHeader(req, token) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) references, err = conan_model.GetPackageReferences(db.DefaultContext, user.ID, rref) @@ -466,8 +456,8 @@ func TestPackageConan(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, revisions) - req := NewRequest(t, "DELETE", fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s", url, name, version1, user1, c.Channel)) - req = addTokenAuthHeader(req, token) + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s", url, name, version1, user1, c.Channel)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) revisions, err = conan_model.GetRecipeRevisions(db.DefaultContext, user.ID, rref) @@ -493,8 +483,8 @@ func TestPackageConan(t *testing.T) { t.Run("Authenticate", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/users/authenticate", url)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/users/authenticate", url)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) body := resp.Body.String() @@ -506,8 +496,8 @@ func TestPackageConan(t *testing.T) { t.Run("CheckCredentials", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/users/check_credentials", url)) - req = addTokenAuthHeader(req, token) + req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/users/check_credentials", url)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) }) @@ -672,14 +662,14 @@ func TestPackageConan(t *testing.T) { checkPackageRevisionCount(2) - req := NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages/%s/revisions/%s", url, name, version1, user1, channel1, revision1, conanPackageReference, revision1)) - req = addTokenAuthHeader(req, token) + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages/%s/revisions/%s", url, name, version1, user1, channel1, revision1, conanPackageReference, revision1)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) checkPackageRevisionCount(1) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages/%s", url, name, version1, user1, channel1, revision1, conanPackageReference)) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages/%s", url, name, version1, user1, channel1, revision1, conanPackageReference)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) checkPackageRevisionCount(0) @@ -688,8 +678,8 @@ func TestPackageConan(t *testing.T) { checkPackageReferenceCount(1) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages", url, name, version1, user1, channel1, revision2)) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s/packages", url, name, version1, user1, channel1, revision2)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) checkPackageReferenceCount(0) @@ -708,14 +698,14 @@ func TestPackageConan(t *testing.T) { checkRecipeRevisionCount(2) - req := NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s", url, name, version1, user1, channel1, revision1)) - req = addTokenAuthHeader(req, token) + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s/revisions/%s", url, name, version1, user1, channel1, revision1)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) checkRecipeRevisionCount(1) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s", url, name, version1, user1, channel1)) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s", url, name, version1, user1, channel1)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) checkRecipeRevisionCount(0) diff --git a/tests/integration/api_packages_conda_test.go b/tests/integration/api_packages_conda_test.go index daa7dca55fa2e..bb269e82d603a 100644 --- a/tests/integration/api_packages_conda_test.go +++ b/tests/integration/api_packages_conda_test.go @@ -66,12 +66,12 @@ func TestPackageConda(t *testing.T) { req := NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes())) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes())) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes())). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) - req = NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes())) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes())). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeConda) @@ -107,12 +107,12 @@ func TestPackageConda(t *testing.T) { req := NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes())) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes())) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes())). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) - req = NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes())) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes())). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeConda) diff --git a/tests/integration/api_packages_container_test.go b/tests/integration/api_packages_container_test.go index 93b4ff46241a0..f32d33888b400 100644 --- a/tests/integration/api_packages_container_test.go +++ b/tests/integration/api_packages_container_test.go @@ -103,8 +103,8 @@ func TestPackageContainer(t *testing.T) { anonymousToken = fmt.Sprintf("Bearer %s", tokenResponse.Token) - req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)) - addTokenAuthHeader(req, anonymousToken) + req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). + AddTokenAuth(anonymousToken) MakeRequest(t, req, http.StatusOK) }) @@ -116,8 +116,8 @@ func TestPackageContainer(t *testing.T) { assert.ElementsMatch(t, authenticate, resp.Header().Values("WWW-Authenticate")) - req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)). + AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusOK) tokenResponse := &TokenResponse{} @@ -127,8 +127,8 @@ func TestPackageContainer(t *testing.T) { userToken = fmt.Sprintf("Bearer %s", tokenResponse.Token) - req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusOK) }) }) @@ -136,8 +136,8 @@ func TestPackageContainer(t *testing.T) { t.Run("DetermineSupport", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)) - addTokenAuthHeader(req, userToken) + req := NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). + AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "registry/2.0", resp.Header().Get("Docker-Distribution-Api-Version")) }) @@ -149,16 +149,16 @@ func TestPackageContainer(t *testing.T) { t.Run("UploadBlob/Monolithic", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)) - addTokenAuthHeader(req, anonymousToken) + req := NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + AddTokenAuth(anonymousToken) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequestWithBody(t, "POST", fmt.Sprintf("%s/blobs/uploads?digest=%s", url, unknownDigest), bytes.NewReader(blobContent)) - addTokenAuthHeader(req, userToken) + req = NewRequestWithBody(t, "POST", fmt.Sprintf("%s/blobs/uploads?digest=%s", url, unknownDigest), bytes.NewReader(blobContent)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusBadRequest) - req = NewRequestWithBody(t, "POST", fmt.Sprintf("%s/blobs/uploads?digest=%s", url, blobDigest), bytes.NewReader(blobContent)) - addTokenAuthHeader(req, userToken) + req = NewRequestWithBody(t, "POST", fmt.Sprintf("%s/blobs/uploads?digest=%s", url, blobDigest), bytes.NewReader(blobContent)). + AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusCreated) assert.Equal(t, fmt.Sprintf("/v2/%s/%s/blobs/%s", user.Name, image, blobDigest), resp.Header().Get("Location")) @@ -179,8 +179,8 @@ func TestPackageContainer(t *testing.T) { t.Run("UploadBlob/Chunked", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)) - addTokenAuthHeader(req, userToken) + req := NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusAccepted) uuid := resp.Header().Get("Docker-Upload-Uuid") @@ -193,18 +193,17 @@ func TestPackageContainer(t *testing.T) { uploadURL := resp.Header().Get("Location") assert.NotEmpty(t, uploadURL) - req = NewRequestWithBody(t, "PATCH", setting.AppURL+uploadURL[1:]+"000", bytes.NewReader(blobContent)) - addTokenAuthHeader(req, userToken) + req = NewRequestWithBody(t, "PATCH", setting.AppURL+uploadURL[1:]+"000", bytes.NewReader(blobContent)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusNotFound) - req = NewRequestWithBody(t, "PATCH", setting.AppURL+uploadURL[1:], bytes.NewReader(blobContent)) - addTokenAuthHeader(req, userToken) - - req.Header.Set("Content-Range", "1-10") + req = NewRequestWithBody(t, "PATCH", setting.AppURL+uploadURL[1:], bytes.NewReader(blobContent)). + AddTokenAuth(userToken). + SetHeader("Content-Range", "1-10") MakeRequest(t, req, http.StatusRequestedRangeNotSatisfiable) contentRange := fmt.Sprintf("0-%d", len(blobContent)-1) - req.Header.Set("Content-Range", contentRange) + req.SetHeader("Content-Range", contentRange) resp = MakeRequest(t, req, http.StatusAccepted) assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid")) @@ -212,8 +211,8 @@ func TestPackageContainer(t *testing.T) { uploadURL = resp.Header().Get("Location") - req = NewRequest(t, "GET", setting.AppURL+uploadURL[1:]) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "GET", setting.AppURL+uploadURL[1:]). + AddTokenAuth(userToken) resp = MakeRequest(t, req, http.StatusNoContent) assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid")) @@ -223,8 +222,8 @@ func TestPackageContainer(t *testing.T) { assert.NoError(t, err) assert.EqualValues(t, len(blobContent), pbu.BytesReceived) - req = NewRequest(t, "PUT", fmt.Sprintf("%s?digest=%s", setting.AppURL+uploadURL[1:], blobDigest)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "PUT", fmt.Sprintf("%s?digest=%s", setting.AppURL+uploadURL[1:], blobDigest)). + AddTokenAuth(userToken) resp = MakeRequest(t, req, http.StatusCreated) assert.Equal(t, fmt.Sprintf("/v2/%s/%s/blobs/%s", user.Name, image, blobDigest), resp.Header().Get("Location")) @@ -233,8 +232,8 @@ func TestPackageContainer(t *testing.T) { t.Run("Cancel", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)) - addTokenAuthHeader(req, userToken) + req := NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusAccepted) uuid := resp.Header().Get("Docker-Upload-Uuid") @@ -243,19 +242,19 @@ func TestPackageContainer(t *testing.T) { uploadURL := resp.Header().Get("Location") assert.NotEmpty(t, uploadURL) - req = NewRequest(t, "GET", setting.AppURL+uploadURL[1:]) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "GET", setting.AppURL+uploadURL[1:]). + AddTokenAuth(userToken) resp = MakeRequest(t, req, http.StatusNoContent) assert.Equal(t, uuid, resp.Header().Get("Docker-Upload-Uuid")) assert.Equal(t, "0-0", resp.Header().Get("Range")) - req = NewRequest(t, "DELETE", setting.AppURL+uploadURL[1:]) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "DELETE", setting.AppURL+uploadURL[1:]). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "GET", setting.AppURL+uploadURL[1:]) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "GET", setting.AppURL+uploadURL[1:]). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusNotFound) }) }) @@ -264,31 +263,31 @@ func TestPackageContainer(t *testing.T) { defer tests.PrintCurrentTest(t)() privateBlobDigest := "sha256:6ccce4863b70f258d691f59609d31b4502e1ba5199942d3bc5d35d17a4ce771d" - req := NewRequestWithBody(t, "POST", fmt.Sprintf("%sv2/%s/%s/blobs/uploads?digest=%s", setting.AppURL, privateUser.Name, image, privateBlobDigest), strings.NewReader("gitea")) - req = AddBasicAuthHeader(req, privateUser.Name) + req := NewRequestWithBody(t, "POST", fmt.Sprintf("%sv2/%s/%s/blobs/uploads?digest=%s", setting.AppURL, privateUser.Name, image, privateBlobDigest), strings.NewReader("gitea")). + AddBasicAuth(privateUser.Name) MakeRequest(t, req, http.StatusCreated) - req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads?mount=%s", url, unknownDigest)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads?mount=%s", url, unknownDigest)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusAccepted) - req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads?mount=%s", url, privateBlobDigest)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads?mount=%s", url, privateBlobDigest)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusAccepted) - req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads?mount=%s", url, blobDigest)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads?mount=%s", url, blobDigest)). + AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusCreated) assert.Equal(t, fmt.Sprintf("/v2/%s/%s/blobs/%s", user.Name, image, blobDigest), resp.Header().Get("Location")) assert.Equal(t, blobDigest, resp.Header().Get("Docker-Content-Digest")) - req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads?mount=%s&from=%s", url, unknownDigest, "unknown/image")) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads?mount=%s&from=%s", url, unknownDigest, "unknown/image")). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusAccepted) - req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads?mount=%s&from=%s/%s", url, blobDigest, user.Name, image)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads?mount=%s&from=%s/%s", url, blobDigest, user.Name, image)). + AddTokenAuth(userToken) resp = MakeRequest(t, req, http.StatusCreated) assert.Equal(t, fmt.Sprintf("/v2/%s/%s/blobs/%s", user.Name, image, blobDigest), resp.Header().Get("Location")) @@ -300,18 +299,18 @@ func TestPackageContainer(t *testing.T) { t.Run("UploadManifest", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "POST", fmt.Sprintf("%s/blobs/uploads?digest=%s", url, configDigest), strings.NewReader(configContent)) - addTokenAuthHeader(req, userToken) + req := NewRequestWithBody(t, "POST", fmt.Sprintf("%s/blobs/uploads?digest=%s", url, configDigest), strings.NewReader(configContent)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusCreated) - req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, tag), strings.NewReader(manifestContent)) - addTokenAuthHeader(req, anonymousToken) - req.Header.Set("Content-Type", "application/vnd.docker.distribution.manifest.v2+json") + req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, tag), strings.NewReader(manifestContent)). + AddTokenAuth(anonymousToken). + SetHeader("Content-Type", "application/vnd.docker.distribution.manifest.v2+json") MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, tag), strings.NewReader(manifestContent)) - addTokenAuthHeader(req, userToken) - req.Header.Set("Content-Type", "application/vnd.docker.distribution.manifest.v2+json") + req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, tag), strings.NewReader(manifestContent)). + AddTokenAuth(userToken). + SetHeader("Content-Type", "application/vnd.docker.distribution.manifest.v2+json") resp := MakeRequest(t, req, http.StatusCreated) assert.Equal(t, manifestDigest, resp.Header().Get("Docker-Content-Digest")) @@ -353,8 +352,8 @@ func TestPackageContainer(t *testing.T) { } } - req = NewRequest(t, "GET", fmt.Sprintf("%s/manifests/%s", url, tag)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "GET", fmt.Sprintf("%s/manifests/%s", url, tag)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusOK) pv, err = packages_model.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, image, tag) @@ -362,9 +361,9 @@ func TestPackageContainer(t *testing.T) { assert.EqualValues(t, 1, pv.DownloadCount) // Overwrite existing tag should keep the download count - req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, tag), strings.NewReader(manifestContent)) - addTokenAuthHeader(req, userToken) - req.Header.Set("Content-Type", oci.MediaTypeImageManifest) + req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, tag), strings.NewReader(manifestContent)). + AddTokenAuth(userToken). + SetHeader("Content-Type", oci.MediaTypeImageManifest) MakeRequest(t, req, http.StatusCreated) pv, err = packages_model.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, image, tag) @@ -375,12 +374,12 @@ func TestPackageContainer(t *testing.T) { t.Run("HeadManifest", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "HEAD", fmt.Sprintf("%s/manifests/unknown-tag", url)) - addTokenAuthHeader(req, userToken) + req := NewRequest(t, "HEAD", fmt.Sprintf("%s/manifests/unknown-tag", url)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "HEAD", fmt.Sprintf("%s/manifests/%s", url, tag)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "HEAD", fmt.Sprintf("%s/manifests/%s", url, tag)). + AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, fmt.Sprintf("%d", len(manifestContent)), resp.Header().Get("Content-Length")) @@ -390,12 +389,12 @@ func TestPackageContainer(t *testing.T) { t.Run("GetManifest", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/manifests/unknown-tag", url)) - addTokenAuthHeader(req, userToken) + req := NewRequest(t, "GET", fmt.Sprintf("%s/manifests/unknown-tag", url)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("%s/manifests/%s", url, tag)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "GET", fmt.Sprintf("%s/manifests/%s", url, tag)). + AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, fmt.Sprintf("%d", len(manifestContent)), resp.Header().Get("Content-Length")) @@ -409,15 +408,15 @@ func TestPackageContainer(t *testing.T) { t.Run("UploadUntaggedManifest", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, untaggedManifestDigest), strings.NewReader(untaggedManifestContent)) - addTokenAuthHeader(req, userToken) - req.Header.Set("Content-Type", oci.MediaTypeImageManifest) + req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, untaggedManifestDigest), strings.NewReader(untaggedManifestContent)). + AddTokenAuth(userToken). + SetHeader("Content-Type", oci.MediaTypeImageManifest) resp := MakeRequest(t, req, http.StatusCreated) assert.Equal(t, untaggedManifestDigest, resp.Header().Get("Docker-Content-Digest")) - req = NewRequest(t, "HEAD", fmt.Sprintf("%s/manifests/%s", url, untaggedManifestDigest)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "HEAD", fmt.Sprintf("%s/manifests/%s", url, untaggedManifestDigest)). + AddTokenAuth(userToken) resp = MakeRequest(t, req, http.StatusOK) assert.Equal(t, fmt.Sprintf("%d", len(untaggedManifestContent)), resp.Header().Get("Content-Length")) @@ -449,9 +448,9 @@ func TestPackageContainer(t *testing.T) { t.Run("UploadIndexManifest", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, multiTag), strings.NewReader(indexManifestContent)) - addTokenAuthHeader(req, userToken) - req.Header.Set("Content-Type", oci.MediaTypeImageIndex) + req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, multiTag), strings.NewReader(indexManifestContent)). + AddTokenAuth(userToken). + SetHeader("Content-Type", oci.MediaTypeImageIndex) resp := MakeRequest(t, req, http.StatusCreated) assert.Equal(t, indexManifestDigest, resp.Header().Get("Docker-Content-Digest")) @@ -498,31 +497,31 @@ func TestPackageContainer(t *testing.T) { t.Run("HeadBlob", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "HEAD", fmt.Sprintf("%s/blobs/%s", url, unknownDigest)) - addTokenAuthHeader(req, userToken) + req := NewRequest(t, "HEAD", fmt.Sprintf("%s/blobs/%s", url, unknownDigest)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "HEAD", fmt.Sprintf("%s/blobs/%s", url, blobDigest)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "HEAD", fmt.Sprintf("%s/blobs/%s", url, blobDigest)). + AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, fmt.Sprintf("%d", len(blobContent)), resp.Header().Get("Content-Length")) assert.Equal(t, blobDigest, resp.Header().Get("Docker-Content-Digest")) - req = NewRequest(t, "HEAD", fmt.Sprintf("%s/blobs/%s", url, blobDigest)) - addTokenAuthHeader(req, anonymousToken) + req = NewRequest(t, "HEAD", fmt.Sprintf("%s/blobs/%s", url, blobDigest)). + AddTokenAuth(anonymousToken) MakeRequest(t, req, http.StatusOK) }) t.Run("GetBlob", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/blobs/%s", url, unknownDigest)) - addTokenAuthHeader(req, userToken) + req := NewRequest(t, "GET", fmt.Sprintf("%s/blobs/%s", url, unknownDigest)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("%s/blobs/%s", url, blobDigest)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "GET", fmt.Sprintf("%s/blobs/%s", url, blobDigest)). + AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, fmt.Sprintf("%d", len(blobContent)), resp.Header().Get("Content-Length")) @@ -566,8 +565,8 @@ func TestPackageContainer(t *testing.T) { } for _, c := range cases { - req := NewRequest(t, "GET", c.URL) - addTokenAuthHeader(req, userToken) + req := NewRequest(t, "GET", c.URL). + AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) type TagList struct { @@ -583,7 +582,8 @@ func TestPackageContainer(t *testing.T) { assert.Equal(t, c.ExpectedLink, resp.Header().Get("Link")) } - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s?type=container&q=%s&token=%s", user.Name, image, token)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s?type=container&q=%s", user.Name, image)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiPackages []*api.Package @@ -595,36 +595,36 @@ func TestPackageContainer(t *testing.T) { t.Run("Blob", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("%s/blobs/%s", url, blobDigest)) - addTokenAuthHeader(req, userToken) + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/blobs/%s", url, blobDigest)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusAccepted) - req = NewRequest(t, "HEAD", fmt.Sprintf("%s/blobs/%s", url, blobDigest)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "HEAD", fmt.Sprintf("%s/blobs/%s", url, blobDigest)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusNotFound) }) t.Run("ManifestByDigest", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("%s/manifests/%s", url, untaggedManifestDigest)) - addTokenAuthHeader(req, userToken) + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/manifests/%s", url, untaggedManifestDigest)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusAccepted) - req = NewRequest(t, "HEAD", fmt.Sprintf("%s/manifests/%s", url, untaggedManifestDigest)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "HEAD", fmt.Sprintf("%s/manifests/%s", url, untaggedManifestDigest)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusNotFound) }) t.Run("ManifestByTag", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("%s/manifests/%s", url, multiTag)) - addTokenAuthHeader(req, userToken) + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/manifests/%s", url, multiTag)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusAccepted) - req = NewRequest(t, "HEAD", fmt.Sprintf("%s/manifests/%s", url, multiTag)) - addTokenAuthHeader(req, userToken) + req = NewRequest(t, "HEAD", fmt.Sprintf("%s/manifests/%s", url, multiTag)). + AddTokenAuth(userToken) MakeRequest(t, req, http.StatusNotFound) }) }) @@ -647,8 +647,8 @@ func TestPackageContainer(t *testing.T) { go func() { defer wg.Done() - req := NewRequestWithBody(t, "POST", fmt.Sprintf("%s/blobs/uploads?digest=%s", url, digest), bytes.NewReader(content)) - addTokenAuthHeader(req, userToken) + req := NewRequestWithBody(t, "POST", fmt.Sprintf("%s/blobs/uploads?digest=%s", url, digest), bytes.NewReader(content)). + AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusCreated) assert.Equal(t, digest, resp.Header().Get("Docker-Content-Digest")) @@ -664,8 +664,8 @@ func TestPackageContainer(t *testing.T) { return func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%sv2/_catalog", setting.AppURL)) - addTokenAuthHeader(req, userToken) + req := NewRequest(t, "GET", fmt.Sprintf("%sv2/_catalog", setting.AppURL)). + AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) type RepositoryList struct { diff --git a/tests/integration/api_packages_cran_test.go b/tests/integration/api_packages_cran_test.go index 9ef23226db07f..d307e87d4e0f8 100644 --- a/tests/integration/api_packages_cran_test.go +++ b/tests/integration/api_packages_cran_test.go @@ -74,15 +74,13 @@ func TestPackageCran(t *testing.T) { req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( "dummy.txt", []byte{}, - )) - req = AddBasicAuthHeader(req, user.Name) + )).AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( "package/DESCRIPTION", createDescription(packageName, packageVersion), - )) - req = AddBasicAuthHeader(req, user.Name) + )).AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeCran) @@ -105,24 +103,23 @@ func TestPackageCran(t *testing.T) { req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( "package/DESCRIPTION", createDescription(packageName, packageVersion), - )) - req = AddBasicAuthHeader(req, user.Name) + )).AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) }) t.Run("Download", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/src/contrib/%s_%s.tar.gz", url, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/src/contrib/%s_%s.tar.gz", url, packageName, packageVersion)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusOK) }) t.Run("Enumerate", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", url+"/src/contrib/PACKAGES") - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", url+"/src/contrib/PACKAGES"). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Contains(t, resp.Header().Get("Content-Type"), "text/plain") @@ -131,8 +128,8 @@ func TestPackageCran(t *testing.T) { assert.Contains(t, body, fmt.Sprintf("Package: %s", packageName)) assert.Contains(t, body, fmt.Sprintf("Version: %s", packageVersion)) - req = NewRequest(t, "GET", url+"/src/contrib/PACKAGES.gz") - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", url+"/src/contrib/PACKAGES.gz"). + AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusOK) assert.Contains(t, resp.Header().Get("Content-Type"), "application/x-gzip") @@ -160,15 +157,13 @@ func TestPackageCran(t *testing.T) { req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( "dummy.txt", []byte{}, - )) - req = AddBasicAuthHeader(req, user.Name) + )).AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) req = NewRequestWithBody(t, "PUT", uploadURL+"?platform=&rversion=", createArchive( "package/DESCRIPTION", createDescription(packageName, packageVersion), - )) - req = AddBasicAuthHeader(req, user.Name) + )).AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) uploadURL += "?platform=windows&rversion=4.2" @@ -176,8 +171,7 @@ func TestPackageCran(t *testing.T) { req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( "package/DESCRIPTION", createDescription(packageName, packageVersion), - )) - req = AddBasicAuthHeader(req, user.Name) + )).AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeCran) @@ -191,8 +185,7 @@ func TestPackageCran(t *testing.T) { req = NewRequestWithBody(t, "PUT", uploadURL, createArchive( "package/DESCRIPTION", createDescription(packageName, packageVersion), - )) - req = AddBasicAuthHeader(req, user.Name) + )).AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) }) @@ -210,8 +203,8 @@ func TestPackageCran(t *testing.T) { } for _, c := range cases { - req := NewRequest(t, "GET", fmt.Sprintf("%s/bin/%s/contrib/%s/%s_%s.zip", url, c.Platform, c.RVersion, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/bin/%s/contrib/%s/%s_%s.zip", url, c.Platform, c.RVersion, packageName, packageVersion)). + AddBasicAuth(user.Name) MakeRequest(t, req, c.ExpectedStatus) } }) @@ -222,8 +215,8 @@ func TestPackageCran(t *testing.T) { req := NewRequest(t, "GET", url+"/bin/windows/contrib/4.1/PACKAGES") MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", url+"/bin/windows/contrib/4.2/PACKAGES") - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", url+"/bin/windows/contrib/4.2/PACKAGES"). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Contains(t, resp.Header().Get("Content-Type"), "text/plain") @@ -232,8 +225,8 @@ func TestPackageCran(t *testing.T) { assert.Contains(t, body, fmt.Sprintf("Package: %s", packageName)) assert.Contains(t, body, fmt.Sprintf("Version: %s", packageVersion)) - req = NewRequest(t, "GET", url+"/bin/windows/contrib/4.2/PACKAGES.gz") - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", url+"/bin/windows/contrib/4.2/PACKAGES.gz"). + AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusOK) assert.Contains(t, resp.Header().Get("Content-Type"), "application/x-gzip") diff --git a/tests/integration/api_packages_debian_test.go b/tests/integration/api_packages_debian_test.go index 6c43f72a71daa..05979fccb546c 100644 --- a/tests/integration/api_packages_debian_test.go +++ b/tests/integration/api_packages_debian_test.go @@ -89,16 +89,16 @@ func TestPackageDebian(t *testing.T) { req := NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader([]byte{})) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader([]byte{})) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader([]byte{})). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) - req = NewRequestWithBody(t, "PUT", uploadURL, createArchive("", "", "")) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", uploadURL, createArchive("", "", "")). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) - req = NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion, architecture)) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion, architecture)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) pv, err := packages.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages.TypeDebian, packageName, packageVersion) @@ -145,8 +145,8 @@ func TestPackageDebian(t *testing.T) { return seen }) - req = NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion, architecture)) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion, architecture)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) }) @@ -162,8 +162,8 @@ func TestPackageDebian(t *testing.T) { t.Run("Packages", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion2, architecture)) - AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", uploadURL, createArchive(packageName, packageVersion2, architecture)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) url := fmt.Sprintf("%s/dists/%s/%s/binary-%s/Packages", rootURL, distribution, component, architecture) @@ -243,12 +243,12 @@ func TestPackageDebian(t *testing.T) { req := NewRequest(t, "DELETE", fmt.Sprintf("%s/pool/%s/%s/%s/%s/%s", rootURL, distribution, component, packageName, packageVersion, architecture)) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/pool/%s/%s/%s/%s/%s", rootURL, distribution, component, packageName, packageVersion, architecture)) - AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/pool/%s/%s/%s/%s/%s", rootURL, distribution, component, packageName, packageVersion, architecture)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/pool/%s/%s/%s/%s/%s", rootURL, distribution, component, packageName, packageVersion2, architecture)) - AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/pool/%s/%s/%s/%s/%s", rootURL, distribution, component, packageName, packageVersion2, architecture)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) req = NewRequest(t, "GET", fmt.Sprintf("%s/dists/%s/%s/binary-%s/Packages", rootURL, distribution, component, architecture)) diff --git a/tests/integration/api_packages_generic_test.go b/tests/integration/api_packages_generic_test.go index f5d8def0f3379..93525ac4b19cc 100644 --- a/tests/integration/api_packages_generic_test.go +++ b/tests/integration/api_packages_generic_test.go @@ -35,8 +35,8 @@ func TestPackageGeneric(t *testing.T) { t.Run("Upload", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)) - AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric) @@ -62,16 +62,16 @@ func TestPackageGeneric(t *testing.T) { t.Run("Exists", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)) - AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) }) t.Run("Additional", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", url+"/dummy.bin", bytes.NewReader(content)) - AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url+"/dummy.bin", bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) // Check deduplication @@ -84,16 +84,16 @@ func TestPackageGeneric(t *testing.T) { t.Run("InvalidParameter", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, "invalid+package name", packageVersion, filename), bytes.NewReader(content)) - AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, "invalid+package name", packageVersion, filename), bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) - req = NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, "%20test ", filename), bytes.NewReader(content)) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, "%20test ", filename), bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) - req = NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, packageVersion, "inval+id.na me"), bytes.NewReader(content)) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, packageVersion, "inval+id.na me"), bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) }) }) @@ -187,15 +187,15 @@ func TestPackageGeneric(t *testing.T) { req := NewRequest(t, "DELETE", url+"/"+filename) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "DELETE", url+"/"+filename) - AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", url+"/"+filename). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) req = NewRequest(t, "GET", url+"/"+filename) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "DELETE", url+"/"+filename) - AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", url+"/"+filename). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric) @@ -205,8 +205,8 @@ func TestPackageGeneric(t *testing.T) { t.Run("RemovesVersion", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req = NewRequest(t, "DELETE", url+"/dummy.bin") - AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", url+"/dummy.bin"). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric) @@ -218,15 +218,15 @@ func TestPackageGeneric(t *testing.T) { t.Run("Version", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)) - AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) req = NewRequest(t, "DELETE", url) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "DELETE", url) - AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", url). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric) @@ -236,8 +236,8 @@ func TestPackageGeneric(t *testing.T) { req = NewRequest(t, "GET", url+"/"+filename) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "DELETE", url) - AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", url). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) }) }) diff --git a/tests/integration/api_packages_goproxy_test.go b/tests/integration/api_packages_goproxy_test.go index 08c1ca54f1403..dab9fefc5e17e 100644 --- a/tests/integration/api_packages_goproxy_test.go +++ b/tests/integration/api_packages_goproxy_test.go @@ -51,16 +51,16 @@ func TestPackageGo(t *testing.T) { req := NewRequestWithBody(t, "PUT", url+"/upload", bytes.NewReader(content)) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequestWithBody(t, "PUT", url+"/upload", bytes.NewReader(content)) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", url+"/upload", bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) content = createArchive(map[string][]byte{ packageName + "@" + packageVersion + "/go.mod": []byte(goModContent), }) - req = NewRequestWithBody(t, "PUT", url+"/upload", bytes.NewReader(content)) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", url+"/upload", bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGo) @@ -83,8 +83,8 @@ func TestPackageGo(t *testing.T) { assert.NoError(t, err) assert.Equal(t, int64(len(content)), pb.Size) - req = NewRequestWithBody(t, "PUT", url+"/upload", bytes.NewReader(content)) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", url+"/upload", bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) time.Sleep(time.Second) @@ -93,8 +93,8 @@ func TestPackageGo(t *testing.T) { packageName + "@" + packageVersion2 + "/go.mod": []byte(goModContent), }) - req = NewRequestWithBody(t, "PUT", url+"/upload", bytes.NewReader(content)) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", url+"/upload", bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) }) diff --git a/tests/integration/api_packages_helm_test.go b/tests/integration/api_packages_helm_test.go index 4f61452071b66..76285add11796 100644 --- a/tests/integration/api_packages_helm_test.go +++ b/tests/integration/api_packages_helm_test.go @@ -68,8 +68,8 @@ dependencies: uploadURL := url + "/api/charts" - req := NewRequestWithBody(t, "POST", uploadURL, bytes.NewReader(content)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "POST", uploadURL, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeHelm) @@ -93,8 +93,8 @@ dependencies: assert.NoError(t, err) assert.Equal(t, int64(len(content)), pb.Size) - req = NewRequestWithBody(t, "POST", uploadURL, bytes.NewReader(content)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "POST", uploadURL, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) }) @@ -110,8 +110,8 @@ dependencies: checkDownloadCount(0) - req := NewRequest(t, "GET", fmt.Sprintf("%s/%s", url, filename)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/%s", url, filename)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, content, resp.Body.Bytes()) @@ -122,8 +122,8 @@ dependencies: t.Run("Index", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/index.yaml", url)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/index.yaml", url)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) type ChartVersion struct { diff --git a/tests/integration/api_packages_maven_test.go b/tests/integration/api_packages_maven_test.go index c78024563f4df..c7ed554a9d7f7 100644 --- a/tests/integration/api_packages_maven_test.go +++ b/tests/integration/api_packages_maven_test.go @@ -35,8 +35,8 @@ func TestPackageMaven(t *testing.T) { filename := fmt.Sprintf("%s-%s.jar", packageName, packageVersion) putFile := func(t *testing.T, path, content string, expectedStatus int) { - req := NewRequestWithBody(t, "PUT", root+path, strings.NewReader(content)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", root+path, strings.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, expectedStatus) } @@ -84,14 +84,14 @@ func TestPackageMaven(t *testing.T) { t.Run("Download", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "HEAD", fmt.Sprintf("%s/%s/%s", root, packageVersion, filename)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "HEAD", fmt.Sprintf("%s/%s/%s", root, packageVersion, filename)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) checkHeaders(t, resp.Header(), "application/java-archive", 4) - req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s", root, packageVersion, filename)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s", root, packageVersion, filename)). + AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusOK) checkHeaders(t, resp.Header(), "application/java-archive", 4) @@ -165,14 +165,14 @@ func TestPackageMaven(t *testing.T) { t.Run("DownloadPOM", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "HEAD", fmt.Sprintf("%s/%s/%s.pom", root, packageVersion, filename)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "HEAD", fmt.Sprintf("%s/%s/%s.pom", root, packageVersion, filename)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) checkHeaders(t, resp.Header(), "text/xml", int64(len(pomContent))) - req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s.pom", root, packageVersion, filename)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s.pom", root, packageVersion, filename)). + AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusOK) checkHeaders(t, resp.Header(), "text/xml", int64(len(pomContent))) @@ -188,8 +188,8 @@ func TestPackageMaven(t *testing.T) { t.Run("DownloadChecksums", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/1.2.3/%s", root, filename)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/1.2.3/%s", root, filename)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) for key, checksum := range map[string]string{ @@ -198,8 +198,8 @@ func TestPackageMaven(t *testing.T) { "sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", "sha512": "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff", } { - req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s.%s", root, packageVersion, filename, key)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s.%s", root, packageVersion, filename, key)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, checksum, resp.Body.String()) @@ -209,8 +209,8 @@ func TestPackageMaven(t *testing.T) { t.Run("DownloadMetadata", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", root+"/maven-metadata.xml") - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", root+"/maven-metadata.xml"). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) expectedMetadata := `` + "\ncom.giteatest-project1.0.11.0.11.0.1" @@ -225,8 +225,8 @@ func TestPackageMaven(t *testing.T) { "sha256": "3f48322f81c4b2c3bb8649ae1e5c9801476162b520e1c2734ac06b2c06143208", "sha512": "cb075aa2e2ef1a83cdc14dd1e08c505b72d633399b39e73a21f00f0deecb39a3e2c79f157c1163f8a3854828750706e0dec3a0f5e4778e91f8ec2cf351a855f2", } { - req := NewRequest(t, "GET", fmt.Sprintf("%s/maven-metadata.xml.%s", root, key)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/maven-metadata.xml.%s", root, key)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, checksum, resp.Body.String()) diff --git a/tests/integration/api_packages_npm_test.go b/tests/integration/api_packages_npm_test.go index bd3bfeeff067c..9c888972ffb43 100644 --- a/tests/integration/api_packages_npm_test.go +++ b/tests/integration/api_packages_npm_test.go @@ -87,8 +87,8 @@ func TestPackageNpm(t *testing.T) { t.Run("Upload", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion))) - req = addTokenAuthHeader(req, token) + req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion))). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm) @@ -119,23 +119,23 @@ func TestPackageNpm(t *testing.T) { t.Run("UploadExists", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion))) - req = addTokenAuthHeader(req, token) + req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion))). + AddTokenAuth(token) MakeRequest(t, req, http.StatusConflict) }) t.Run("Download", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/-/%s/%s", root, packageVersion, filename)) - req = addTokenAuthHeader(req, token) + req := NewRequest(t, "GET", fmt.Sprintf("%s/-/%s/%s", root, packageVersion, filename)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) b, _ := base64.StdEncoding.DecodeString(data) assert.Equal(t, b, resp.Body.Bytes()) - req = NewRequest(t, "GET", fmt.Sprintf("%s/-/%s", root, filename)) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", fmt.Sprintf("%s/-/%s", root, filename)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) assert.Equal(t, b, resp.Body.Bytes()) @@ -149,12 +149,12 @@ func TestPackageNpm(t *testing.T) { t.Run("PackageMetadata", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/packages/%s/npm/%s", user.Name, "does-not-exist")) - req = addTokenAuthHeader(req, token) + req := NewRequest(t, "GET", fmt.Sprintf("/api/packages/%s/npm/%s", user.Name, "does-not-exist")). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", root) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", root). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var result npm.PackageMetadata @@ -184,8 +184,8 @@ func TestPackageNpm(t *testing.T) { defer tests.PrintCurrentTest(t)() test := func(t *testing.T, status int, tag, version string) { - req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/%s", tagsRoot, tag), strings.NewReader(`"`+version+`"`)) - req = addTokenAuthHeader(req, token) + req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/%s", tagsRoot, tag), strings.NewReader(`"`+version+`"`)). + AddTokenAuth(token) MakeRequest(t, req, status) } @@ -199,8 +199,8 @@ func TestPackageNpm(t *testing.T) { t.Run("ListTags", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", tagsRoot) - req = addTokenAuthHeader(req, token) + req := NewRequest(t, "GET", tagsRoot). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var result map[string]string @@ -216,8 +216,8 @@ func TestPackageNpm(t *testing.T) { t.Run("PackageMetadataDistTags", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", root) - req = addTokenAuthHeader(req, token) + req := NewRequest(t, "GET", root). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var result npm.PackageMetadata @@ -234,8 +234,8 @@ func TestPackageNpm(t *testing.T) { defer tests.PrintCurrentTest(t)() test := func(t *testing.T, status int, tag string) { - req := NewRequest(t, "DELETE", fmt.Sprintf("%s/%s", tagsRoot, tag)) - req = addTokenAuthHeader(req, token) + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/%s", tagsRoot, tag)). + AddTokenAuth(token) MakeRequest(t, req, status) } @@ -279,15 +279,15 @@ func TestPackageNpm(t *testing.T) { t.Run("Delete", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion+"-dummy"))) - req = addTokenAuthHeader(req, token) + req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion+"-dummy"))). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) req = NewRequest(t, "PUT", root+"/-rev/dummy") MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "PUT", root+"/-rev/dummy") - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "PUT", root+"/-rev/dummy"). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) t.Run("Version", func(t *testing.T) { @@ -300,8 +300,8 @@ func TestPackageNpm(t *testing.T) { req := NewRequest(t, "DELETE", fmt.Sprintf("%s/-/%s/%s/-rev/dummy", root, packageVersion, filename)) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/-/%s/%s/-rev/dummy", root, packageVersion, filename)) - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/-/%s/%s/-rev/dummy", root, packageVersion, filename)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) pvs, err = packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm) @@ -319,8 +319,8 @@ func TestPackageNpm(t *testing.T) { req := NewRequest(t, "DELETE", root+"/-rev/dummy") MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "DELETE", root+"/-rev/dummy") - req = addTokenAuthHeader(req, token) + req = NewRequest(t, "DELETE", root+"/-rev/dummy"). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) pvs, err = packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm) diff --git a/tests/integration/api_packages_nuget_test.go b/tests/integration/api_packages_nuget_test.go index 04c2fbce0ec56..20dafd5cc799f 100644 --- a/tests/integration/api_packages_nuget_test.go +++ b/tests/integration/api_packages_nuget_test.go @@ -31,9 +31,8 @@ import ( "github.com/stretchr/testify/assert" ) -func addNuGetAPIKeyHeader(request *http.Request, token string) *http.Request { - request.Header.Set("X-NuGet-ApiKey", token) - return request +func addNuGetAPIKeyHeader(req *RequestWrapper, token string) { + req.SetHeader("X-NuGet-ApiKey", token) } func decodeXML(t testing.TB, resp *httptest.ResponseRecorder, v any) { @@ -141,9 +140,9 @@ func TestPackageNuGet(t *testing.T) { req := NewRequest(t, "GET", url) if c.UseBasicAuth { - req = AddBasicAuthHeader(req, user.Name) + req.AddBasicAuth(user.Name) } else if c.UseTokenAuth { - req = addNuGetAPIKeyHeader(req, token) + addNuGetAPIKeyHeader(req, token) } resp := MakeRequest(t, req, http.StatusOK) @@ -178,9 +177,9 @@ func TestPackageNuGet(t *testing.T) { req := NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url)) if c.UseBasicAuth { - req = AddBasicAuthHeader(req, user.Name) + req.AddBasicAuth(user.Name) } else if c.UseTokenAuth { - req = addNuGetAPIKeyHeader(req, token) + addNuGetAPIKeyHeader(req, token) } resp := MakeRequest(t, req, http.StatusOK) @@ -219,8 +218,8 @@ func TestPackageNuGet(t *testing.T) { t.Run("DependencyPackage", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNuGet) @@ -244,8 +243,8 @@ func TestPackageNuGet(t *testing.T) { assert.NoError(t, err) assert.Equal(t, int64(len(content)), pb.Size) - req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) }) @@ -278,16 +277,16 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) return &buf } - req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage("unknown-package", "SymbolsPackage")) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage("unknown-package", "SymbolsPackage")). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) - req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "DummyPackage")) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "DummyPackage")). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) - req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "SymbolsPackage")) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "SymbolsPackage")). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNuGet) @@ -330,8 +329,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) } } - req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "SymbolsPackage")) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "SymbolsPackage")). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) }) }) @@ -348,16 +347,16 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) checkDownloadCount(0) - req := NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s.%s.nupkg", url, packageName, packageVersion, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s.%s.nupkg", url, packageName, packageVersion, packageName, packageVersion)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, content, resp.Body.Bytes()) checkDownloadCount(1) - req = NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s.%s.snupkg", url, packageName, packageVersion, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s.%s.snupkg", url, packageName, packageVersion, packageName, packageVersion)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusOK) checkDownloadCount(1) @@ -368,12 +367,12 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) req := NewRequest(t, "GET", fmt.Sprintf("%s/symbols/%s/%sFFFFFFFF/gitea.pdb", url, symbolFilename, symbolID)) MakeRequest(t, req, http.StatusBadRequest) - req = NewRequest(t, "GET", fmt.Sprintf("%s/symbols/%s/%sFFFFFFFF/%s", url, symbolFilename, "00000000000000000000000000000000", symbolFilename)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%s/symbols/%s/%sFFFFFFFF/%s", url, symbolFilename, "00000000000000000000000000000000", symbolFilename)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("%s/symbols/%s/%sFFFFffff/%s", url, symbolFilename, symbolID, symbolFilename)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%s/symbols/%s/%sFFFFffff/%s", url, symbolFilename, symbolID, symbolFilename)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusOK) checkDownloadCount(1) @@ -414,8 +413,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) {"test", 1, 10, 1, 0}, } - req := NewRequestWithBody(t, "PUT", url, createPackage(packageName, "1.0.99")) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url, createPackage(packageName, "1.0.99")). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) t.Run("v2", func(t *testing.T) { @@ -423,8 +422,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) defer tests.PrintCurrentTest(t)() for i, c := range cases { - req := NewRequest(t, "GET", fmt.Sprintf("%s/Search()?searchTerm='%s'&$skip=%d&$top=%d", url, c.Query, c.Skip, c.Take)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/Search()?searchTerm='%s'&$skip=%d&$top=%d", url, c.Query, c.Skip, c.Take)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result FeedResponse @@ -433,8 +432,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) assert.Equal(t, c.ExpectedTotal, result.Count, "case %d: unexpected total hits", i) assert.Len(t, result.Entries, c.ExpectedResults, "case %d: unexpected result count", i) - req = NewRequest(t, "GET", fmt.Sprintf("%s/Search()/$count?searchTerm='%s'&$skip=%d&$top=%d", url, c.Query, c.Skip, c.Take)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%s/Search()/$count?searchTerm='%s'&$skip=%d&$top=%d", url, c.Query, c.Skip, c.Take)). + AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusOK) assert.Equal(t, strconv.FormatInt(c.ExpectedTotal, 10), resp.Body.String(), "case %d: unexpected total hits", i) @@ -445,8 +444,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) defer tests.PrintCurrentTest(t)() for i, c := range cases { - req := NewRequest(t, "GET", fmt.Sprintf("%s/Packages()?$filter=substringof('%s',tolower(Id))&$skip=%d&$top=%d", url, c.Query, c.Skip, c.Take)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/Packages()?$filter=substringof('%s',tolower(Id))&$skip=%d&$top=%d", url, c.Query, c.Skip, c.Take)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result FeedResponse @@ -455,8 +454,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) assert.Equal(t, c.ExpectedTotal, result.Count, "case %d: unexpected total hits", i) assert.Len(t, result.Entries, c.ExpectedResults, "case %d: unexpected result count", i) - req = NewRequest(t, "GET", fmt.Sprintf("%s/Packages()/$count?$filter=substringof('%s',tolower(Id))&$skip=%d&$top=%d", url, c.Query, c.Skip, c.Take)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%s/Packages()/$count?$filter=substringof('%s',tolower(Id))&$skip=%d&$top=%d", url, c.Query, c.Skip, c.Take)). + AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusOK) assert.Equal(t, strconv.FormatInt(c.ExpectedTotal, 10), resp.Body.String(), "case %d: unexpected total hits", i) @@ -464,8 +463,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) }) t.Run("Next", func(t *testing.T) { - req := NewRequest(t, "GET", fmt.Sprintf("%s/Search()?searchTerm='test'&$skip=0&$top=1", url)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/Search()?searchTerm='test'&$skip=0&$top=1", url)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result FeedResponse @@ -479,8 +478,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) defer tests.PrintCurrentTest(t)() for i, c := range cases { - req := NewRequest(t, "GET", fmt.Sprintf("%s/query?q=%s&skip=%d&take=%d", url, c.Query, c.Skip, c.Take)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/query?q=%s&skip=%d&take=%d", url, c.Query, c.Skip, c.Take)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result nuget.SearchResultResponse @@ -493,12 +492,12 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) t.Run("EnforceGrouped", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequestWithBody(t, "PUT", url, createPackage(packageName+".dummy", "1.0.0")) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url, createPackage(packageName+".dummy", "1.0.0")). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) - req = NewRequest(t, "GET", fmt.Sprintf("%s/query?q=%s", url, packageName)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%s/query?q=%s", url, packageName)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result nuget.SearchResultResponse @@ -514,14 +513,14 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) } } - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName+".dummy", "1.0.0")) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName+".dummy", "1.0.0")). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) }) }) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName, "1.0.99")) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName, "1.0.99")). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) }) @@ -533,8 +532,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) t.Run("RegistrationIndex", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/registration/%s/index.json", url, packageName)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/registration/%s/index.json", url, packageName)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result nuget.RegistrationIndexResponse @@ -560,8 +559,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) t.Run("v2", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/Packages(Id='%s',Version='%s')", url, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/Packages(Id='%s',Version='%s')", url, packageName, packageVersion)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result FeedEntry @@ -577,8 +576,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) t.Run("v3", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/registration/%s/%s.json", url, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/registration/%s/%s.json", url, packageName, packageVersion)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result nuget.RegistrationLeafResponse @@ -595,8 +594,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) t.Run("v2", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/FindPackagesById()?id='%s'&$top=1", url, packageName)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/FindPackagesById()?id='%s'&$top=1", url, packageName)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result FeedResponse @@ -606,8 +605,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) assert.Equal(t, packageVersion, result.Entries[0].Properties.Version) assert.Condition(t, containsOneNextLink(t, result.Links)) - req = NewRequest(t, "GET", fmt.Sprintf("%s/FindPackagesById()/$count?id='%s'", url, packageName)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%s/FindPackagesById()/$count?id='%s'", url, packageName)). + AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusOK) assert.Equal(t, "1", resp.Body.String()) @@ -616,8 +615,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) t.Run("v3", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/index.json", url, packageName)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/index.json", url, packageName)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) var result nuget.PackageVersionsResponse @@ -631,8 +630,8 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) t.Run("Delete", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName, packageVersion)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNuGet) @@ -643,20 +642,20 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) t.Run("DownloadNotExists", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s.%s.nupkg", url, packageName, packageVersion, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s.%s.nupkg", url, packageName, packageVersion, packageName, packageVersion)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s.%s.snupkg", url, packageName, packageVersion, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%s/package/%s/%s/%s.%s.snupkg", url, packageName, packageVersion, packageName, packageVersion)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) }) t.Run("DeleteNotExists", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("%s/package/%s/%s", url, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "DELETE", fmt.Sprintf("%s/package/%s/%s", url, packageName, packageVersion)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) }) } diff --git a/tests/integration/api_packages_pub_test.go b/tests/integration/api_packages_pub_test.go index 6e9d8742f472d..11da894ddf3da 100644 --- a/tests/integration/api_packages_pub_test.go +++ b/tests/integration/api_packages_pub_test.go @@ -66,8 +66,8 @@ description: ` + packageDescription req := NewRequest(t, "GET", uploadURL) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "GET", uploadURL) - addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", uploadURL). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) type UploadRequest struct { @@ -88,16 +88,16 @@ description: ` + packageDescription _ = writer.Close() - req := NewRequestWithBody(t, "POST", url, body) - req.Header.Add("Content-Type", writer.FormDataContentType()) - addTokenAuthHeader(req, token) + req := NewRequestWithBody(t, "POST", url, body). + SetHeader("Content-Type", writer.FormDataContentType()). + AddTokenAuth(token) return MakeRequest(t, req, expectedStatus) } resp = uploadFile(t, result.URL, content, http.StatusNoContent) - req = NewRequest(t, "GET", resp.Header().Get("Location")) - addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", resp.Header().Get("Location")). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypePub) diff --git a/tests/integration/api_packages_pypi_test.go b/tests/integration/api_packages_pypi_test.go index 76013b79c840f..a090b31e20642 100644 --- a/tests/integration/api_packages_pypi_test.go +++ b/tests/integration/api_packages_pypi_test.go @@ -54,9 +54,9 @@ func TestPackagePyPI(t *testing.T) { _ = writer.Close() - req := NewRequestWithBody(t, "POST", root, body) - req.Header.Add("Content-Type", writer.FormDataContentType()) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "POST", root, body). + SetHeader("Content-Type", writer.FormDataContentType()). + AddBasicAuth(user.Name) MakeRequest(t, req, expectedStatus) } @@ -137,8 +137,8 @@ func TestPackagePyPI(t *testing.T) { defer tests.PrintCurrentTest(t)() downloadFile := func(filename string) { - req := NewRequest(t, "GET", fmt.Sprintf("%s/files/%s/%s/%s", root, packageName, packageVersion, filename)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/files/%s/%s/%s", root, packageName, packageVersion, filename)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, []byte(content), resp.Body.Bytes()) @@ -156,8 +156,8 @@ func TestPackagePyPI(t *testing.T) { t.Run("PackageMetadata", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/simple/%s", root, packageName)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/simple/%s", root, packageName)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, resp.Body) diff --git a/tests/integration/api_packages_rpm_test.go b/tests/integration/api_packages_rpm_test.go index 6d3b0688f2a31..caf6f86381e20 100644 --- a/tests/integration/api_packages_rpm_test.go +++ b/tests/integration/api_packages_rpm_test.go @@ -105,8 +105,8 @@ gpgkey=%sapi/packages/%s/rpm/repository.key`, user.Name, user.Name, setting.AppN req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeRpm) @@ -130,8 +130,8 @@ gpgkey=%sapi/packages/%s/rpm/repository.key`, user.Name, user.Name, setting.AppN assert.NoError(t, err) assert.Equal(t, int64(len(content)), pb.Size) - req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) }) @@ -404,16 +404,16 @@ gpgkey=%sapi/packages/%s/rpm/repository.key`, user.Name, user.Name, setting.AppN req := NewRequest(t, "DELETE", fmt.Sprintf("%s/package/%s/%s/%s", rootURL, packageName, packageVersion, packageArchitecture)) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/package/%s/%s/%s", rootURL, packageName, packageVersion, packageArchitecture)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/package/%s/%s/%s", rootURL, packageName, packageVersion, packageArchitecture)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeRpm) assert.NoError(t, err) assert.Empty(t, pvs) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/package/%s/%s/%s", rootURL, packageName, packageVersion, packageArchitecture)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", fmt.Sprintf("%s/package/%s/%s/%s", rootURL, packageName, packageVersion, packageArchitecture)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) }) } diff --git a/tests/integration/api_packages_rubygems_test.go b/tests/integration/api_packages_rubygems_test.go index a3df143209a5c..5670731c4926c 100644 --- a/tests/integration/api_packages_rubygems_test.go +++ b/tests/integration/api_packages_rubygems_test.go @@ -115,8 +115,8 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`) root := fmt.Sprintf("/api/packages/%s/rubygems", user.Name) uploadFile := func(t *testing.T, expectedStatus int) { - req := NewRequestWithBody(t, "POST", fmt.Sprintf("%s/api/v1/gems", root), bytes.NewReader(gemContent)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "POST", fmt.Sprintf("%s/api/v1/gems", root), bytes.NewReader(gemContent)). + AddBasicAuth(user.Name) MakeRequest(t, req, expectedStatus) } @@ -156,8 +156,8 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`) t.Run("Download", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/gems/%s", root, packageFilename)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/gems/%s", root, packageFilename)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, gemContent, resp.Body.Bytes()) @@ -171,8 +171,8 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`) t.Run("DownloadGemspec", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/quick/Marshal.4.8/%sspec.rz", root, packageFilename)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/quick/Marshal.4.8/%sspec.rz", root, packageFilename)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) b, _ := base64.StdEncoding.DecodeString(`eJxi4Si1EndPzbWyCi5ITc5My0xOLMnMz2M8zMIRLeGpxGWsZ6RnzGbF5hqSyempxJWeWZKayGbN @@ -191,8 +191,8 @@ gAAAAP//MS06Gw==`) defer tests.PrintCurrentTest(t)() enumeratePackages := func(t *testing.T, endpoint string, expectedContent []byte) { - req := NewRequest(t, "GET", fmt.Sprintf("%s/%s", root, endpoint)) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", fmt.Sprintf("%s/%s", root, endpoint)). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, expectedContent, resp.Body.Bytes()) @@ -215,9 +215,9 @@ gAAAAP//MS06Gw==`) writer.WriteField("version", packageVersion) writer.Close() - req := NewRequestWithBody(t, "DELETE", fmt.Sprintf("%s/api/v1/gems/yank", root), &body) - req.Header.Add("Content-Type", writer.FormDataContentType()) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "DELETE", fmt.Sprintf("%s/api/v1/gems/yank", root), &body). + SetHeader("Content-Type", writer.FormDataContentType()). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusOK) pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeRubyGems) diff --git a/tests/integration/api_packages_swift_test.go b/tests/integration/api_packages_swift_test.go index a3035ea60485d..7d4ff954e2274 100644 --- a/tests/integration/api_packages_swift_test.go +++ b/tests/integration/api_packages_swift_test.go @@ -62,9 +62,9 @@ func TestPackageSwift(t *testing.T) { assert.Equal(t, "application/problem+json", resp.Header().Get("Content-Type")) } - req := NewRequestWithBody(t, "PUT", url+"/scope/package/1.0.0", strings.NewReader("")) - req = AddBasicAuthHeader(req, user.Name) - req.Header.Add("Accept", "application/unknown") + req := NewRequestWithBody(t, "PUT", url+"/scope/package/1.0.0", strings.NewReader("")). + AddBasicAuth(user.Name). + SetHeader("Accept", "application/unknown") resp := MakeRequest(t, req, http.StatusBadRequest) assert.Equal(t, "1", resp.Header().Get("Content-Version")) @@ -87,10 +87,10 @@ func TestPackageSwift(t *testing.T) { mpw.Close() - req := NewRequestWithBody(t, "PUT", url, &body) - req.Header.Add("Content-Type", mpw.FormDataContentType()) - req.Header.Add("Accept", swift_router.AcceptJSON) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url, &body). + SetHeader("Content-Type", mpw.FormDataContentType()). + SetHeader("Accept", swift_router.AcceptJSON). + AddBasicAuth(user.Name) MakeRequest(t, req, expectedStatus) } @@ -106,8 +106,8 @@ func TestPackageSwift(t *testing.T) { } for _, triple := range []string{"/sc_ope/package/1.0.0", "/scope/pack~age/1.0.0", "/scope/package/1_0.0"} { - req := NewRequestWithBody(t, "PUT", url+triple, bytes.NewReader([]byte{})) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url+triple, bytes.NewReader([]byte{})). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusBadRequest) assert.Equal(t, "1", resp.Header().Get("Content-Version")) @@ -168,9 +168,9 @@ func TestPackageSwift(t *testing.T) { t.Run("Download", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s/%s.zip", url, packageScope, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) - req.Header.Add("Accept", swift_router.AcceptZip) + req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s/%s.zip", url, packageScope, packageName, packageVersion)). + AddBasicAuth(user.Name). + SetHeader("Accept", swift_router.AcceptZip) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "1", resp.Header().Get("Content-Version")) @@ -188,9 +188,9 @@ func TestPackageSwift(t *testing.T) { t.Run("EnumeratePackageVersions", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s", url, packageScope, packageName)) - req = AddBasicAuthHeader(req, user.Name) - req.Header.Add("Accept", swift_router.AcceptJSON) + req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s", url, packageScope, packageName)). + AddBasicAuth(user.Name). + SetHeader("Accept", swift_router.AcceptJSON) resp := MakeRequest(t, req, http.StatusOK) versionURL := setting.AppURL + url[1:] + fmt.Sprintf("/%s/%s/%s", packageScope, packageName, packageVersion) @@ -207,8 +207,8 @@ func TestPackageSwift(t *testing.T) { assert.Contains(t, result.Releases, packageVersion) assert.Equal(t, versionURL, result.Releases[packageVersion].URL) - req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s.json", url, packageScope, packageName)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s.json", url, packageScope, packageName)). + AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusOK) assert.Equal(t, body, resp.Body.String()) @@ -217,9 +217,9 @@ func TestPackageSwift(t *testing.T) { t.Run("PackageVersionMetadata", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s/%s", url, packageScope, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) - req.Header.Add("Accept", swift_router.AcceptJSON) + req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s/%s", url, packageScope, packageName, packageVersion)). + AddBasicAuth(user.Name). + SetHeader("Accept", swift_router.AcceptJSON) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "1", resp.Header().Get("Content-Version")) @@ -249,8 +249,8 @@ func TestPackageSwift(t *testing.T) { assert.Equal(t, "Swift", result.Metadata.ProgrammingLanguage.Name) assert.Equal(t, packageAuthor, result.Metadata.Author.GivenName) - req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s/%s.json", url, packageScope, packageName, packageVersion)) - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/%s/%s.json", url, packageScope, packageName, packageVersion)). + AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusOK) assert.Equal(t, body, resp.Body.String()) @@ -262,9 +262,9 @@ func TestPackageSwift(t *testing.T) { t.Run("Default", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", manifestURL) - req = AddBasicAuthHeader(req, user.Name) - req.Header.Add("Accept", swift_router.AcceptSwift) + req := NewRequest(t, "GET", manifestURL). + AddBasicAuth(user.Name). + SetHeader("Accept", swift_router.AcceptSwift) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "1", resp.Header().Get("Content-Version")) @@ -275,24 +275,24 @@ func TestPackageSwift(t *testing.T) { t.Run("DifferentVersion", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", manifestURL+"?swift-version=5.6") - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", manifestURL+"?swift-version=5.6"). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "1", resp.Header().Get("Content-Version")) assert.Equal(t, "text/x-swift", resp.Header().Get("Content-Type")) assert.Equal(t, contentManifest2, resp.Body.String()) - req = NewRequest(t, "GET", manifestURL+"?swift-version=5.6.0") - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", manifestURL+"?swift-version=5.6.0"). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusOK) }) t.Run("Redirect", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", manifestURL+"?swift-version=1.0") - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", manifestURL+"?swift-version=1.0"). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusSeeOther) assert.Equal(t, "1", resp.Header().Get("Content-Version")) @@ -303,8 +303,8 @@ func TestPackageSwift(t *testing.T) { t.Run("LookupPackageIdentifiers", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", url+"/identifiers") - req.Header.Add("Accept", swift_router.AcceptJSON) + req := NewRequest(t, "GET", url+"/identifiers"). + SetHeader("Accept", swift_router.AcceptJSON) resp := MakeRequest(t, req, http.StatusBadRequest) assert.Equal(t, "1", resp.Header().Get("Content-Version")) @@ -313,8 +313,8 @@ func TestPackageSwift(t *testing.T) { req = NewRequest(t, "GET", url+"/identifiers?url=https://unknown.host/") MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", url+"/identifiers?url="+packageRepositoryURL) - req.Header.Add("Accept", swift_router.AcceptJSON) + req = NewRequest(t, "GET", url+"/identifiers?url="+packageRepositoryURL). + SetHeader("Accept", swift_router.AcceptJSON) resp = MakeRequest(t, req, http.StatusOK) var result *swift_router.LookupPackageIdentifiersResponse diff --git a/tests/integration/api_packages_test.go b/tests/integration/api_packages_test.go index e530b2c1ad79d..8c981566b6028 100644 --- a/tests/integration/api_packages_test.go +++ b/tests/integration/api_packages_test.go @@ -41,14 +41,15 @@ func TestPackageAPI(t *testing.T) { filename := "file.bin" url := fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, packageVersion, filename) - req := NewRequestWithBody(t, "PUT", url, bytes.NewReader([]byte{})) - AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url, bytes.NewReader([]byte{})). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) t.Run("ListPackages", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s?token=%s", user.Name, tokenReadPackage)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s", user.Name)). + AddTokenAuth(tokenReadPackage) resp := MakeRequest(t, req, http.StatusOK) var apiPackages []*api.Package @@ -65,10 +66,12 @@ func TestPackageAPI(t *testing.T) { t.Run("GetPackage", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/dummy/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenReadPackage)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/dummy/%s/%s", user.Name, packageName, packageVersion)). + AddTokenAuth(tokenReadPackage) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenReadPackage)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s", user.Name, packageName, packageVersion)). + AddTokenAuth(tokenReadPackage) resp := MakeRequest(t, req, http.StatusOK) var p *api.Package @@ -87,7 +90,8 @@ func TestPackageAPI(t *testing.T) { assert.NoError(t, err) // no repository link - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenReadPackage)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s", user.Name, packageName, packageVersion)). + AddTokenAuth(tokenReadPackage) resp := MakeRequest(t, req, http.StatusOK) var ap1 *api.Package @@ -97,7 +101,8 @@ func TestPackageAPI(t *testing.T) { // link to public repository assert.NoError(t, packages_model.SetRepositoryLink(db.DefaultContext, p.ID, 1)) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenReadPackage)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s", user.Name, packageName, packageVersion)). + AddTokenAuth(tokenReadPackage) resp = MakeRequest(t, req, http.StatusOK) var ap2 *api.Package @@ -108,7 +113,8 @@ func TestPackageAPI(t *testing.T) { // link to private repository assert.NoError(t, packages_model.SetRepositoryLink(db.DefaultContext, p.ID, 2)) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenReadPackage)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s", user.Name, packageName, packageVersion)). + AddTokenAuth(tokenReadPackage) resp = MakeRequest(t, req, http.StatusOK) var ap3 *api.Package @@ -122,10 +128,12 @@ func TestPackageAPI(t *testing.T) { t.Run("ListPackageFiles", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/dummy/%s/%s/files?token=%s", user.Name, packageName, packageVersion, tokenReadPackage)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/dummy/%s/%s/files", user.Name, packageName, packageVersion)). + AddTokenAuth(tokenReadPackage) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s/files?token=%s", user.Name, packageName, packageVersion, tokenReadPackage)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s/files", user.Name, packageName, packageVersion)). + AddTokenAuth(tokenReadPackage) resp := MakeRequest(t, req, http.StatusOK) var files []*api.PackageFile @@ -143,10 +151,12 @@ func TestPackageAPI(t *testing.T) { t.Run("DeletePackage", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/packages/%s/dummy/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenDeletePackage)) + req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/packages/%s/dummy/%s/%s", user.Name, packageName, packageVersion)). + AddTokenAuth(tokenDeletePackage) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s?token=%s", user.Name, packageName, packageVersion, tokenDeletePackage)) + req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/packages/%s/generic/%s/%s", user.Name, packageName, packageVersion)). + AddTokenAuth(tokenDeletePackage) MakeRequest(t, req, http.StatusNoContent) }) } @@ -170,7 +180,7 @@ func TestPackageAccess(t *testing.T) { url := fmt.Sprintf("/api/packages/%s/generic/test-package/1.0/%s.bin", owner.Name, filename) req := NewRequestWithBody(t, "PUT", url, bytes.NewReader([]byte{1})) if doer != nil { - AddBasicAuthHeader(req, doer.Name) + req.AddBasicAuth(doer.Name) } MakeRequest(t, req, expectedStatus) } @@ -179,7 +189,7 @@ func TestPackageAccess(t *testing.T) { url := fmt.Sprintf("/api/packages/%s/generic/test-package/1.0/admin.bin", owner.Name) req := NewRequest(t, "GET", url) if doer != nil { - AddBasicAuthHeader(req, doer.Name) + req.AddBasicAuth(doer.Name) } MakeRequest(t, req, expectedStatus) } @@ -374,7 +384,8 @@ func TestPackageAccess(t *testing.T) { {limitedOrgNoMember, http.StatusOK}, {publicOrgNoMember, http.StatusOK}, } { - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s?token=%s", target.Owner.Name, tokenReadPackage)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s", target.Owner.Name)). + AddTokenAuth(tokenReadPackage) MakeRequest(t, req, target.ExpectedStatus) } }) @@ -396,8 +407,8 @@ func TestPackageQuota(t *testing.T) { uploadPackage := func(doer *user_model.User, version string, expectedStatus int) { url := fmt.Sprintf("/api/packages/%s/generic/test-package/%s/file.bin", user.Name, version) - req := NewRequestWithBody(t, "PUT", url, bytes.NewReader([]byte{1})) - AddBasicAuthHeader(req, doer.Name) + req := NewRequestWithBody(t, "PUT", url, bytes.NewReader([]byte{1})). + AddBasicAuth(doer.Name) MakeRequest(t, req, expectedStatus) } @@ -424,8 +435,8 @@ func TestPackageQuota(t *testing.T) { uploadBlob := func(doer *user_model.User, data string, expectedStatus int) { url := fmt.Sprintf("/v2/%s/quota-test/blobs/uploads?digest=sha256:%x", user.Name, sha256.Sum256([]byte(data))) - req := NewRequestWithBody(t, "POST", url, strings.NewReader(data)) - AddBasicAuthHeader(req, doer.Name) + req := NewRequestWithBody(t, "POST", url, strings.NewReader(data)). + AddBasicAuth(doer.Name) MakeRequest(t, req, expectedStatus) } @@ -454,18 +465,18 @@ func TestPackageCleanup(t *testing.T) { // Upload and delete a generic package and upload a container blob data, _ := util.CryptoRandomBytes(5) url := fmt.Sprintf("/api/packages/%s/generic/cleanup-test/1.1.1/file.bin", user.Name) - req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(data)) - AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(data)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) - req = NewRequest(t, "DELETE", url) - AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "DELETE", url). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) data, _ = util.CryptoRandomBytes(5) url = fmt.Sprintf("/v2/%s/cleanup-test/blobs/uploads?digest=sha256:%x", user.Name, sha256.Sum256(data)) - req = NewRequestWithBody(t, "POST", url, bytes.NewReader(data)) - AddBasicAuthHeader(req, user.Name) + req = NewRequestWithBody(t, "POST", url, bytes.NewReader(data)). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) pbs, err := packages_model.FindExpiredUnreferencedBlobs(db.DefaultContext, duration) @@ -592,8 +603,8 @@ func TestPackageCleanup(t *testing.T) { for _, v := range c.Versions { url := fmt.Sprintf("/api/packages/%s/generic/package/%s/file.bin", user.Name, v.Version) - req := NewRequestWithBody(t, "PUT", url, bytes.NewReader([]byte{1})) - AddBasicAuthHeader(req, user.Name) + req := NewRequestWithBody(t, "PUT", url, bytes.NewReader([]byte{1})). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) if v.Created != 0 { diff --git a/tests/integration/api_packages_vagrant_test.go b/tests/integration/api_packages_vagrant_test.go index cbfc362f32d51..a5e954f3a27db 100644 --- a/tests/integration/api_packages_vagrant_test.go +++ b/tests/integration/api_packages_vagrant_test.go @@ -64,8 +64,8 @@ func TestPackageVagrant(t *testing.T) { req := NewRequest(t, "GET", authenticateURL) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "GET", authenticateURL) - addTokenAuthHeader(req, token) + req = NewRequest(t, "GET", authenticateURL). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) }) @@ -82,8 +82,8 @@ func TestPackageVagrant(t *testing.T) { req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)) - addTokenAuthHeader(req, token) + req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) req = NewRequest(t, "HEAD", boxURL) @@ -111,8 +111,8 @@ func TestPackageVagrant(t *testing.T) { assert.NoError(t, err) assert.Equal(t, int64(len(content)), pb.Size) - req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)) - addTokenAuthHeader(req, token) + req = NewRequestWithBody(t, "PUT", uploadURL, bytes.NewReader(content)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusConflict) }) diff --git a/tests/integration/api_pull_review_test.go b/tests/integration/api_pull_review_test.go index 0e9bace44c9d6..daa136b21e45c 100644 --- a/tests/integration/api_pull_review_test.go +++ b/tests/integration/api_pull_review_test.go @@ -29,7 +29,8 @@ func TestAPIPullReview(t *testing.T) { // test ListPullReviews session := loginUser(t, "user2") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token) + req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var reviews []*api.PullReview @@ -54,20 +55,23 @@ func TestAPIPullReview(t *testing.T) { assert.True(t, reviews[5].Official) // test GetPullReview - req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, reviews[3].ID, token) + req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d", repo.OwnerName, repo.Name, pullIssue.Index, reviews[3].ID). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var review api.PullReview DecodeJSON(t, resp, &review) assert.EqualValues(t, *reviews[3], review) - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/pulls/%d/reviews/%d?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, reviews[5].ID, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/pulls/%d/reviews/%d", repo.OwnerName, repo.Name, pullIssue.Index, reviews[5].ID). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &review) assert.EqualValues(t, *reviews[5], review) // test GetPullReviewComments comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 7}) - req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d/comments?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, 10, token) + req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d/comments", repo.OwnerName, repo.Name, pullIssue.Index, 10). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var reviewComments []*api.PullReviewComment DecodeJSON(t, resp, &reviewComments) @@ -79,7 +83,7 @@ func TestAPIPullReview(t *testing.T) { assert.EqualValues(t, comment.HTMLURL(db.DefaultContext), reviewComments[0].HTMLURL) // test CreatePullReview - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.CreatePullReviewOptions{ + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{ Body: "body1", // Event: "" # will result in PENDING Comments: []api.CreatePullReviewComment{ @@ -100,7 +104,7 @@ func TestAPIPullReview(t *testing.T) { NewLineNum: 1, }, }, - }) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &review) assert.EqualValues(t, 6, review.ID) @@ -108,10 +112,10 @@ func TestAPIPullReview(t *testing.T) { assert.EqualValues(t, 3, review.CodeCommentsCount) // test SubmitPullReview - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, review.ID, token), &api.SubmitPullReviewOptions{ + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d", repo.OwnerName, repo.Name, pullIssue.Index, review.ID), &api.SubmitPullReviewOptions{ Event: "APPROVED", Body: "just two nits", - }) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &review) assert.EqualValues(t, 6, review.ID) @@ -119,35 +123,37 @@ func TestAPIPullReview(t *testing.T) { assert.EqualValues(t, 3, review.CodeCommentsCount) // test dismiss review - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d/dismissals?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, review.ID, token), &api.DismissPullReviewOptions{ + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d/dismissals", repo.OwnerName, repo.Name, pullIssue.Index, review.ID), &api.DismissPullReviewOptions{ Message: "test", - }) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &review) assert.EqualValues(t, 6, review.ID) assert.True(t, review.Dismissed) // test dismiss review - req = NewRequest(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d/undismissals?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, review.ID, token)) + req = NewRequest(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d/undismissals", repo.OwnerName, repo.Name, pullIssue.Index, review.ID)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &review) assert.EqualValues(t, 6, review.ID) assert.False(t, review.Dismissed) // test DeletePullReview - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.CreatePullReviewOptions{ + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{ Body: "just a comment", Event: "COMMENT", - }) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &review) assert.EqualValues(t, "COMMENT", review.State) assert.EqualValues(t, 0, review.CodeCommentsCount) - req = NewRequestf(t, http.MethodDelete, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, review.ID, token) + req = NewRequestf(t, http.MethodDelete, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d", repo.OwnerName, repo.Name, pullIssue.Index, review.ID). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // test CreatePullReview Comment without body but with comments - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.CreatePullReviewOptions{ + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{ // Body: "", Event: "COMMENT", Comments: []api.CreatePullReviewComment{ @@ -163,7 +169,7 @@ func TestAPIPullReview(t *testing.T) { NewLineNum: 0, }, }, - }) + }).AddTokenAuth(token) var commentReview api.PullReview resp = MakeRequest(t, req, http.StatusOK) @@ -175,11 +181,11 @@ func TestAPIPullReview(t *testing.T) { // test CreatePullReview Comment with body but without comments commentBody := "This is a body of the comment." - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.CreatePullReviewOptions{ + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{ Body: commentBody, Event: "COMMENT", Comments: []api.CreatePullReviewComment{}, - }) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &commentReview) @@ -189,11 +195,11 @@ func TestAPIPullReview(t *testing.T) { assert.False(t, commentReview.Dismissed) // test CreatePullReview Comment without body and no comments - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.CreatePullReviewOptions{ + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{ Body: "", Event: "COMMENT", Comments: []api.CreatePullReviewComment{}, - }) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusUnprocessableEntity) errMap := make(map[string]any) json.Unmarshal(resp.Body.Bytes(), &errMap) @@ -205,7 +211,8 @@ func TestAPIPullReview(t *testing.T) { assert.NoError(t, pullIssue12.LoadAttributes(db.DefaultContext)) repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}) - req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token) + req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews", repo3.OwnerName, repo3.Name, pullIssue12.Index). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &reviews) assert.EqualValues(t, 11, reviews[0].ID) @@ -232,41 +239,41 @@ func TestAPIPullReviewRequest(t *testing.T) { // Test add Review Request session := loginUser(t, "user2") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.PullReviewRequestOptions{ + req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo.OwnerName, repo.Name, pullIssue.Index), &api.PullReviewRequestOptions{ Reviewers: []string{"user4@example.com", "user8"}, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) // poster of pr can't be reviewer - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.PullReviewRequestOptions{ + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo.OwnerName, repo.Name, pullIssue.Index), &api.PullReviewRequestOptions{ Reviewers: []string{"user1"}, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) // test user not exist - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.PullReviewRequestOptions{ + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo.OwnerName, repo.Name, pullIssue.Index), &api.PullReviewRequestOptions{ Reviewers: []string{"testOther"}, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) // Test Remove Review Request session2 := loginUser(t, "user4") token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeWriteRepository) - req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token2), &api.PullReviewRequestOptions{ + req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo.OwnerName, repo.Name, pullIssue.Index), &api.PullReviewRequestOptions{ Reviewers: []string{"user4"}, - }) + }).AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) // doer is not admin - req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token2), &api.PullReviewRequestOptions{ + req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo.OwnerName, repo.Name, pullIssue.Index), &api.PullReviewRequestOptions{ Reviewers: []string{"user8"}, - }) + }).AddTokenAuth(token2) MakeRequest(t, req, http.StatusUnprocessableEntity) - req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.PullReviewRequestOptions{ + req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo.OwnerName, repo.Name, pullIssue.Index), &api.PullReviewRequestOptions{ Reviewers: []string{"user8"}, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // Test team review request @@ -275,33 +282,35 @@ func TestAPIPullReviewRequest(t *testing.T) { repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}) // Test add Team Review Request - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token), &api.PullReviewRequestOptions{ + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo3.OwnerName, repo3.Name, pullIssue12.Index), &api.PullReviewRequestOptions{ TeamReviewers: []string{"team1", "owners"}, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) // Test add Team Review Request to not allowned - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token), &api.PullReviewRequestOptions{ + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo3.OwnerName, repo3.Name, pullIssue12.Index), &api.PullReviewRequestOptions{ TeamReviewers: []string{"test_team"}, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) // Test add Team Review Request to not exist - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token), &api.PullReviewRequestOptions{ + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo3.OwnerName, repo3.Name, pullIssue12.Index), &api.PullReviewRequestOptions{ TeamReviewers: []string{"not_exist_team"}, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) // Test Remove team Review Request - req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token), &api.PullReviewRequestOptions{ + req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo3.OwnerName, repo3.Name, pullIssue12.Index), &api.PullReviewRequestOptions{ TeamReviewers: []string{"team1"}, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // empty request test - req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token), &api.PullReviewRequestOptions{}) + req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo3.OwnerName, repo3.Name, pullIssue12.Index), &api.PullReviewRequestOptions{}). + AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) - req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token), &api.PullReviewRequestOptions{}) + req = NewRequestWithJSON(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers", repo3.OwnerName, repo3.Name, pullIssue12.Index), &api.PullReviewRequestOptions{}). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) } diff --git a/tests/integration/api_pull_test.go b/tests/integration/api_pull_test.go index 9d590630e4510..33cc826e5eaa2 100644 --- a/tests/integration/api_pull_test.go +++ b/tests/integration/api_pull_test.go @@ -31,7 +31,8 @@ func TestAPIViewPulls(t *testing.T) { ctx := NewAPITestContext(t, "user2", repo.Name, auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/pulls?state=all&token="+ctx.Token, owner.Name, repo.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/pulls?state=all", owner.Name, repo.Name). + AddTokenAuth(ctx.Token) resp := ctx.Session.MakeRequest(t, req, http.StatusOK) var pulls []*api.PullRequest @@ -76,10 +77,10 @@ func TestAPIMergePullWIP(t *testing.T) { session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge?token=%s", owner.Name, repo.Name, pr.Index, token), &forms.MergePullRequestForm{ + req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/merge", owner.Name, repo.Name, pr.Index), &forms.MergePullRequestForm{ MergeMessageField: pr.Issue.Title, Do: string(repo_model.MergeStyleMerge), - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusMethodNotAllowed) } @@ -95,11 +96,11 @@ func TestAPICreatePullSuccess(t *testing.T) { session := loginUser(t, owner11.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", owner10.Name, repo10.Name, token), &api.CreatePullRequestOption{ + req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &api.CreatePullRequestOption{ Head: fmt.Sprintf("%s:master", owner11.Name), Base: "master", Title: "create a failure pr", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) MakeRequest(t, req, http.StatusUnprocessableEntity) // second request should fail } @@ -126,7 +127,8 @@ func TestAPICreatePullWithFieldsSuccess(t *testing.T) { Labels: []int64{5}, } - req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", owner10.Name, repo10.Name, token), opts) + req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), opts). + AddTokenAuth(token) res := MakeRequest(t, req, http.StatusCreated) pull := new(api.PullRequest) @@ -158,7 +160,8 @@ func TestAPICreatePullWithFieldsFailure(t *testing.T) { Base: "master", } - req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", owner10.Name, repo10.Name, token), opts) + req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) opts.Title = "is required" @@ -182,35 +185,34 @@ func TestAPIEditPull(t *testing.T) { session := loginUser(t, owner10.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", owner10.Name, repo10.Name, token), &api.CreatePullRequestOption{ + req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &api.CreatePullRequestOption{ Head: "develop", Base: "master", Title: "create a success pr", - }) + }).AddTokenAuth(token) pull := new(api.PullRequest) resp := MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, pull) assert.EqualValues(t, "master", pull.Base.Name) - req = NewRequestWithJSON(t, http.MethodPatch, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d?token=%s", owner10.Name, repo10.Name, pull.Index, token), &api.EditPullRequestOption{ + req = NewRequestWithJSON(t, http.MethodPatch, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d", owner10.Name, repo10.Name, pull.Index), &api.EditPullRequestOption{ Base: "feature/1", Title: "edit a this pr", - }) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, pull) assert.EqualValues(t, "feature/1", pull.Base.Name) - req = NewRequestWithJSON(t, http.MethodPatch, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d?token=%s", owner10.Name, repo10.Name, pull.Index, token), &api.EditPullRequestOption{ + req = NewRequestWithJSON(t, http.MethodPatch, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d", owner10.Name, repo10.Name, pull.Index), &api.EditPullRequestOption{ Base: "not-exist", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) } func doAPIGetPullFiles(ctx APITestContext, pr *api.PullRequest, callback func(*testing.T, []*api.ChangedFile)) func(*testing.T) { return func(t *testing.T) { - url := fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/files?token=%s", ctx.Username, ctx.Reponame, pr.Index, ctx.Token) - - req := NewRequest(t, http.MethodGet, url) + req := NewRequest(t, http.MethodGet, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/files", ctx.Username, ctx.Reponame, pr.Index)). + AddTokenAuth(ctx.Token) if ctx.ExpectedCode == 0 { ctx.ExpectedCode = http.StatusOK } diff --git a/tests/integration/api_releases_test.go b/tests/integration/api_releases_test.go index 526842d5ac07c..6ec3fcc4b8b11 100644 --- a/tests/integration/api_releases_test.go +++ b/tests/integration/api_releases_test.go @@ -59,11 +59,12 @@ func TestAPIListReleases(t *testing.T) { // test filter testFilterByLen := func(auth bool, query url.Values, expectedLength int, msgAndArgs ...string) { + link.RawQuery = query.Encode() + req := NewRequest(t, "GET", link.String()) if auth { - query.Set("token", token) + req.AddTokenAuth(token) } - link.RawQuery = query.Encode() - resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) + resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiReleases) assert.Len(t, apiReleases, expectedLength, msgAndArgs) } @@ -77,8 +78,7 @@ func TestAPIListReleases(t *testing.T) { } func createNewReleaseUsingAPI(t *testing.T, session *TestSession, token string, owner *user_model.User, repo *repo_model.Repository, name, target, title, desc string) *api.Release { - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases?token=%s", - owner.Name, repo.Name, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases", owner.Name, repo.Name) req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateReleaseOption{ TagName: name, Title: title, @@ -86,7 +86,7 @@ func createNewReleaseUsingAPI(t *testing.T, session *TestSession, token string, IsDraft: false, IsPrerelease: false, Target: target, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var newRelease api.Release @@ -122,9 +122,9 @@ func TestAPICreateAndUpdateRelease(t *testing.T) { newRelease := createNewReleaseUsingAPI(t, session, token, owner, repo, "v0.0.1", target, "v0.0.1", "test") - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/%d?token=%s", - owner.Name, repo.Name, newRelease.ID, token) - req := NewRequest(t, "GET", urlStr) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/%d", owner.Name, repo.Name, newRelease.ID) + req := NewRequest(t, "GET", urlStr). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var release api.Release @@ -141,7 +141,7 @@ func TestAPICreateAndUpdateRelease(t *testing.T) { IsDraft: &release.IsDraft, IsPrerelease: &release.IsPrerelease, Target: release.Target, - }) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &newRelease) @@ -189,10 +189,7 @@ func TestAPIGetLatestRelease(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/latest", - owner.Name, repo.Name) - - req := NewRequestf(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/releases/latest", owner.Name, repo.Name)) resp := MakeRequest(t, req, http.StatusOK) var release *api.Release @@ -209,10 +206,7 @@ func TestAPIGetReleaseByTag(t *testing.T) { tag := "v1.1" - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", - owner.Name, repo.Name, tag) - - req := NewRequestf(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner.Name, repo.Name, tag)) resp := MakeRequest(t, req, http.StatusOK) var release *api.Release @@ -222,10 +216,7 @@ func TestAPIGetReleaseByTag(t *testing.T) { nonexistingtag := "nonexistingtag" - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", - owner.Name, repo.Name, nonexistingtag) - - req = NewRequestf(t, "GET", urlStr) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/%s", owner.Name, repo.Name, nonexistingtag)) resp = MakeRequest(t, req, http.StatusNotFound) var err *api.APIError @@ -244,15 +235,18 @@ func TestAPIDeleteReleaseByTagName(t *testing.T) { createNewReleaseUsingAPI(t, session, token, owner, repo, "release-tag", "", "Release Tag", "test") // delete release - req := NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/release-tag?token=%s", owner.Name, repo.Name, token)) + req := NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/release-tag", owner.Name, repo.Name)). + AddTokenAuth(token) _ = MakeRequest(t, req, http.StatusNoContent) // make sure release is deleted - req = NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/release-tag?token=%s", owner.Name, repo.Name, token)) + req = NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/releases/tags/release-tag", owner.Name, repo.Name)). + AddTokenAuth(token) _ = MakeRequest(t, req, http.StatusNotFound) // delete release tag too - req = NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/tags/release-tag?token=%s", owner.Name, repo.Name, token)) + req = NewRequestf(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/tags/release-tag", owner.Name, repo.Name)). + AddTokenAuth(token) _ = MakeRequest(t, req, http.StatusNoContent) } @@ -278,7 +272,8 @@ func TestAPIUploadAssetRelease(t *testing.T) { err = writer.Close() assert.NoError(t, err) - req := NewRequestWithBody(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets?name=test-asset&token=%s", owner.Name, repo.Name, r.ID, token), body) + req := NewRequestWithBody(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/releases/%d/assets?name=test-asset", owner.Name, repo.Name, r.ID), body). + AddTokenAuth(token) req.Header.Add("Content-Type", writer.FormDataContentType()) resp := MakeRequest(t, req, http.StatusCreated) diff --git a/tests/integration/api_repo_avatar_test.go b/tests/integration/api_repo_avatar_test.go index 58a4fc536c87e..6677885f7eb20 100644 --- a/tests/integration/api_repo_avatar_test.go +++ b/tests/integration/api_repo_avatar_test.go @@ -38,7 +38,8 @@ func TestAPIUpdateRepoAvatar(t *testing.T) { Image: base64.StdEncoding.EncodeToString(avatar), } - req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/avatar?token=%s", repo.OwnerName, repo.Name, token), &opts) + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/avatar", repo.OwnerName, repo.Name), &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) // Test what happens if you don't have a valid Base64 string @@ -46,7 +47,8 @@ func TestAPIUpdateRepoAvatar(t *testing.T) { Image: "Invalid", } - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/avatar?token=%s", repo.OwnerName, repo.Name, token), &opts) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/avatar", repo.OwnerName, repo.Name), &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusBadRequest) // Test what happens if you use a file that is not an image @@ -60,7 +62,8 @@ func TestAPIUpdateRepoAvatar(t *testing.T) { Image: base64.StdEncoding.EncodeToString(text), } - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/avatar?token=%s", repo.OwnerName, repo.Name, token), &opts) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/avatar", repo.OwnerName, repo.Name), &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusInternalServerError) } @@ -71,6 +74,7 @@ func TestAPIDeleteRepoAvatar(t *testing.T) { user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) token := getUserToken(t, user2.LowerName, auth_model.AccessTokenScopeWriteRepository) - req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/avatar?token=%s", repo.OwnerName, repo.Name, token)) + req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/avatar", repo.OwnerName, repo.Name)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) } diff --git a/tests/integration/api_repo_collaborator_test.go b/tests/integration/api_repo_collaborator_test.go index b7280a4f6c417..59cf85fef33d8 100644 --- a/tests/integration/api_repo_collaborator_test.go +++ b/tests/integration/api_repo_collaborator_test.go @@ -31,7 +31,8 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) { testCtx := NewAPITestContext(t, repo2Owner.Name, repo2.Name, auth_model.AccessTokenScopeWriteRepository) t.Run("RepoOwnerShouldBeOwner", func(t *testing.T) { - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission?token=%s", repo2Owner.Name, repo2.Name, repo2Owner.Name, testCtx.Token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission", repo2Owner.Name, repo2.Name, repo2Owner.Name). + AddTokenAuth(testCtx.Token) resp := MakeRequest(t, req, http.StatusOK) var repoPermission api.RepoCollaboratorPermission @@ -43,7 +44,8 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) { t.Run("CollaboratorWithReadAccess", func(t *testing.T) { t.Run("AddUserAsCollaboratorWithReadAccess", doAPIAddCollaborator(testCtx, user4.Name, perm.AccessModeRead)) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission?token=%s", repo2Owner.Name, repo2.Name, user4.Name, testCtx.Token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission", repo2Owner.Name, repo2.Name, user4.Name). + AddTokenAuth(testCtx.Token) resp := MakeRequest(t, req, http.StatusOK) var repoPermission api.RepoCollaboratorPermission @@ -55,7 +57,8 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) { t.Run("CollaboratorWithWriteAccess", func(t *testing.T) { t.Run("AddUserAsCollaboratorWithWriteAccess", doAPIAddCollaborator(testCtx, user4.Name, perm.AccessModeWrite)) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission?token=%s", repo2Owner.Name, repo2.Name, user4.Name, testCtx.Token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission", repo2Owner.Name, repo2.Name, user4.Name). + AddTokenAuth(testCtx.Token) resp := MakeRequest(t, req, http.StatusOK) var repoPermission api.RepoCollaboratorPermission @@ -67,7 +70,8 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) { t.Run("CollaboratorWithAdminAccess", func(t *testing.T) { t.Run("AddUserAsCollaboratorWithAdminAccess", doAPIAddCollaborator(testCtx, user4.Name, perm.AccessModeAdmin)) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission?token=%s", repo2Owner.Name, repo2.Name, user4.Name, testCtx.Token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission", repo2Owner.Name, repo2.Name, user4.Name). + AddTokenAuth(testCtx.Token) resp := MakeRequest(t, req, http.StatusOK) var repoPermission api.RepoCollaboratorPermission @@ -77,7 +81,8 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) { }) t.Run("CollaboratorNotFound", func(t *testing.T) { - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission?token=%s", repo2Owner.Name, repo2.Name, "non-existent-user", testCtx.Token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission", repo2Owner.Name, repo2.Name, "non-existent-user"). + AddTokenAuth(testCtx.Token) MakeRequest(t, req, http.StatusNotFound) }) @@ -87,7 +92,8 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) { _session := loginUser(t, user5.Name) _testCtx := NewAPITestContext(t, user5.Name, repo2.Name, auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission?token=%s", repo2Owner.Name, repo2.Name, user5.Name, _testCtx.Token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission", repo2Owner.Name, repo2.Name, user5.Name). + AddTokenAuth(_testCtx.Token) resp := _session.MakeRequest(t, req, http.StatusOK) var repoPermission api.RepoCollaboratorPermission @@ -102,7 +108,8 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) { _session := loginUser(t, user5.Name) _testCtx := NewAPITestContext(t, user5.Name, repo2.Name, auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission?token=%s", repo2Owner.Name, repo2.Name, user5.Name, _testCtx.Token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission", repo2Owner.Name, repo2.Name, user5.Name). + AddTokenAuth(_testCtx.Token) resp := _session.MakeRequest(t, req, http.StatusOK) var repoPermission api.RepoCollaboratorPermission @@ -118,7 +125,8 @@ func TestAPIRepoCollaboratorPermission(t *testing.T) { _session := loginUser(t, user10.Name) _testCtx := NewAPITestContext(t, user10.Name, repo2.Name, auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission?token=%s", repo2Owner.Name, repo2.Name, user11.Name, _testCtx.Token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/collaborators/%s/permission", repo2Owner.Name, repo2.Name, user11.Name). + AddTokenAuth(_testCtx.Token) resp := _session.MakeRequest(t, req, http.StatusOK) var repoPermission api.RepoCollaboratorPermission diff --git a/tests/integration/api_repo_edit_test.go b/tests/integration/api_repo_edit_test.go index 0e992c2df2491..c4fc2177b4ce1 100644 --- a/tests/integration/api_repo_edit_test.go +++ b/tests/integration/api_repo_edit_test.go @@ -155,8 +155,8 @@ func TestAPIRepoEdit(t *testing.T) { // Test editing a repo1 which user2 owns, changing name and many properties origRepoEditOption := getRepoEditOptionFromRepo(repo1) repoEditOption := getNewRepoEditOption(origRepoEditOption) - url := fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo1.Name, token2) - req := NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req := NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo1.Name), &repoEditOption). + AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusOK) var repo api.Repository DecodeJSON(t, resp, &repo) @@ -186,8 +186,9 @@ func TestAPIRepoEdit(t *testing.T) { } *repoEditOption.HasWiki = true repoEditOption.ExternalWiki = nil - url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, *repoEditOption.Name, token2) - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + url := fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, *repoEditOption.Name) + req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &repo) assert.NotNil(t, repo) @@ -209,7 +210,8 @@ func TestAPIRepoEdit(t *testing.T) { repoEditOption.ExternalWiki = &api.ExternalWiki{ ExternalWikiURL: "http://www.somewebsite.com", } - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &repo) assert.NotNil(t, repo) @@ -223,7 +225,8 @@ func TestAPIRepoEdit(t *testing.T) { repoEditOption.ExternalTracker.ExternalTrackerStyle = "regexp" repoEditOption.ExternalTracker.ExternalTrackerRegexpPattern = `(\d+)` - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &repo) assert.NotNil(t, repo) @@ -234,15 +237,18 @@ func TestAPIRepoEdit(t *testing.T) { // Do some tests with invalid URL for external tracker and wiki repoEditOption.ExternalTracker.ExternalTrackerURL = "htp://www.somewebsite.com" - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusUnprocessableEntity) repoEditOption.ExternalTracker.ExternalTrackerURL = "http://www.somewebsite.com" repoEditOption.ExternalTracker.ExternalTrackerFormat = "http://www.somewebsite.com/{user/{repo}?issue={index}" - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusUnprocessableEntity) repoEditOption.ExternalTracker.ExternalTrackerFormat = "http://www.somewebsite.com/{user}/{repo}?issue={index}" repoEditOption.ExternalWiki.ExternalWikiURL = "htp://www.somewebsite.com" - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusUnprocessableEntity) // Test small repo change through API with issue and wiki option not set; They shall not be touched. @@ -251,7 +257,8 @@ func TestAPIRepoEdit(t *testing.T) { repoEditOption.ExternalTracker = nil repoEditOption.HasWiki = nil repoEditOption.ExternalWiki = nil - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &repo) assert.NotNil(t, repo) @@ -265,39 +272,38 @@ func TestAPIRepoEdit(t *testing.T) { assert.NotNil(t, *repo1editedOption.ExternalWiki) // reset repo in db - url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, *repoEditOption.Name, token2) - req = NewRequestWithJSON(t, "PATCH", url, &origRepoEditOption) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, *repoEditOption.Name), &origRepoEditOption). + AddTokenAuth(token2) _ = MakeRequest(t, req, http.StatusOK) // Test editing a non-existing repo name := "repodoesnotexist" - url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, name, token2) - req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{Name: &name}) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, name), &api.EditRepoOption{Name: &name}). + AddTokenAuth(token2) _ = MakeRequest(t, req, http.StatusNotFound) // Test editing repo16 by user4 who does not have write access origRepoEditOption = getRepoEditOptionFromRepo(repo16) repoEditOption = getNewRepoEditOption(origRepoEditOption) - url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo16.Name, token4) - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name), &repoEditOption). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusNotFound) // Tests a repo with no token given so will fail origRepoEditOption = getRepoEditOptionFromRepo(repo16) repoEditOption = getNewRepoEditOption(origRepoEditOption) - url = fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name) - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name), &repoEditOption) _ = MakeRequest(t, req, http.StatusNotFound) // Test using access token for a private repo that the user of the token owns origRepoEditOption = getRepoEditOptionFromRepo(repo16) repoEditOption = getNewRepoEditOption(origRepoEditOption) - url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo16.Name, token2) - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name), &repoEditOption). + AddTokenAuth(token2) _ = MakeRequest(t, req, http.StatusOK) // reset repo in db - url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, *repoEditOption.Name, token2) - req = NewRequestWithJSON(t, "PATCH", url, &origRepoEditOption) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, *repoEditOption.Name), &origRepoEditOption). + AddTokenAuth(token2) _ = MakeRequest(t, req, http.StatusOK) // Test making a repo public that is private @@ -306,53 +312,54 @@ func TestAPIRepoEdit(t *testing.T) { repoEditOption = &api.EditRepoOption{ Private: &bFalse, } - url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo16.Name, token2) - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + url = fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo16.Name) + req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption). + AddTokenAuth(token2) _ = MakeRequest(t, req, http.StatusOK) repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) assert.False(t, repo16.IsPrivate) // Make it private again repoEditOption.Private = &bTrue - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption). + AddTokenAuth(token2) _ = MakeRequest(t, req, http.StatusOK) // Test to change empty repo assert.False(t, repo15.IsArchived) - url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo15.Name, token2) + url = fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo15.Name) req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{ Archived: &bTrue, - }) + }).AddTokenAuth(token2) _ = MakeRequest(t, req, http.StatusOK) repo15 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15}) assert.True(t, repo15.IsArchived) req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{ Archived: &bFalse, - }) + }).AddTokenAuth(token2) _ = MakeRequest(t, req, http.StatusOK) // Test using org repo "org3/repo3" where user2 is a collaborator origRepoEditOption = getRepoEditOptionFromRepo(repo3) repoEditOption = getNewRepoEditOption(origRepoEditOption) - url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", org3.Name, repo3.Name, token2) - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", org3.Name, repo3.Name), &repoEditOption). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusOK) // reset repo in db - url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", org3.Name, *repoEditOption.Name, token2) - req = NewRequestWithJSON(t, "PATCH", url, &origRepoEditOption) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", org3.Name, *repoEditOption.Name), &origRepoEditOption). + AddTokenAuth(token2) _ = MakeRequest(t, req, http.StatusOK) // Test using org repo "org3/repo3" with no user token origRepoEditOption = getRepoEditOptionFromRepo(repo3) repoEditOption = getNewRepoEditOption(origRepoEditOption) - url = fmt.Sprintf("/api/v1/repos/%s/%s", org3.Name, repo3.Name) - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", org3.Name, repo3.Name), &repoEditOption) MakeRequest(t, req, http.StatusNotFound) // Test using repo "user2/repo1" where user4 is a NOT collaborator origRepoEditOption = getRepoEditOptionFromRepo(repo1) repoEditOption = getNewRepoEditOption(origRepoEditOption) - url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo1.Name, token4) - req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo1.Name), &repoEditOption). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusForbidden) }) } diff --git a/tests/integration/api_repo_file_create_test.go b/tests/integration/api_repo_file_create_test.go index fbe0b5bcd0555..f78909eb32582 100644 --- a/tests/integration/api_repo_file_create_test.go +++ b/tests/integration/api_repo_file_create_test.go @@ -164,8 +164,8 @@ func TestAPICreateFile(t *testing.T) { createFileOptions.BranchName = branch fileID++ treePath := fmt.Sprintf("new/file%d.txt", fileID) - url := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req := NewRequestWithJSON(t, "POST", url, &createFileOptions) + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &createFileOptions). + AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusCreated) gitRepo, _ := git.OpenRepository(stdCtx.Background(), repo1.RepoPath()) commitID, _ := gitRepo.GetBranchCommitID(createFileOptions.NewBranchName) @@ -191,8 +191,8 @@ func TestAPICreateFile(t *testing.T) { createFileOptions.NewBranchName = "new_branch" fileID++ treePath := fmt.Sprintf("new/file%d.txt", fileID) - url := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req := NewRequestWithJSON(t, "POST", url, &createFileOptions) + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &createFileOptions). + AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusCreated) var fileResponse api.FileResponse DecodeJSON(t, resp, &fileResponse) @@ -209,8 +209,8 @@ func TestAPICreateFile(t *testing.T) { createFileOptions.Message = "" fileID++ treePath = fmt.Sprintf("new/file%d.txt", fileID) - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req = NewRequestWithJSON(t, "POST", url, &createFileOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &createFileOptions). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, &fileResponse) expectedMessage := "Add " + treePath + "\n" @@ -219,8 +219,8 @@ func TestAPICreateFile(t *testing.T) { // Test trying to create a file that already exists, should fail createFileOptions = getCreateFileOptions() treePath = "README.md" - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req = NewRequestWithJSON(t, "POST", url, &createFileOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &createFileOptions). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusUnprocessableEntity) expectedAPIError := context.APIError{ Message: "repository file already exists [path: " + treePath + "]", @@ -234,48 +234,46 @@ func TestAPICreateFile(t *testing.T) { createFileOptions = getCreateFileOptions() fileID++ treePath = fmt.Sprintf("new/file%d.txt", fileID) - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo16.Name, treePath, token4) - req = NewRequestWithJSON(t, "POST", url, &createFileOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath), &createFileOptions). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusNotFound) // Tests a repo with no token given so will fail createFileOptions = getCreateFileOptions() fileID++ treePath = fmt.Sprintf("new/file%d.txt", fileID) - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath) - req = NewRequestWithJSON(t, "POST", url, &createFileOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath), &createFileOptions) MakeRequest(t, req, http.StatusNotFound) // Test using access token for a private repo that the user of the token owns createFileOptions = getCreateFileOptions() fileID++ treePath = fmt.Sprintf("new/file%d.txt", fileID) - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo16.Name, treePath, token2) - req = NewRequestWithJSON(t, "POST", url, &createFileOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath), &createFileOptions). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusCreated) // Test using org repo "org3/repo3" where user2 is a collaborator createFileOptions = getCreateFileOptions() fileID++ treePath = fmt.Sprintf("new/file%d.txt", fileID) - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", org3.Name, repo3.Name, treePath, token2) - req = NewRequestWithJSON(t, "POST", url, &createFileOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath), &createFileOptions). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusCreated) // Test using org repo "org3/repo3" with no user token createFileOptions = getCreateFileOptions() fileID++ treePath = fmt.Sprintf("new/file%d.txt", fileID) - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath) - req = NewRequestWithJSON(t, "POST", url, &createFileOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath), &createFileOptions) MakeRequest(t, req, http.StatusNotFound) // Test using repo "user2/repo1" where user4 is a NOT collaborator createFileOptions = getCreateFileOptions() fileID++ treePath = fmt.Sprintf("new/file%d.txt", fileID) - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token4) - req = NewRequestWithJSON(t, "POST", url, &createFileOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &createFileOptions). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusForbidden) // Test creating a file in an empty repository @@ -283,8 +281,8 @@ func TestAPICreateFile(t *testing.T) { createFileOptions = getCreateFileOptions() fileID++ treePath = fmt.Sprintf("new/file%d.txt", fileID) - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, "empty-repo", treePath, token2) - req = NewRequestWithJSON(t, "POST", url, &createFileOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, "empty-repo", treePath), &createFileOptions). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusCreated) emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "empty-repo"}) // public repo gitRepo, _ := git.OpenRepository(stdCtx.Background(), emptyRepo.RepoPath()) diff --git a/tests/integration/api_repo_file_delete_test.go b/tests/integration/api_repo_file_delete_test.go index c6ab7a0e615be..7c93307e1981f 100644 --- a/tests/integration/api_repo_file_delete_test.go +++ b/tests/integration/api_repo_file_delete_test.go @@ -64,8 +64,8 @@ func TestAPIDeleteFile(t *testing.T) { createFile(user2, repo1, treePath) deleteFileOptions := getDeleteFileOptions() deleteFileOptions.BranchName = branch - url := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req := NewRequestWithJSON(t, "DELETE", url, &deleteFileOptions) + req := NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &deleteFileOptions). + AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusOK) var fileResponse api.FileResponse DecodeJSON(t, resp, &fileResponse) @@ -80,8 +80,8 @@ func TestAPIDeleteFile(t *testing.T) { deleteFileOptions := getDeleteFileOptions() deleteFileOptions.BranchName = repo1.DefaultBranch deleteFileOptions.NewBranchName = "new_branch" - url := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req := NewRequestWithJSON(t, "DELETE", url, &deleteFileOptions) + req := NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &deleteFileOptions). + AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusOK) var fileResponse api.FileResponse DecodeJSON(t, resp, &fileResponse) @@ -95,8 +95,8 @@ func TestAPIDeleteFile(t *testing.T) { createFile(user2, repo1, treePath) deleteFileOptions = getDeleteFileOptions() deleteFileOptions.Message = "" - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req = NewRequestWithJSON(t, "DELETE", url, &deleteFileOptions) + req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &deleteFileOptions). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &fileResponse) expectedMessage := "Delete " + treePath + "\n" @@ -108,8 +108,8 @@ func TestAPIDeleteFile(t *testing.T) { createFile(user2, repo1, treePath) deleteFileOptions = getDeleteFileOptions() deleteFileOptions.SHA = "badsha" - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req = NewRequestWithJSON(t, "DELETE", url, &deleteFileOptions) + req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &deleteFileOptions). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusBadRequest) // Test creating a file in repo16 by user4 who does not have write access @@ -117,8 +117,8 @@ func TestAPIDeleteFile(t *testing.T) { treePath = fmt.Sprintf("delete/file%d.txt", fileID) createFile(user2, repo16, treePath) deleteFileOptions = getDeleteFileOptions() - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo16.Name, treePath, token4) - req = NewRequestWithJSON(t, "DELETE", url, &deleteFileOptions) + req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath), &deleteFileOptions). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusNotFound) // Tests a repo with no token given so will fail @@ -126,8 +126,7 @@ func TestAPIDeleteFile(t *testing.T) { treePath = fmt.Sprintf("delete/file%d.txt", fileID) createFile(user2, repo16, treePath) deleteFileOptions = getDeleteFileOptions() - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath) - req = NewRequestWithJSON(t, "DELETE", url, &deleteFileOptions) + req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath), &deleteFileOptions) MakeRequest(t, req, http.StatusNotFound) // Test using access token for a private repo that the user of the token owns @@ -135,8 +134,8 @@ func TestAPIDeleteFile(t *testing.T) { treePath = fmt.Sprintf("delete/file%d.txt", fileID) createFile(user2, repo16, treePath) deleteFileOptions = getDeleteFileOptions() - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo16.Name, treePath, token2) - req = NewRequestWithJSON(t, "DELETE", url, &deleteFileOptions) + req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath), &deleteFileOptions). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusOK) // Test using org repo "org3/repo3" where user2 is a collaborator @@ -144,8 +143,8 @@ func TestAPIDeleteFile(t *testing.T) { treePath = fmt.Sprintf("delete/file%d.txt", fileID) createFile(org3, repo3, treePath) deleteFileOptions = getDeleteFileOptions() - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", org3.Name, repo3.Name, treePath, token2) - req = NewRequestWithJSON(t, "DELETE", url, &deleteFileOptions) + req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath), &deleteFileOptions). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusOK) // Test using org repo "org3/repo3" with no user token @@ -153,8 +152,7 @@ func TestAPIDeleteFile(t *testing.T) { treePath = fmt.Sprintf("delete/file%d.txt", fileID) createFile(org3, repo3, treePath) deleteFileOptions = getDeleteFileOptions() - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath) - req = NewRequestWithJSON(t, "DELETE", url, &deleteFileOptions) + req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath), &deleteFileOptions) MakeRequest(t, req, http.StatusNotFound) // Test using repo "user2/repo1" where user4 is a NOT collaborator @@ -162,8 +160,8 @@ func TestAPIDeleteFile(t *testing.T) { treePath = fmt.Sprintf("delete/file%d.txt", fileID) createFile(user2, repo1, treePath) deleteFileOptions = getDeleteFileOptions() - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token4) - req = NewRequestWithJSON(t, "DELETE", url, &deleteFileOptions) + req = NewRequestWithJSON(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &deleteFileOptions). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusForbidden) }) } diff --git a/tests/integration/api_repo_file_update_test.go b/tests/integration/api_repo_file_update_test.go index ecf24cdbf984d..7e88f6cd80360 100644 --- a/tests/integration/api_repo_file_update_test.go +++ b/tests/integration/api_repo_file_update_test.go @@ -132,8 +132,8 @@ func TestAPIUpdateFile(t *testing.T) { createFile(user2, repo1, treePath) updateFileOptions := getUpdateFileOptions() updateFileOptions.BranchName = branch - url := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req := NewRequestWithJSON(t, "PUT", url, &updateFileOptions) + req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &updateFileOptions). + AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusOK) gitRepo, _ := git.OpenRepository(stdCtx.Background(), repo1.RepoPath()) commitID, _ := gitRepo.GetBranchCommitID(updateFileOptions.NewBranchName) @@ -156,8 +156,8 @@ func TestAPIUpdateFile(t *testing.T) { fileID++ treePath := fmt.Sprintf("update/file%d.txt", fileID) createFile(user2, repo1, treePath) - url := fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req := NewRequestWithJSON(t, "PUT", url, &updateFileOptions) + req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &updateFileOptions). + AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusOK) var fileResponse api.FileResponse DecodeJSON(t, resp, &fileResponse) @@ -177,8 +177,8 @@ func TestAPIUpdateFile(t *testing.T) { createFile(user2, repo1, treePath) updateFileOptions.FromPath = treePath treePath = "rename/" + treePath - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions) + req = NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &updateFileOptions). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &fileResponse) expectedSHA = "08bd14b2e2852529157324de9c226b3364e76136" @@ -195,8 +195,8 @@ func TestAPIUpdateFile(t *testing.T) { fileID++ treePath = fmt.Sprintf("update/file%d.txt", fileID) createFile(user2, repo1, treePath) - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions) + req = NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &updateFileOptions). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &fileResponse) expectedMessage := "Update " + treePath + "\n" @@ -209,8 +209,8 @@ func TestAPIUpdateFile(t *testing.T) { updateFileOptions = getUpdateFileOptions() correctSHA := updateFileOptions.SHA updateFileOptions.SHA = "badsha" - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token2) - req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions) + req = NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &updateFileOptions). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusUnprocessableEntity) expectedAPIError := context.APIError{ Message: "sha does not match [given: " + updateFileOptions.SHA + ", expected: " + correctSHA + "]", @@ -225,8 +225,8 @@ func TestAPIUpdateFile(t *testing.T) { treePath = fmt.Sprintf("update/file%d.txt", fileID) createFile(user2, repo16, treePath) updateFileOptions = getUpdateFileOptions() - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo16.Name, treePath, token4) - req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions) + req = NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath), &updateFileOptions). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusNotFound) // Tests a repo with no token given so will fail @@ -234,8 +234,7 @@ func TestAPIUpdateFile(t *testing.T) { treePath = fmt.Sprintf("update/file%d.txt", fileID) createFile(user2, repo16, treePath) updateFileOptions = getUpdateFileOptions() - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath) - req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions) + req = NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath), &updateFileOptions) MakeRequest(t, req, http.StatusNotFound) // Test using access token for a private repo that the user of the token owns @@ -243,8 +242,8 @@ func TestAPIUpdateFile(t *testing.T) { treePath = fmt.Sprintf("update/file%d.txt", fileID) createFile(user2, repo16, treePath) updateFileOptions = getUpdateFileOptions() - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo16.Name, treePath, token2) - req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions) + req = NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath), &updateFileOptions). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusOK) // Test using org repo "org3/repo3" where user2 is a collaborator @@ -252,8 +251,8 @@ func TestAPIUpdateFile(t *testing.T) { treePath = fmt.Sprintf("update/file%d.txt", fileID) createFile(org3, repo3, treePath) updateFileOptions = getUpdateFileOptions() - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", org3.Name, repo3.Name, treePath, token2) - req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions) + req = NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath), &updateFileOptions). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusOK) // Test using org repo "org3/repo3" with no user token @@ -261,8 +260,7 @@ func TestAPIUpdateFile(t *testing.T) { treePath = fmt.Sprintf("update/file%d.txt", fileID) createFile(org3, repo3, treePath) updateFileOptions = getUpdateFileOptions() - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath) - req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions) + req = NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath), &updateFileOptions) MakeRequest(t, req, http.StatusNotFound) // Test using repo "user2/repo1" where user4 is a NOT collaborator @@ -270,8 +268,8 @@ func TestAPIUpdateFile(t *testing.T) { treePath = fmt.Sprintf("update/file%d.txt", fileID) createFile(user2, repo1, treePath) updateFileOptions = getUpdateFileOptions() - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo1.Name, treePath, token4) - req = NewRequestWithJSON(t, "PUT", url, &updateFileOptions) + req = NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s", user2.Name, repo1.Name, treePath), &updateFileOptions). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusForbidden) }) } diff --git a/tests/integration/api_repo_files_change_test.go b/tests/integration/api_repo_files_change_test.go index 1ab759497fb0e..d500d48b36091 100644 --- a/tests/integration/api_repo_files_change_test.go +++ b/tests/integration/api_repo_files_change_test.go @@ -93,8 +93,8 @@ func TestAPIChangeFiles(t *testing.T) { changeFilesOptions.Files[0].Path = createTreePath changeFilesOptions.Files[1].Path = updateTreePath changeFilesOptions.Files[2].Path = deleteTreePath - url := fmt.Sprintf("/api/v1/repos/%s/%s/contents?token=%s", user2.Name, repo1.Name, token2) - req := NewRequestWithJSON(t, "POST", url, &changeFilesOptions) + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents", user2.Name, repo1.Name), &changeFilesOptions). + AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusCreated) gitRepo, _ := git.OpenRepository(stdCtx.Background(), repo1.RepoPath()) commitID, _ := gitRepo.GetBranchCommitID(changeFilesOptions.NewBranchName) @@ -138,8 +138,9 @@ func TestAPIChangeFiles(t *testing.T) { changeFilesOptions.Files[2].Path = deleteTreePath createFile(user2, repo1, updateTreePath) createFile(user2, repo1, deleteTreePath) - url := fmt.Sprintf("/api/v1/repos/%s/%s/contents?token=%s", user2.Name, repo1.Name, token2) - req := NewRequestWithJSON(t, "POST", url, &changeFilesOptions) + url := fmt.Sprintf("/api/v1/repos/%s/%s/contents", user2.Name, repo1.Name) + req := NewRequestWithJSON(t, "POST", url, &changeFilesOptions). + AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusCreated) var filesResponse api.FilesResponse DecodeJSON(t, resp, &filesResponse) @@ -168,7 +169,8 @@ func TestAPIChangeFiles(t *testing.T) { changeFilesOptions.Files = []*api.ChangeFileOperation{changeFilesOptions.Files[1]} changeFilesOptions.Files[0].FromPath = updateTreePath changeFilesOptions.Files[0].Path = "rename/" + updateTreePath - req = NewRequestWithJSON(t, "POST", url, &changeFilesOptions) + req = NewRequestWithJSON(t, "POST", url, &changeFilesOptions). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, &filesResponse) expectedUpdateSHA = "08bd14b2e2852529157324de9c226b3364e76136" @@ -191,7 +193,8 @@ func TestAPIChangeFiles(t *testing.T) { changeFilesOptions.Files[2].Path = deleteTreePath createFile(user2, repo1, updateTreePath) createFile(user2, repo1, deleteTreePath) - req = NewRequestWithJSON(t, "POST", url, &changeFilesOptions) + req = NewRequestWithJSON(t, "POST", url, &changeFilesOptions). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, &filesResponse) expectedMessage := fmt.Sprintf("Add %v\nUpdate %v\nDelete %v\n", createTreePath, updateTreePath, deleteTreePath) @@ -206,7 +209,8 @@ func TestAPIChangeFiles(t *testing.T) { changeFilesOptions.Files[0].Path = updateTreePath correctSHA := changeFilesOptions.Files[0].SHA changeFilesOptions.Files[0].SHA = "badsha" - req = NewRequestWithJSON(t, "POST", url, &changeFilesOptions) + req = NewRequestWithJSON(t, "POST", url, &changeFilesOptions). + AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusUnprocessableEntity) expectedAPIError := context.APIError{ Message: "sha does not match [given: " + changeFilesOptions.Files[0].SHA + ", expected: " + correctSHA + "]", @@ -227,8 +231,8 @@ func TestAPIChangeFiles(t *testing.T) { changeFilesOptions.Files[0].Path = createTreePath changeFilesOptions.Files[1].Path = updateTreePath changeFilesOptions.Files[2].Path = deleteTreePath - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents?token=%s", user2.Name, repo16.Name, token4) - req = NewRequestWithJSON(t, "POST", url, &changeFilesOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents", user2.Name, repo16.Name), &changeFilesOptions). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusNotFound) // Tests a repo with no token given so will fail @@ -242,8 +246,7 @@ func TestAPIChangeFiles(t *testing.T) { changeFilesOptions.Files[0].Path = createTreePath changeFilesOptions.Files[1].Path = updateTreePath changeFilesOptions.Files[2].Path = deleteTreePath - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents", user2.Name, repo16.Name) - req = NewRequestWithJSON(t, "POST", url, &changeFilesOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents", user2.Name, repo16.Name), &changeFilesOptions) MakeRequest(t, req, http.StatusNotFound) // Test using access token for a private repo that the user of the token owns @@ -257,8 +260,8 @@ func TestAPIChangeFiles(t *testing.T) { changeFilesOptions.Files[0].Path = createTreePath changeFilesOptions.Files[1].Path = updateTreePath changeFilesOptions.Files[2].Path = deleteTreePath - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents?token=%s", user2.Name, repo16.Name, token2) - req = NewRequestWithJSON(t, "POST", url, &changeFilesOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents", user2.Name, repo16.Name), &changeFilesOptions). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusCreated) // Test using org repo "org3/repo3" where user2 is a collaborator @@ -272,8 +275,8 @@ func TestAPIChangeFiles(t *testing.T) { changeFilesOptions.Files[0].Path = createTreePath changeFilesOptions.Files[1].Path = updateTreePath changeFilesOptions.Files[2].Path = deleteTreePath - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents?token=%s", org3.Name, repo3.Name, token2) - req = NewRequestWithJSON(t, "POST", url, &changeFilesOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents", org3.Name, repo3.Name), &changeFilesOptions). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusCreated) // Test using org repo "org3/repo3" with no user token @@ -287,8 +290,7 @@ func TestAPIChangeFiles(t *testing.T) { changeFilesOptions.Files[0].Path = createTreePath changeFilesOptions.Files[1].Path = updateTreePath changeFilesOptions.Files[2].Path = deleteTreePath - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents", org3.Name, repo3.Name) - req = NewRequestWithJSON(t, "POST", url, &changeFilesOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents", org3.Name, repo3.Name), &changeFilesOptions) MakeRequest(t, req, http.StatusNotFound) // Test using repo "user2/repo1" where user4 is a NOT collaborator @@ -302,8 +304,8 @@ func TestAPIChangeFiles(t *testing.T) { changeFilesOptions.Files[0].Path = createTreePath changeFilesOptions.Files[1].Path = updateTreePath changeFilesOptions.Files[2].Path = deleteTreePath - url = fmt.Sprintf("/api/v1/repos/%s/%s/contents?token=%s", user2.Name, repo1.Name, token4) - req = NewRequestWithJSON(t, "POST", url, &changeFilesOptions) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents", user2.Name, repo1.Name), &changeFilesOptions). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusForbidden) }) } diff --git a/tests/integration/api_repo_get_contents_list_test.go b/tests/integration/api_repo_get_contents_list_test.go index 7874eddfd4d19..86313f5e3b209 100644 --- a/tests/integration/api_repo_get_contents_list_test.go +++ b/tests/integration/api_repo_get_contents_list_test.go @@ -154,14 +154,17 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { MakeRequest(t, req, http.StatusNotFound) // Test accessing private ref with user token that does not have access - should fail - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo16.Name, treePath, token4) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusNotFound) // Test access private ref of owner of token - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/readme.md?token=%s", user2.Name, repo16.Name, token2) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/readme.md", user2.Name, repo16.Name). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusOK) // Test access of org org3 private repo file by owner user2 - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?token=%s", org3.Name, repo3.Name, treePath, token2) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusOK) } diff --git a/tests/integration/api_repo_get_contents_test.go b/tests/integration/api_repo_get_contents_test.go index 1d708a4cdb438..ffbdfcb0fab81 100644 --- a/tests/integration/api_repo_get_contents_test.go +++ b/tests/integration/api_repo_get_contents_test.go @@ -151,15 +151,18 @@ func testAPIGetContents(t *testing.T, u *url.URL) { MakeRequest(t, req, http.StatusNotFound) // Test accessing private ref with user token that does not have access - should fail - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, repo16.Name, treePath, token4) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s", user2.Name, repo16.Name, treePath). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusNotFound) // Test access private ref of owner of token - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/readme.md?token=%s", user2.Name, repo16.Name, token2) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/readme.md", user2.Name, repo16.Name). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusOK) // Test access of org org3 private repo file by owner user2 - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s?token=%s", org3.Name, repo3.Name, treePath, token2) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/contents/%s", org3.Name, repo3.Name, treePath). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusOK) } diff --git a/tests/integration/api_repo_git_blobs_test.go b/tests/integration/api_repo_git_blobs_test.go index 866234d0a6cc9..184362e7e320f 100644 --- a/tests/integration/api_repo_git_blobs_test.go +++ b/tests/integration/api_repo_git_blobs_test.go @@ -48,7 +48,8 @@ func TestAPIReposGitBlobs(t *testing.T) { MakeRequest(t, req, http.StatusNotFound) // Test using access token for a private repo that the user of the token owns - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/blobs/%s?token=%s", user2.Name, repo16.Name, repo16ReadmeSHA, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/blobs/%s", user2.Name, repo16.Name, repo16ReadmeSHA). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) // Test using bad sha @@ -56,11 +57,13 @@ func TestAPIReposGitBlobs(t *testing.T) { MakeRequest(t, req, http.StatusBadRequest) // Test using org repo "org3/repo3" where user2 is a collaborator - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/blobs/%s?token=%s", org3.Name, repo3.Name, repo3ReadmeSHA, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/blobs/%s", org3.Name, repo3.Name, repo3ReadmeSHA). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) // Test using org repo "org3/repo3" where user2 is a collaborator - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/blobs/%s?token=%s", org3.Name, repo3.Name, repo3ReadmeSHA, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/blobs/%s", org3.Name, repo3.Name, repo3ReadmeSHA). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) // Test using org repo "org3/repo3" with no user token diff --git a/tests/integration/api_repo_git_commits_test.go b/tests/integration/api_repo_git_commits_test.go index 765055720d79d..365520620730e 100644 --- a/tests/integration/api_repo_git_commits_test.go +++ b/tests/integration/api_repo_git_commits_test.go @@ -32,13 +32,16 @@ func TestAPIReposGitCommits(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // check invalid requests - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/12345?token="+token, user.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/12345", user.Name). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/..?token="+token, user.Name) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/..", user.Name). + AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) - req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/branch-not-exist?token="+token, user.Name) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/branch-not-exist", user.Name). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) for _, ref := range [...]string{ @@ -47,7 +50,8 @@ func TestAPIReposGitCommits(t *testing.T) { "65f1", // short sha "65f1bf27bc3bf70f64657658635e66094edbcb4d", // full sha } { - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/%s?token="+token, user.Name, ref) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/commits/%s", user.Name, ref). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) } } @@ -60,7 +64,8 @@ func TestAPIReposGitCommitList(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Test getting commits (Page 1) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo20/commits?token="+token+"¬=master&sha=remove-files-a", user.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo20/commits?not=master&sha=remove-files-a", user.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiData []api.Commit @@ -83,7 +88,8 @@ func TestAPIReposGitCommitListNotMaster(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Test getting commits (Page 1) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?token="+token, user.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits", user.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiData []api.Commit @@ -108,7 +114,8 @@ func TestAPIReposGitCommitListPage2Empty(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Test getting commits (Page=2) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?token="+token+"&page=2", user.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?page=2", user.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiData []api.Commit @@ -125,7 +132,8 @@ func TestAPIReposGitCommitListDifferentBranch(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Test getting commits (Page=1, Branch=good-sign) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?token="+token+"&sha=good-sign", user.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?sha=good-sign", user.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiData []api.Commit @@ -144,7 +152,8 @@ func TestAPIReposGitCommitListWithoutSelectFields(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Test getting commits without files, verification, and stats - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?token="+token+"&sha=good-sign&stat=false&files=false&verification=false", user.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?sha=good-sign&stat=false&files=false&verification=false", user.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiData []api.Commit @@ -165,14 +174,16 @@ func TestDownloadCommitDiffOrPatch(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Test getting diff - reqDiff := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/git/commits/f27c2b2b03dcab38beaf89b0ab4ff61f6de63441.diff?token="+token, user.Name) + reqDiff := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/git/commits/f27c2b2b03dcab38beaf89b0ab4ff61f6de63441.diff", user.Name). + AddTokenAuth(token) resp := MakeRequest(t, reqDiff, http.StatusOK) assert.EqualValues(t, "commit f27c2b2b03dcab38beaf89b0ab4ff61f6de63441\nAuthor: User2 \nDate: Sun Aug 6 19:55:01 2017 +0200\n\n good signed commit\n\ndiff --git a/readme.md b/readme.md\nnew file mode 100644\nindex 0000000..458121c\n--- /dev/null\n+++ b/readme.md\n@@ -0,0 +1 @@\n+good sign\n", resp.Body.String()) // Test getting patch - reqPatch := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/git/commits/f27c2b2b03dcab38beaf89b0ab4ff61f6de63441.patch?token="+token, user.Name) + reqPatch := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/git/commits/f27c2b2b03dcab38beaf89b0ab4ff61f6de63441.patch", user.Name). + AddTokenAuth(token) resp = MakeRequest(t, reqPatch, http.StatusOK) assert.EqualValues(t, "From f27c2b2b03dcab38beaf89b0ab4ff61f6de63441 Mon Sep 17 00:00:00 2001\nFrom: User2 \nDate: Sun, 6 Aug 2017 19:55:01 +0200\nSubject: [PATCH] good signed commit\n\n---\n readme.md | 1 +\n 1 file changed, 1 insertion(+)\n create mode 100644 readme.md\n\ndiff --git a/readme.md b/readme.md\nnew file mode 100644\nindex 0000000..458121c\n--- /dev/null\n+++ b/readme.md\n@@ -0,0 +1 @@\n+good sign\n", @@ -186,7 +197,8 @@ func TestGetFileHistory(t *testing.T) { session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?path=readme.md&token="+token+"&sha=good-sign", user.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/commits?path=readme.md&sha=good-sign", user.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiData []api.Commit @@ -206,7 +218,8 @@ func TestGetFileHistoryNotOnMaster(t *testing.T) { session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo20/commits?path=test.csv&token="+token+"&sha=add-csv¬=master", user.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo20/commits?path=test.csv&sha=add-csv¬=master", user.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiData []api.Commit diff --git a/tests/integration/api_repo_git_hook_test.go b/tests/integration/api_repo_git_hook_test.go index 9f3205ce60d9e..9917b41790d12 100644 --- a/tests/integration/api_repo_git_hook_test.go +++ b/tests/integration/api_repo_git_hook_test.go @@ -32,8 +32,8 @@ func TestAPIListGitHooks(t *testing.T) { // user1 is an admin user session := loginUser(t, "user1") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git?token=%s", - owner.Name, repo.Name, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git", owner.Name, repo.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiGitHooks []*api.GitHook DecodeJSON(t, resp, &apiGitHooks) @@ -58,8 +58,8 @@ func TestAPIListGitHooksNoHooks(t *testing.T) { // user1 is an admin user session := loginUser(t, "user1") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git?token=%s", - owner.Name, repo.Name, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git", owner.Name, repo.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiGitHooks []*api.GitHook DecodeJSON(t, resp, &apiGitHooks) @@ -78,8 +78,8 @@ func TestAPIListGitHooksNoAccess(t *testing.T) { session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git?token=%s", - owner.Name, repo.Name, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git", owner.Name, repo.Name). + AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) } @@ -92,8 +92,8 @@ func TestAPIGetGitHook(t *testing.T) { // user1 is an admin user session := loginUser(t, "user1") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s", - owner.Name, repo.Name, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git/pre-receive", owner.Name, repo.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiGitHook *api.GitHook DecodeJSON(t, resp, &apiGitHook) @@ -109,8 +109,8 @@ func TestAPIGetGitHookNoAccess(t *testing.T) { session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s", - owner.Name, repo.Name, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git/pre-receive", owner.Name, repo.Name). + AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) } @@ -124,19 +124,19 @@ func TestAPIEditGitHook(t *testing.T) { session := loginUser(t, "user1") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s", - owner.Name, repo.Name, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/hooks/git/pre-receive", + owner.Name, repo.Name) req := NewRequestWithJSON(t, "PATCH", urlStr, &api.EditGitHookOption{ Content: testHookContent, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiGitHook *api.GitHook DecodeJSON(t, resp, &apiGitHook) assert.True(t, apiGitHook.IsActive) assert.Equal(t, testHookContent, apiGitHook.Content) - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s", - owner.Name, repo.Name, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git/pre-receive", owner.Name, repo.Name). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var apiGitHook2 *api.GitHook DecodeJSON(t, resp, &apiGitHook2) @@ -152,11 +152,10 @@ func TestAPIEditGitHookNoAccess(t *testing.T) { session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s", - owner.Name, repo.Name, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/hooks/git/pre-receive", owner.Name, repo.Name) req := NewRequestWithJSON(t, "PATCH", urlStr, &api.EditGitHookOption{ Content: testHookContent, - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) } @@ -170,12 +169,12 @@ func TestAPIDeleteGitHook(t *testing.T) { session := loginUser(t, "user1") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s", - owner.Name, repo.Name, token) + req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/hooks/git/pre-receive", owner.Name, repo.Name). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s", - owner.Name, repo.Name, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/hooks/git/pre-receive", owner.Name, repo.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiGitHook2 *api.GitHook DecodeJSON(t, resp, &apiGitHook2) @@ -191,7 +190,7 @@ func TestAPIDeleteGitHookNoAccess(t *testing.T) { session := loginUser(t, owner.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/hooks/git/pre-receive?token=%s", - owner.Name, repo.Name, token) + req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/hooks/git/pre-receive", owner.Name, repo.Name). + AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) } diff --git a/tests/integration/api_repo_git_notes_test.go b/tests/integration/api_repo_git_notes_test.go index a7327d932748f..9f3e927077e9b 100644 --- a/tests/integration/api_repo_git_notes_test.go +++ b/tests/integration/api_repo_git_notes_test.go @@ -24,14 +24,17 @@ func TestAPIReposGitNotes(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // check invalid requests - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/notes/12345?token=%s", user.Name, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/notes/12345", user.Name). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/notes/..?token=%s", user.Name, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/notes/..", user.Name). + AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) // check valid request - req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/notes/65f1bf27bc3bf70f64657658635e66094edbcb4d?token=%s", user.Name, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/notes/65f1bf27bc3bf70f64657658635e66094edbcb4d", user.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiData api.Note diff --git a/tests/integration/api_repo_git_ref_test.go b/tests/integration/api_repo_git_ref_test.go index 20900b3241944..875752ae3fd86 100644 --- a/tests/integration/api_repo_git_ref_test.go +++ b/tests/integration/api_repo_git_ref_test.go @@ -24,13 +24,16 @@ func TestAPIReposGitRefs(t *testing.T) { "refs/heads/master", // Branch "refs/tags/v1.1", // Tag } { - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/%s?token="+token, user.Name, ref) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/%s", user.Name, ref). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) } // Test getting all refs - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/refs?token="+token, user.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/refs", user.Name). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) // Test getting non-existent refs - req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/refs/heads/unknown?token="+token, user.Name) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/git/refs/heads/unknown", user.Name). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) } diff --git a/tests/integration/api_repo_git_tags_test.go b/tests/integration/api_repo_git_tags_test.go index a9d47abf9378d..2e8510ab1b3ae 100644 --- a/tests/integration/api_repo_git_tags_test.go +++ b/tests/integration/api_repo_git_tags_test.go @@ -45,7 +45,8 @@ func TestAPIGitTags(t *testing.T) { aTag, _ := gitRepo.GetTag(aTagName) // SHOULD work for annotated tags - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/tags/%s?token=%s", user.Name, repo.Name, aTag.ID.String(), token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/tags/%s", user.Name, repo.Name, aTag.ID.String()). + AddTokenAuth(token) res := MakeRequest(t, req, http.StatusOK) var tag *api.AnnotatedTag @@ -60,7 +61,8 @@ func TestAPIGitTags(t *testing.T) { assert.Equal(t, util.URLJoin(repo.APIURL(), "git/tags", aTag.ID.String()), tag.URL) // Should NOT work for lightweight tags - badReq := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/tags/%s?token=%s", user.Name, repo.Name, commit.ID.String(), token) + badReq := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/tags/%s", user.Name, repo.Name, commit.ID.String()). + AddTokenAuth(token) MakeRequest(t, badReq, http.StatusBadRequest) } @@ -72,17 +74,14 @@ func TestAPIDeleteTagByName(t *testing.T) { session := loginUser(t, owner.LowerName) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/tags/delete-tag?token=%s", - owner.Name, repo.Name, token) - - req := NewRequestf(t, http.MethodDelete, urlStr) + req := NewRequest(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/tags/delete-tag", owner.Name, repo.Name)). + AddTokenAuth(token) _ = MakeRequest(t, req, http.StatusNoContent) // Make sure that actual releases can't be deleted outright createNewReleaseUsingAPI(t, session, token, owner, repo, "release-tag", "", "Release Tag", "test") - urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/tags/release-tag?token=%s", - owner.Name, repo.Name, token) - req = NewRequestf(t, http.MethodDelete, urlStr) + req = NewRequest(t, http.MethodDelete, fmt.Sprintf("/api/v1/repos/%s/%s/tags/release-tag", owner.Name, repo.Name)). + AddTokenAuth(token) _ = MakeRequest(t, req, http.StatusConflict) } diff --git a/tests/integration/api_repo_git_trees_test.go b/tests/integration/api_repo_git_trees_test.go index aa732b9946cf0..8eec6d8d220d6 100644 --- a/tests/integration/api_repo_git_trees_test.go +++ b/tests/integration/api_repo_git_trees_test.go @@ -50,7 +50,8 @@ func TestAPIReposGitTrees(t *testing.T) { } // Test using access token for a private repo that the user of the token owns - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/trees/%s?token=%s", user2.Name, repo16.Name, repo16TreeSHA, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/trees/%s", user2.Name, repo16.Name, repo16TreeSHA). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) // Test using bad sha @@ -58,7 +59,8 @@ func TestAPIReposGitTrees(t *testing.T) { MakeRequest(t, req, http.StatusBadRequest) // Test using org repo "org3/repo3" where user2 is a collaborator - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/trees/%s?token=%s", org3.Name, repo3.Name, repo3TreeSHA, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/git/trees/%s", org3.Name, repo3.Name, repo3TreeSHA). + AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) // Test using org repo "org3/repo3" with no user token diff --git a/tests/integration/api_repo_hook_test.go b/tests/integration/api_repo_hook_test.go index 18b12597dbdb2..f27fcc00d6b3f 100644 --- a/tests/integration/api_repo_hook_test.go +++ b/tests/integration/api_repo_hook_test.go @@ -27,17 +27,14 @@ func TestAPICreateHook(t *testing.T) { // user1 is an admin user session := loginUser(t, "user1") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - completeURL := func(lastSegment string) string { - return fmt.Sprintf("/api/v1/repos/%s/%s/%s?token=%s", owner.Name, repo.Name, lastSegment, token) - } - req := NewRequestWithJSON(t, "POST", completeURL("hooks"), api.CreateHookOption{ + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/%s", owner.Name, repo.Name, "hooks"), api.CreateHookOption{ Type: "gitea", Config: api.CreateHookOptionConfig{ "content_type": "json", "url": "http://example.com/", }, AuthorizationHeader: "Bearer s3cr3t", - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var apiHook *api.Hook diff --git a/tests/integration/api_repo_lfs_migrate_test.go b/tests/integration/api_repo_lfs_migrate_test.go index 2cd7132b76ccf..8b4d79db022c1 100644 --- a/tests/integration/api_repo_lfs_migrate_test.go +++ b/tests/integration/api_repo_lfs_migrate_test.go @@ -33,12 +33,12 @@ func TestAPIRepoLFSMigrateLocal(t *testing.T) { session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate?token="+token, &api.MigrateRepoOptions{ + req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate", &api.MigrateRepoOptions{ CloneAddr: path.Join(setting.RepoRootPath, "migration/lfs-test.git"), RepoOwnerID: user.ID, RepoName: "lfs-test-local", LFS: true, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, NoExpectedStatus) assert.EqualValues(t, http.StatusCreated, resp.Code) diff --git a/tests/integration/api_repo_lfs_test.go b/tests/integration/api_repo_lfs_test.go index b0e9269bb86e2..211dcf76c1128 100644 --- a/tests/integration/api_repo_lfs_test.go +++ b/tests/integration/api_repo_lfs_test.go @@ -82,11 +82,10 @@ func TestAPILFSBatch(t *testing.T) { session := loginUser(t, "user2") - newRequest := func(t testing.TB, br *lfs.BatchRequest) *http.Request { - req := NewRequestWithJSON(t, "POST", "/user2/lfs-batch-repo.git/info/lfs/objects/batch", br) - req.Header.Set("Accept", lfs.MediaType) - req.Header.Set("Content-Type", lfs.MediaType) - return req + newRequest := func(t testing.TB, br *lfs.BatchRequest) *RequestWrapper { + return NewRequestWithJSON(t, "POST", "/user2/lfs-batch-repo.git/info/lfs/objects/batch", br). + SetHeader("Accept", lfs.MediaType). + SetHeader("Content-Type", lfs.MediaType) } decodeResponse := func(t *testing.T, b *bytes.Buffer) *lfs.BatchResponse { var br lfs.BatchResponse @@ -342,9 +341,8 @@ func TestAPILFSUpload(t *testing.T) { session := loginUser(t, "user2") - newRequest := func(t testing.TB, p lfs.Pointer, content string) *http.Request { - req := NewRequestWithBody(t, "PUT", path.Join("/user2/lfs-upload-repo.git/info/lfs/objects/", p.Oid, strconv.FormatInt(p.Size, 10)), strings.NewReader(content)) - return req + newRequest := func(t testing.TB, p lfs.Pointer, content string) *RequestWrapper { + return NewRequestWithBody(t, "PUT", path.Join("/user2/lfs-upload-repo.git/info/lfs/objects/", p.Oid, strconv.FormatInt(p.Size, 10)), strings.NewReader(content)) } t.Run("InvalidPointer", func(t *testing.T) { @@ -447,11 +445,10 @@ func TestAPILFSVerify(t *testing.T) { session := loginUser(t, "user2") - newRequest := func(t testing.TB, p *lfs.Pointer) *http.Request { - req := NewRequestWithJSON(t, "POST", "/user2/lfs-verify-repo.git/info/lfs/verify", p) - req.Header.Set("Accept", lfs.MediaType) - req.Header.Set("Content-Type", lfs.MediaType) - return req + newRequest := func(t testing.TB, p *lfs.Pointer) *RequestWrapper { + return NewRequestWithJSON(t, "POST", "/user2/lfs-verify-repo.git/info/lfs/verify", p). + SetHeader("Accept", lfs.MediaType). + SetHeader("Content-Type", lfs.MediaType) } t.Run("InvalidJsonRequest", func(t *testing.T) { diff --git a/tests/integration/api_repo_raw_test.go b/tests/integration/api_repo_raw_test.go index ccb20a939ee62..e5f83d1c80c09 100644 --- a/tests/integration/api_repo_raw_test.go +++ b/tests/integration/api_repo_raw_test.go @@ -27,12 +27,14 @@ func TestAPIReposRaw(t *testing.T) { "v1.1", // Tag "65f1bf27bc3bf70f64657658635e66094edbcb4d", // Commit } { - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/raw/%s/README.md?token="+token, user.Name, ref) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/raw/%s/README.md", user.Name, ref). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) assert.EqualValues(t, "file", resp.Header().Get("x-gitea-object-type")) } // Test default branch - req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/raw/README.md?token="+token, user.Name) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/raw/README.md", user.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) assert.EqualValues(t, "file", resp.Header().Get("x-gitea-object-type")) } diff --git a/tests/integration/api_repo_secrets_test.go b/tests/integration/api_repo_secrets_test.go index 263ad1608cda1..feb9bae2b22c7 100644 --- a/tests/integration/api_repo_secrets_test.go +++ b/tests/integration/api_repo_secrets_test.go @@ -60,44 +60,47 @@ func TestAPIRepoSecrets(t *testing.T) { } for _, c := range cases { - req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/actions/secrets/%s?token=%s", repo.FullName(), c.Name, token), api.CreateOrUpdateSecretOption{ + req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/actions/secrets/%s", repo.FullName(), c.Name), api.CreateOrUpdateSecretOption{ Data: "data", - }) + }).AddTokenAuth(token) MakeRequest(t, req, c.ExpectedStatus) } }) t.Run("Update", func(t *testing.T) { name := "update_secret" - url := fmt.Sprintf("/api/v1/repos/%s/actions/secrets/%s?token=%s", repo.FullName(), name, token) + url := fmt.Sprintf("/api/v1/repos/%s/actions/secrets/%s", repo.FullName(), name) req := NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{ Data: "initial", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) req = NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{ Data: "changed", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) }) t.Run("Delete", func(t *testing.T) { name := "delete_secret" - url := fmt.Sprintf("/api/v1/repos/%s/actions/secrets/%s?token=%s", repo.FullName(), name, token) + url := fmt.Sprintf("/api/v1/repos/%s/actions/secrets/%s", repo.FullName(), name) req := NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{ Data: "initial", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) - req = NewRequest(t, "DELETE", url) + req = NewRequest(t, "DELETE", url). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "DELETE", url) + req = NewRequest(t, "DELETE", url). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/actions/secrets/000?token=%s", repo.FullName(), token)) + req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/actions/secrets/000", repo.FullName())). + AddTokenAuth(token) MakeRequest(t, req, http.StatusBadRequest) }) } diff --git a/tests/integration/api_repo_tags_test.go b/tests/integration/api_repo_tags_test.go index c4282f99284df..c6eeb404c02c4 100644 --- a/tests/integration/api_repo_tags_test.go +++ b/tests/integration/api_repo_tags_test.go @@ -27,7 +27,8 @@ func TestAPIRepoTags(t *testing.T) { repoName := "repo1" - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/tags?token=%s", user.Name, repoName, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/tags", user.Name, repoName). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var tags []*api.Tag @@ -55,14 +56,16 @@ func TestAPIRepoTags(t *testing.T) { } // get created tag - req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/tags/%s?token=%s", user.Name, repoName, newTag.Name, token) + req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/tags/%s", user.Name, repoName, newTag.Name). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) var tag *api.Tag DecodeJSON(t, resp, &tag) assert.EqualValues(t, newTag, tag) // delete tag - delReq := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/tags/%s?token=%s", user.Name, repoName, newTag.Name, token) + delReq := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/tags/%s", user.Name, repoName, newTag.Name). + AddTokenAuth(token) MakeRequest(t, delReq, http.StatusNoContent) // check if it's gone @@ -70,12 +73,12 @@ func TestAPIRepoTags(t *testing.T) { } func createNewTagUsingAPI(t *testing.T, session *TestSession, token, ownerName, repoName, name, target, msg string) *api.Tag { - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/tags?token=%s", ownerName, repoName, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/tags", ownerName, repoName) req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateTagOption{ TagName: name, Message: msg, Target: target, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var respObj api.Tag diff --git a/tests/integration/api_repo_teams_test.go b/tests/integration/api_repo_teams_test.go index 23cf8a25672fc..558bac8150146 100644 --- a/tests/integration/api_repo_teams_test.go +++ b/tests/integration/api_repo_teams_test.go @@ -31,8 +31,8 @@ func TestAPIRepoTeams(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // ListTeams - url := fmt.Sprintf("/api/v1/repos/%s/teams?token=%s", publicOrgRepo.FullName(), token) - req := NewRequest(t, "GET", url) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/teams", publicOrgRepo.FullName())). + AddTokenAuth(token) res := MakeRequest(t, req, http.StatusOK) var teams []*api.Team DecodeJSON(t, res, &teams) @@ -49,34 +49,34 @@ func TestAPIRepoTeams(t *testing.T) { } // IsTeam - url = fmt.Sprintf("/api/v1/repos/%s/teams/%s?token=%s", publicOrgRepo.FullName(), "Test_Team", token) - req = NewRequest(t, "GET", url) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/teams/%s", publicOrgRepo.FullName(), "Test_Team")). + AddTokenAuth(token) res = MakeRequest(t, req, http.StatusOK) var team *api.Team DecodeJSON(t, res, &team) assert.EqualValues(t, teams[1], team) - url = fmt.Sprintf("/api/v1/repos/%s/teams/%s?token=%s", publicOrgRepo.FullName(), "NonExistingTeam", token) - req = NewRequest(t, "GET", url) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/teams/%s", publicOrgRepo.FullName(), "NonExistingTeam")). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) // AddTeam with user4 - url = fmt.Sprintf("/api/v1/repos/%s/teams/%s?token=%s", publicOrgRepo.FullName(), "team1", token) - req = NewRequest(t, "PUT", url) + req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/teams/%s", publicOrgRepo.FullName(), "team1")). + AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) // AddTeam with user2 user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) session = loginUser(t, user.Name) token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - url = fmt.Sprintf("/api/v1/repos/%s/teams/%s?token=%s", publicOrgRepo.FullName(), "team1", token) - req = NewRequest(t, "PUT", url) + req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/teams/%s", publicOrgRepo.FullName(), "team1")). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) MakeRequest(t, req, http.StatusUnprocessableEntity) // test duplicate request // DeleteTeam - url = fmt.Sprintf("/api/v1/repos/%s/teams/%s?token=%s", publicOrgRepo.FullName(), "team1", token) - req = NewRequest(t, "DELETE", url) + req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/teams/%s", publicOrgRepo.FullName(), "team1")). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) MakeRequest(t, req, http.StatusUnprocessableEntity) // test duplicate request } diff --git a/tests/integration/api_repo_test.go b/tests/integration/api_repo_test.go index fa159c6c5b9c6..90f84c794e123 100644 --- a/tests/integration/api_repo_test.go +++ b/tests/integration/api_repo_test.go @@ -45,8 +45,8 @@ func TestAPIUserReposWithWrongToken(t *testing.T) { defer tests.PrepareTestEnv(t)() user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) wrongToken := fmt.Sprintf("Bearer %s", "wrong_token") - req := NewRequestf(t, "GET", "/api/v1/users/%s/repos", user.Name) - req = addTokenAuthHeader(req, wrongToken) + req := NewRequestf(t, "GET", "/api/v1/users/%s/repos", user.Name). + AddTokenAuth(wrongToken) resp := MakeRequest(t, req, http.StatusUnauthorized) assert.Contains(t, resp.Body.String(), "user does not exist") @@ -208,7 +208,8 @@ func TestAPISearchRepo(t *testing.T) { } t.Run(testName, func(t *testing.T) { - request := NewRequest(t, "GET", testCase.requestURL+"&token="+token) + request := NewRequest(t, "GET", testCase.requestURL). + AddTokenAuth(token) response := MakeRequest(t, request, http.StatusOK) var body api.SearchResults @@ -309,7 +310,8 @@ func TestAPIOrgRepos(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) t.Run(testName, func(t *testing.T) { - req := NewRequestf(t, "GET", "/api/v1/orgs/%s/repos?token="+token, sourceOrg.Name) + req := NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", sourceOrg.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiRepos []*api.Repository @@ -329,7 +331,8 @@ func TestAPIGetRepoByIDUnauthorized(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) - req := NewRequestf(t, "GET", "/api/v1/repositories/2?token="+token) + req := NewRequest(t, "GET", "/api/v1/repositories/2"). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) } @@ -353,11 +356,11 @@ func TestAPIRepoMigrate(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate?token="+token, &api.MigrateRepoOptions{ + req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate", &api.MigrateRepoOptions{ CloneAddr: testCase.cloneURL, RepoOwnerID: testCase.userID, RepoName: testCase.repoName, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, NoExpectedStatus) if resp.Code == http.StatusUnprocessableEntity { respJSON := map[string]string{} @@ -398,12 +401,13 @@ func testAPIRepoMigrateConflict(t *testing.T, u *url.URL) { cloneURL := "https://github.com/go-gitea/test_repo.git" - req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate?token="+httpContext.Token, + req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate", &api.MigrateRepoOptions{ CloneAddr: cloneURL, RepoOwnerID: userID, RepoName: httpContext.Reponame, - }) + }). + AddTokenAuth(httpContext.Token) resp := httpContext.Session.MakeRequest(t, req, http.StatusConflict) respJSON := map[string]string{} DecodeJSON(t, resp, &respJSON) @@ -425,7 +429,8 @@ func TestAPIMirrorSyncNonMirrorRepo(t *testing.T) { DecodeJSON(t, resp, &repo) assert.False(t, repo.Mirror) - req = NewRequestf(t, "POST", "/api/v1/repos/user2/repo1/mirror-sync?token=%s", token) + req = NewRequestf(t, "POST", "/api/v1/repos/user2/repo1/mirror-sync"). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusBadRequest) errRespJSON := map[string]string{} DecodeJSON(t, resp, &errRespJSON) @@ -450,9 +455,9 @@ func TestAPIOrgRepoCreate(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID}) session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/org/%s/repos?token="+token, testCase.orgName), &api.CreateRepoOption{ + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/org/%s/repos", testCase.orgName), &api.CreateRepoOption{ Name: testCase.repoName, - }) + }).AddTokenAuth(token) MakeRequest(t, req, testCase.expectedStatus) } } @@ -473,10 +478,11 @@ func testAPIRepoCreateConflict(t *testing.T, u *url.URL) { httpContext.Reponame = "repo-tmp-17" t.Run("CreateRepo", doAPICreateRepository(httpContext, false)) - req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos?token="+httpContext.Token, + req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos", &api.CreateRepoOption{ Name: httpContext.Reponame, - }) + }). + AddTokenAuth(httpContext.Token) resp := httpContext.Session.MakeRequest(t, req, http.StatusConflict) respJSON := map[string]string{} DecodeJSON(t, resp, &respJSON) @@ -516,13 +522,13 @@ func TestAPIRepoTransfer(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) repoName := "moveME" apiRepo := new(api.Repository) - req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/user/repos?token=%s", token), &api.CreateRepoOption{ + req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos", &api.CreateRepoOption{ Name: repoName, Description: "repo move around", Private: false, Readme: "Default", AutoInit: true, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, apiRepo) @@ -532,10 +538,10 @@ func TestAPIRepoTransfer(t *testing.T) { repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID}) session = loginUser(t, user.Name) token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer?token=%s", repo.OwnerName, repo.Name, token), &api.TransferRepoOption{ + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer", repo.OwnerName, repo.Name), &api.TransferRepoOption{ NewOwner: testCase.newOwner, TeamIDs: testCase.teams, - }) + }).AddTokenAuth(token) MakeRequest(t, req, testCase.expectedStatus) } @@ -551,21 +557,21 @@ func transfer(t *testing.T) *repo_model.Repository { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) repoName := "moveME" apiRepo := new(api.Repository) - req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/user/repos?token=%s", token), &api.CreateRepoOption{ + req := NewRequestWithJSON(t, "POST", "/api/v1/user/repos", &api.CreateRepoOption{ Name: repoName, Description: "repo move around", Private: false, Readme: "Default", AutoInit: true, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, apiRepo) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID}) - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer?token=%s", repo.OwnerName, repo.Name, token), &api.TransferRepoOption{ + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer", repo.OwnerName, repo.Name), &api.TransferRepoOption{ NewOwner: "user4", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) return repo @@ -579,18 +585,21 @@ func TestAPIAcceptTransfer(t *testing.T) { // try to accept with not authorized user session := loginUser(t, "user2") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) - req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/reject?token=%s", repo.OwnerName, repo.Name, token)) + req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/reject", repo.OwnerName, repo.Name)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) // try to accept repo that's not marked as transferred - req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/accept?token=%s", "user2", "repo1", token)) + req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/accept", "user2", "repo1")). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) // accept transfer session = loginUser(t, "user4") token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) - req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/accept?token=%s", repo.OwnerName, repo.Name, token)) + req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/accept", repo.OwnerName, repo.Name)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusAccepted) apiRepo := new(api.Repository) DecodeJSON(t, resp, apiRepo) @@ -605,18 +614,21 @@ func TestAPIRejectTransfer(t *testing.T) { // try to reject with not authorized user session := loginUser(t, "user2") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/reject?token=%s", repo.OwnerName, repo.Name, token)) + req := NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/reject", repo.OwnerName, repo.Name)). + AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) // try to reject repo that's not marked as transferred - req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/reject?token=%s", "user2", "repo1", token)) + req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/reject", "user2", "repo1")). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) // reject transfer session = loginUser(t, "user4") token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/reject?token=%s", repo.OwnerName, repo.Name, token)) + req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer/reject", repo.OwnerName, repo.Name)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) apiRepo := new(api.Repository) DecodeJSON(t, resp, apiRepo) @@ -634,26 +646,26 @@ func TestAPIGenerateRepo(t *testing.T) { // user repo := new(api.Repository) - req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/generate?token=%s", templateRepo.OwnerName, templateRepo.Name, token), &api.GenerateRepoOption{ + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/generate", templateRepo.OwnerName, templateRepo.Name), &api.GenerateRepoOption{ Owner: user.Name, Name: "new-repo", Description: "test generate repo", Private: false, GitContent: true, - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, repo) assert.Equal(t, "new-repo", repo.Name) // org - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/generate?token=%s", templateRepo.OwnerName, templateRepo.Name, token), &api.GenerateRepoOption{ + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/generate", templateRepo.OwnerName, templateRepo.Name), &api.GenerateRepoOption{ Owner: "org3", Name: "new-repo", Description: "test generate repo", Private: false, GitContent: true, - }) + }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, repo) @@ -667,7 +679,8 @@ func TestAPIRepoGetReviewers(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/reviewers?token=%s", user.Name, repo.Name, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/reviewers", user.Name, repo.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var reviewers []*api.User DecodeJSON(t, resp, &reviewers) @@ -681,7 +694,8 @@ func TestAPIRepoGetAssignees(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/assignees?token=%s", user.Name, repo.Name, token) + req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/assignees", user.Name, repo.Name). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var assignees []*api.User DecodeJSON(t, resp, &assignees) diff --git a/tests/integration/api_repo_topic_test.go b/tests/integration/api_repo_topic_test.go index e7c9b95543b31..c41bc4abb638f 100644 --- a/tests/integration/api_repo_topic_test.go +++ b/tests/integration/api_repo_topic_test.go @@ -63,30 +63,33 @@ func TestAPIRepoTopic(t *testing.T) { token2 := getUserToken(t, user2.Name, auth_model.AccessTokenScopeWriteRepository) // Test read topics using login - url := fmt.Sprintf("/api/v1/repos/%s/%s/topics", user2.Name, repo2.Name) - req := NewRequest(t, "GET", url+"?token="+token2) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/topics", user2.Name, repo2.Name)). + AddTokenAuth(token2) res := MakeRequest(t, req, http.StatusOK) var topics *api.TopicName DecodeJSON(t, res, &topics) assert.ElementsMatch(t, []string{"topicname1", "topicname2"}, topics.TopicNames) - // Log out user2 - url = fmt.Sprintf("/api/v1/repos/%s/%s/topics?token=%s", user2.Name, repo2.Name, token2) - // Test delete a topic - req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/topics/%s?token=%s", user2.Name, repo2.Name, "Topicname1", token2) + req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/topics/%s", user2.Name, repo2.Name, "Topicname1"). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) // Test add an existing topic - req = NewRequestf(t, "PUT", "/api/v1/repos/%s/%s/topics/%s?token=%s", user2.Name, repo2.Name, "Golang", token2) + req = NewRequestf(t, "PUT", "/api/v1/repos/%s/%s/topics/%s", user2.Name, repo2.Name, "Golang"). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) // Test add a topic - req = NewRequestf(t, "PUT", "/api/v1/repos/%s/%s/topics/%s?token=%s", user2.Name, repo2.Name, "topicName3", token2) + req = NewRequestf(t, "PUT", "/api/v1/repos/%s/%s/topics/%s", user2.Name, repo2.Name, "topicName3"). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) + url := fmt.Sprintf("/api/v1/repos/%s/%s/topics", user2.Name, repo2.Name) + // Test read topics using token - req = NewRequest(t, "GET", url) + req = NewRequest(t, "GET", url). + AddTokenAuth(token2) res = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, res, &topics) assert.ElementsMatch(t, []string{"topicname2", "golang", "topicname3"}, topics.TopicNames) @@ -95,9 +98,10 @@ func TestAPIRepoTopic(t *testing.T) { newTopics := []string{" windows ", " ", "MAC "} req = NewRequestWithJSON(t, "PUT", url, &api.RepoTopicOptions{ Topics: newTopics, - }) + }).AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "GET", url) + req = NewRequest(t, "GET", url). + AddTokenAuth(token2) res = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, res, &topics) assert.ElementsMatch(t, []string{"windows", "mac"}, topics.TopicNames) @@ -106,9 +110,10 @@ func TestAPIRepoTopic(t *testing.T) { newTopics = []string{"topicname1", "topicname2", "topicname!"} req = NewRequestWithJSON(t, "PUT", url, &api.RepoTopicOptions{ Topics: newTopics, - }) + }).AddTokenAuth(token2) MakeRequest(t, req, http.StatusUnprocessableEntity) - req = NewRequest(t, "GET", url) + req = NewRequest(t, "GET", url). + AddTokenAuth(token2) res = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, res, &topics) assert.ElementsMatch(t, []string{"windows", "mac"}, topics.TopicNames) @@ -117,9 +122,10 @@ func TestAPIRepoTopic(t *testing.T) { newTopics = []string{"t1", "t2", "t1", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "t13", "t14", "t15", "t16", "17", "t18", "t19", "t20", "t21", "t22", "t23", "t24", "t25"} req = NewRequestWithJSON(t, "PUT", url, &api.RepoTopicOptions{ Topics: newTopics, - }) + }).AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "GET", url) + req = NewRequest(t, "GET", url). + AddTokenAuth(token2) res = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, res, &topics) assert.Len(t, topics.TopicNames, 25) @@ -128,28 +134,31 @@ func TestAPIRepoTopic(t *testing.T) { newTopics = append(newTopics, "t26") req = NewRequestWithJSON(t, "PUT", url, &api.RepoTopicOptions{ Topics: newTopics, - }) + }).AddTokenAuth(token2) MakeRequest(t, req, http.StatusUnprocessableEntity) // Test add a topic when there is already maximum - req = NewRequestf(t, "PUT", "/api/v1/repos/%s/%s/topics/%s?token=%s", user2.Name, repo2.Name, "t26", token2) + req = NewRequestf(t, "PUT", "/api/v1/repos/%s/%s/topics/%s", user2.Name, repo2.Name, "t26"). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusUnprocessableEntity) // Test delete a topic that repo doesn't have - req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/topics/%s?token=%s", user2.Name, repo2.Name, "Topicname1", token2) + req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/topics/%s", user2.Name, repo2.Name, "Topicname1"). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusNotFound) // Get user4's token token4 := getUserToken(t, user4.Name, auth_model.AccessTokenScopeWriteRepository) // Test read topics with write access - url = fmt.Sprintf("/api/v1/repos/%s/%s/topics?token=%s", org3.Name, repo3.Name, token4) - req = NewRequest(t, "GET", url) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/topics", org3.Name, repo3.Name)). + AddTokenAuth(token4) res = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, res, &topics) assert.Empty(t, topics.TopicNames) // Test add a topic to repo with write access (requires repo admin access) - req = NewRequestf(t, "PUT", "/api/v1/repos/%s/%s/topics/%s?token=%s", org3.Name, repo3.Name, "topicName", token4) + req = NewRequestf(t, "PUT", "/api/v1/repos/%s/%s/topics/%s", org3.Name, repo3.Name, "topicName"). + AddTokenAuth(token4) MakeRequest(t, req, http.StatusForbidden) } diff --git a/tests/integration/api_team_test.go b/tests/integration/api_team_test.go index a9ae890717473..4df545284e97f 100644 --- a/tests/integration/api_team_test.go +++ b/tests/integration/api_team_test.go @@ -34,7 +34,8 @@ func TestAPITeam(t *testing.T) { session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) - req := NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamUser.TeamID) + req := NewRequestf(t, "GET", "/api/v1/teams/%d", teamUser.TeamID). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiTeam api.Team @@ -49,7 +50,8 @@ func TestAPITeam(t *testing.T) { session = loginUser(t, user2.Name) token = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) - req = NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamUser.TeamID) + req = NewRequestf(t, "GET", "/api/v1/teams/%d", teamUser.TeamID). + AddTokenAuth(token) _ = MakeRequest(t, req, http.StatusForbidden) req = NewRequestf(t, "GET", "/api/v1/teams/%d", teamUser.TeamID) @@ -70,7 +72,8 @@ func TestAPITeam(t *testing.T) { Permission: "write", Units: []string{"repo.code", "repo.issues"}, } - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams?token=%s", org.Name, token), teamToCreate) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams", org.Name), teamToCreate). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusCreated) apiTeam = api.Team{} DecodeJSON(t, resp, &apiTeam) @@ -91,7 +94,8 @@ func TestAPITeam(t *testing.T) { Units: []string{"repo.code", "repo.pulls", "repo.releases"}, } - req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/teams/%d?token=%s", teamID, token), teamToEdit) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/teams/%d", teamID), teamToEdit). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) apiTeam = api.Team{} DecodeJSON(t, resp, &apiTeam) @@ -103,7 +107,8 @@ func TestAPITeam(t *testing.T) { // Edit team Description only editDescription = "first team" teamToEditDesc := api.EditTeamOption{Description: &editDescription} - req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/teams/%d?token=%s", teamID, token), teamToEditDesc) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/teams/%d", teamID), teamToEditDesc). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) apiTeam = api.Team{} DecodeJSON(t, resp, &apiTeam) @@ -115,7 +120,8 @@ func TestAPITeam(t *testing.T) { // Read team. teamRead := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) assert.NoError(t, teamRead.LoadUnits(db.DefaultContext)) - req = NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamID) + req = NewRequestf(t, "GET", "/api/v1/teams/%d", teamID). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) apiTeam = api.Team{} DecodeJSON(t, resp, &apiTeam) @@ -123,7 +129,8 @@ func TestAPITeam(t *testing.T) { teamRead.AccessMode.String(), teamRead.GetUnitNames(), teamRead.GetUnitsMap()) // Delete team. - req = NewRequestf(t, "DELETE", "/api/v1/teams/%d?token="+token, teamID) + req = NewRequestf(t, "DELETE", "/api/v1/teams/%d", teamID). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) unittest.AssertNotExistsBean(t, &organization.Team{ID: teamID}) @@ -136,7 +143,8 @@ func TestAPITeam(t *testing.T) { Permission: "write", UnitsMap: map[string]string{"repo.code": "read", "repo.issues": "write", "repo.wiki": "none"}, } - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams?token=%s", org.Name, token), teamToCreate) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams", org.Name), teamToCreate). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusCreated) apiTeam = api.Team{} DecodeJSON(t, resp, &apiTeam) @@ -157,7 +165,8 @@ func TestAPITeam(t *testing.T) { UnitsMap: map[string]string{"repo.code": "read", "repo.pulls": "read", "repo.releases": "write"}, } - req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/teams/%d?token=%s", teamID, token), teamToEdit) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/teams/%d", teamID), teamToEdit). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) apiTeam = api.Team{} DecodeJSON(t, resp, &apiTeam) @@ -169,7 +178,8 @@ func TestAPITeam(t *testing.T) { // Edit team Description only editDescription = "second team" teamToEditDesc = api.EditTeamOption{Description: &editDescription} - req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/teams/%d?token=%s", teamID, token), teamToEditDesc) + req = NewRequestWithJSON(t, "PATCH", fmt.Sprintf("/api/v1/teams/%d", teamID), teamToEditDesc). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) apiTeam = api.Team{} DecodeJSON(t, resp, &apiTeam) @@ -180,7 +190,8 @@ func TestAPITeam(t *testing.T) { // Read team. teamRead = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}) - req = NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamID) + req = NewRequestf(t, "GET", "/api/v1/teams/%d", teamID). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) apiTeam = api.Team{} DecodeJSON(t, resp, &apiTeam) @@ -189,7 +200,8 @@ func TestAPITeam(t *testing.T) { teamRead.AccessMode.String(), teamRead.GetUnitNames(), teamRead.GetUnitsMap()) // Delete team. - req = NewRequestf(t, "DELETE", "/api/v1/teams/%d?token="+token, teamID) + req = NewRequestf(t, "DELETE", "/api/v1/teams/%d", teamID). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) unittest.AssertNotExistsBean(t, &organization.Team{ID: teamID}) @@ -200,7 +212,8 @@ func TestAPITeam(t *testing.T) { IncludesAllRepositories: true, Permission: "admin", } - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams?token=%s", org.Name, token), teamToCreate) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams", org.Name), teamToCreate). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusCreated) apiTeam = api.Team{} DecodeJSON(t, resp, &apiTeam) @@ -219,7 +232,8 @@ func TestAPITeam(t *testing.T) { teamID = apiTeam.ID // Delete team. - req = NewRequestf(t, "DELETE", "/api/v1/teams/%d?token="+token, teamID) + req = NewRequestf(t, "DELETE", "/api/v1/teams/%d", teamID). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) unittest.AssertNotExistsBean(t, &organization.Team{ID: teamID}) } @@ -263,7 +277,8 @@ func TestAPITeamSearch(t *testing.T) { var results TeamSearchResults token := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadOrganization) - req := NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s&token=%s", org.Name, "_team", token) + req := NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s", org.Name, "_team"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &results) assert.NotEmpty(t, results.Data) @@ -274,7 +289,8 @@ func TestAPITeamSearch(t *testing.T) { user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) token5 := getUserToken(t, user5.Name, auth_model.AccessTokenScopeReadOrganization) - req = NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s&token=%s", org.Name, "team", token5) + req = NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s", org.Name, "team"). + AddTokenAuth(token5) MakeRequest(t, req, http.StatusForbidden) } @@ -288,7 +304,8 @@ func TestAPIGetTeamRepo(t *testing.T) { var results api.Repository token := getUserToken(t, user.Name, auth_model.AccessTokenScopeReadOrganization) - req := NewRequestf(t, "GET", "/api/v1/teams/%d/repos/%s/?token=%s", team.ID, teamRepo.FullName(), token) + req := NewRequestf(t, "GET", "/api/v1/teams/%d/repos/%s/", team.ID, teamRepo.FullName()). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &results) assert.Equal(t, "big_test_private_4", teamRepo.Name) @@ -297,6 +314,7 @@ func TestAPIGetTeamRepo(t *testing.T) { user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}) token5 := getUserToken(t, user5.Name, auth_model.AccessTokenScopeReadOrganization) - req = NewRequestf(t, "GET", "/api/v1/teams/%d/repos/%s/?token=%s", team.ID, teamRepo.FullName(), token5) + req = NewRequestf(t, "GET", "/api/v1/teams/%d/repos/%s/", team.ID, teamRepo.FullName()). + AddTokenAuth(token5) MakeRequest(t, req, http.StatusNotFound) } diff --git a/tests/integration/api_team_user_test.go b/tests/integration/api_team_user_test.go index aa33c690413b9..6c80bc9f80b09 100644 --- a/tests/integration/api_team_user_test.go +++ b/tests/integration/api_team_user_test.go @@ -25,10 +25,12 @@ func TestAPITeamUser(t *testing.T) { normalUsername := "user2" session := loginUser(t, normalUsername) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization) - req := NewRequest(t, "GET", "/api/v1/teams/1/members/user1?token="+token) + req := NewRequest(t, "GET", "/api/v1/teams/1/members/user1"). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", "/api/v1/teams/1/members/user2?token="+token) + req = NewRequest(t, "GET", "/api/v1/teams/1/members/user2"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var user2 *api.User DecodeJSON(t, resp, &user2) diff --git a/tests/integration/api_token_test.go b/tests/integration/api_token_test.go index e28d9a372f3f0..9c7bf37330d03 100644 --- a/tests/integration/api_token_test.go +++ b/tests/integration/api_token_test.go @@ -35,8 +35,8 @@ func TestAPIDeleteMissingToken(t *testing.T) { defer tests.PrepareTestEnv(t)() user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - req := NewRequestf(t, "DELETE", "/api/v1/users/user1/tokens/%d", unittest.NonexistentID) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestf(t, "DELETE", "/api/v1/users/user1/tokens/%d", unittest.NonexistentID). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) } @@ -46,20 +46,20 @@ func TestAPIGetTokensPermission(t *testing.T) { // admin can get tokens for other users user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) - req := NewRequestf(t, "GET", "/api/v1/users/user2/tokens") - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", "/api/v1/users/user2/tokens"). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusOK) // non-admin can get tokens for himself user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - req = NewRequestf(t, "GET", "/api/v1/users/user2/tokens") - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", "/api/v1/users/user2/tokens"). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusOK) // non-admin can't get tokens for other users user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) - req = NewRequestf(t, "GET", "/api/v1/users/user2/tokens") - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", "/api/v1/users/user2/tokens"). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusForbidden) } @@ -73,20 +73,20 @@ func TestAPIDeleteTokensPermission(t *testing.T) { // admin can delete tokens for other users createAPIAccessTokenWithoutCleanUp(t, "test-key-1", user2, nil) - req := NewRequestf(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-1") - req = AddBasicAuthHeader(req, admin.Name) + req := NewRequest(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-1"). + AddBasicAuth(admin.Name) MakeRequest(t, req, http.StatusNoContent) // non-admin can delete tokens for himself createAPIAccessTokenWithoutCleanUp(t, "test-key-2", user2, nil) - req = NewRequestf(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-2") - req = AddBasicAuthHeader(req, user2.Name) + req = NewRequest(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-2"). + AddBasicAuth(user2.Name) MakeRequest(t, req, http.StatusNoContent) // non-admin can't delete tokens for other users createAPIAccessTokenWithoutCleanUp(t, "test-key-3", user2, nil) - req = NewRequestf(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-3") - req = AddBasicAuthHeader(req, user4.Name) + req = NewRequest(t, "DELETE", "/api/v1/users/"+user2.LoginName+"/tokens/test-key-3"). + AddBasicAuth(user4.Name) MakeRequest(t, req, http.StatusForbidden) } @@ -117,9 +117,6 @@ func TestAPIDeniesPermissionBasedOnTokenScope(t *testing.T) { // from other endpoints and not updated. // // Test cases are in alphabetical order by URL. - // - // Note: query parameters are not currently supported since the token is - // appended with `?=token=`. testCases := []requiredScopeTestCase{ { "/api/v1/admin/emails", @@ -526,11 +523,9 @@ func runTestCase(t *testing.T, testCase *requiredScopeTestCase, user *user_model accessToken := createAPIAccessTokenWithoutCleanUp(t, "test-token", user, &unauthorizedScopes) defer deleteAPIAccessToken(t, accessToken, user) - // Add API access token to the URL. - url := fmt.Sprintf("%s?token=%s", testCase.url, accessToken.Token) - // Request the endpoint. Verify that permission is denied. - req := NewRequestf(t, testCase.method, url) + req := NewRequest(t, testCase.method, testCase.url). + AddTokenAuth(accessToken.Token) MakeRequest(t, req, http.StatusForbidden) }) } @@ -552,9 +547,8 @@ func createAPIAccessTokenWithoutCleanUp(t *testing.T, tokenName string, user *us } } log.Debug("Requesting creation of token with scopes: %v", scopes) - req := NewRequestWithJSON(t, "POST", "/api/v1/users/"+user.LoginName+"/tokens", payload) - - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestWithJSON(t, "POST", "/api/v1/users/"+user.LoginName+"/tokens", payload). + AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusCreated) var newAccessToken api.AccessToken @@ -572,8 +566,8 @@ func createAPIAccessTokenWithoutCleanUp(t *testing.T, tokenName string, user *us // createAPIAccessTokenWithoutCleanUp Delete an API access token and assert that // deletion succeeded. func deleteAPIAccessToken(t *testing.T, accessToken api.AccessToken, user *user_model.User) { - req := NewRequestf(t, "DELETE", "/api/v1/users/"+user.LoginName+"/tokens/%d", accessToken.ID) - req = AddBasicAuthHeader(req, user.Name) + req := NewRequestf(t, "DELETE", "/api/v1/users/"+user.LoginName+"/tokens/%d", accessToken.ID). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) unittest.AssertNotExistsBean(t, &auth_model.AccessToken{ID: accessToken.ID}) diff --git a/tests/integration/api_twofa_test.go b/tests/integration/api_twofa_test.go index 1e5e26b8ccb0b..aad806b6dc4ff 100644 --- a/tests/integration/api_twofa_test.go +++ b/tests/integration/api_twofa_test.go @@ -23,8 +23,8 @@ func TestAPITwoFactor(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 16}) - req := NewRequestf(t, "GET", "/api/v1/user") - req = AddBasicAuthHeader(req, user.Name) + req := NewRequest(t, "GET", "/api/v1/user"). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusOK) otpKey, err := totp.Generate(totp.GenerateOpts{ @@ -41,15 +41,15 @@ func TestAPITwoFactor(t *testing.T) { assert.NoError(t, auth_model.NewTwoFactor(db.DefaultContext, tfa)) - req = NewRequestf(t, "GET", "/api/v1/user") - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", "/api/v1/user"). + AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusUnauthorized) passcode, err := totp.GenerateCode(otpKey.Secret(), time.Now()) assert.NoError(t, err) - req = NewRequestf(t, "GET", "/api/v1/user") - req = AddBasicAuthHeader(req, user.Name) + req = NewRequest(t, "GET", "/api/v1/user"). + AddBasicAuth(user.Name) req.Header.Set("X-Gitea-OTP", passcode) MakeRequest(t, req, http.StatusOK) } diff --git a/tests/integration/api_user_avatar_test.go b/tests/integration/api_user_avatar_test.go index 807c119e2c99c..5b4546f1504a2 100644 --- a/tests/integration/api_user_avatar_test.go +++ b/tests/integration/api_user_avatar_test.go @@ -35,14 +35,16 @@ func TestAPIUpdateUserAvatar(t *testing.T) { Image: base64.StdEncoding.EncodeToString(avatar), } - req := NewRequestWithJSON(t, "POST", "/api/v1/user/avatar?token="+token, &opts) + req := NewRequestWithJSON(t, "POST", "/api/v1/user/avatar", &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) opts = api.UpdateUserAvatarOption{ Image: "Invalid", } - req = NewRequestWithJSON(t, "POST", "/api/v1/user/avatar?token="+token, &opts) + req = NewRequestWithJSON(t, "POST", "/api/v1/user/avatar", &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusBadRequest) // Test what happens if you use a file that is not an image @@ -56,7 +58,8 @@ func TestAPIUpdateUserAvatar(t *testing.T) { Image: base64.StdEncoding.EncodeToString(text), } - req = NewRequestWithJSON(t, "POST", "/api/v1/user/avatar?token="+token, &opts) + req = NewRequestWithJSON(t, "POST", "/api/v1/user/avatar", &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusInternalServerError) } @@ -67,6 +70,7 @@ func TestAPIDeleteUserAvatar(t *testing.T) { session := loginUser(t, normalUsername) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) - req := NewRequest(t, "DELETE", "/api/v1/user/avatar?token="+token) + req := NewRequest(t, "DELETE", "/api/v1/user/avatar"). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) } diff --git a/tests/integration/api_user_email_test.go b/tests/integration/api_user_email_test.go index 9fff42af42253..6eeb547444550 100644 --- a/tests/integration/api_user_email_test.go +++ b/tests/integration/api_user_email_test.go @@ -21,7 +21,8 @@ func TestAPIListEmails(t *testing.T) { session := loginUser(t, normalUsername) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) - req := NewRequest(t, "GET", "/api/v1/user/emails?token="+token) + req := NewRequest(t, "GET", "/api/v1/user/emails"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var emails []*api.Email @@ -52,13 +53,15 @@ func TestAPIAddEmail(t *testing.T) { Emails: []string{"user101@example.com"}, } - req := NewRequestWithJSON(t, "POST", "/api/v1/user/emails?token="+token, &opts) + req := NewRequestWithJSON(t, "POST", "/api/v1/user/emails", &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) opts = api.CreateEmailOption{ Emails: []string{"user2-3@example.com"}, } - req = NewRequestWithJSON(t, "POST", "/api/v1/user/emails?token="+token, &opts) + req = NewRequestWithJSON(t, "POST", "/api/v1/user/emails", &opts). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var emails []*api.Email @@ -74,7 +77,8 @@ func TestAPIAddEmail(t *testing.T) { opts = api.CreateEmailOption{ Emails: []string{"notAEmail"}, } - req = NewRequestWithJSON(t, "POST", "/api/v1/user/emails?token="+token, &opts) + req = NewRequestWithJSON(t, "POST", "/api/v1/user/emails", &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusUnprocessableEntity) } @@ -88,16 +92,19 @@ func TestAPIDeleteEmail(t *testing.T) { opts := api.DeleteEmailOption{ Emails: []string{"user2-3@example.com"}, } - req := NewRequestWithJSON(t, "DELETE", "/api/v1/user/emails?token="+token, &opts) + req := NewRequestWithJSON(t, "DELETE", "/api/v1/user/emails", &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) opts = api.DeleteEmailOption{ Emails: []string{"user2-2@example.com"}, } - req = NewRequestWithJSON(t, "DELETE", "/api/v1/user/emails?token="+token, &opts) + req = NewRequestWithJSON(t, "DELETE", "/api/v1/user/emails", &opts). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "GET", "/api/v1/user/emails?token="+token) + req = NewRequest(t, "GET", "/api/v1/user/emails"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var emails []*api.Email diff --git a/tests/integration/api_user_follow_test.go b/tests/integration/api_user_follow_test.go index 62717af90e2ae..1762732c10e6d 100644 --- a/tests/integration/api_user_follow_test.go +++ b/tests/integration/api_user_follow_test.go @@ -30,14 +30,16 @@ func TestAPIFollow(t *testing.T) { t.Run("Follow", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/following/%s?token=%s", user1, token2)) + req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/following/%s", user1)). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) }) t.Run("ListFollowing", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/following?token=%s", user2, token2)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/following", user2)). + AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusOK) var users []api.User @@ -49,7 +51,8 @@ func TestAPIFollow(t *testing.T) { t.Run("ListMyFollowing", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/following?token=%s", token2)) + req := NewRequest(t, "GET", "/api/v1/user/following"). + AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusOK) var users []api.User @@ -61,7 +64,8 @@ func TestAPIFollow(t *testing.T) { t.Run("ListFollowers", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/followers?token=%s", user1, token1)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/followers", user1)). + AddTokenAuth(token1) resp := MakeRequest(t, req, http.StatusOK) var users []api.User @@ -73,7 +77,8 @@ func TestAPIFollow(t *testing.T) { t.Run("ListMyFollowers", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/followers?token=%s", token1)) + req := NewRequest(t, "GET", "/api/v1/user/followers"). + AddTokenAuth(token1) resp := MakeRequest(t, req, http.StatusOK) var users []api.User @@ -85,27 +90,32 @@ func TestAPIFollow(t *testing.T) { t.Run("CheckFollowing", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/following/%s?token=%s", user2, user1, token2)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/following/%s", user2, user1)). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/following/%s?token=%s", user1, user2, token2)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/following/%s", user1, user2)). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusNotFound) }) t.Run("CheckMyFollowing", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/following/%s?token=%s", user1, token2)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/following/%s", user1)). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/following/%s?token=%s", user2, token1)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/following/%s", user2)). + AddTokenAuth(token1) MakeRequest(t, req, http.StatusNotFound) }) t.Run("Unfollow", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/following/%s?token=%s", user1, token2)) + req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/following/%s", user1)). + AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) }) } diff --git a/tests/integration/api_user_heatmap_test.go b/tests/integration/api_user_heatmap_test.go index 5a7e58a02d601..a49bdd0c25222 100644 --- a/tests/integration/api_user_heatmap_test.go +++ b/tests/integration/api_user_heatmap_test.go @@ -27,8 +27,8 @@ func TestUserHeatmap(t *testing.T) { timeutil.Set(fakeNow) defer timeutil.Unset() - urlStr := fmt.Sprintf("/api/v1/users/%s/heatmap?token=%s", normalUsername, token) - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/heatmap", normalUsername)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var heatmap []*activities_model.UserHeatmapData DecodeJSON(t, resp, &heatmap) diff --git a/tests/integration/api_user_info_test.go b/tests/integration/api_user_info_test.go index cf42b50a4d58c..89f726685977e 100644 --- a/tests/integration/api_user_info_test.go +++ b/tests/integration/api_user_info_test.go @@ -31,7 +31,8 @@ func TestAPIUserInfo(t *testing.T) { t.Run("GetInfo", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s?token=%s", user2, token)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s", user2)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var u api.User @@ -48,7 +49,8 @@ func TestAPIUserInfo(t *testing.T) { assert.Equal(t, org3.GetPlaceholderEmail(), u.Email) // Test if the correct Mail is returned if a User is logged in - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s?token=%s", org3.Name, token)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s", org3.Name)). + AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &u) assert.Equal(t, org3.GetEmail(), u.Email) @@ -57,7 +59,8 @@ func TestAPIUserInfo(t *testing.T) { t.Run("GetAuthenticatedUser", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user?token=%s", token)) + req := NewRequest(t, "GET", "/api/v1/user"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var u api.User diff --git a/tests/integration/api_user_org_perm_test.go b/tests/integration/api_user_org_perm_test.go index c61004fab4494..85bb1db1709df 100644 --- a/tests/integration/api_user_org_perm_test.go +++ b/tests/integration/api_user_org_perm_test.go @@ -35,7 +35,8 @@ func sampleTest(t *testing.T, auoptc apiUserOrgPermTestCase) { session := loginUser(t, auoptc.LoginUser) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadOrganization, auth_model.AccessTokenScopeReadUser) - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/orgs/%s/permissions?token=%s", auoptc.User, auoptc.Organization, token)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/orgs/%s/permissions", auoptc.User, auoptc.Organization)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiOP api.OrganizationPermissions @@ -128,7 +129,8 @@ func TestUnknowUser(t *testing.T) { session := loginUser(t, "user1") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser, auth_model.AccessTokenScopeReadOrganization) - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/unknow/orgs/org25/permissions?token=%s", token)) + req := NewRequest(t, "GET", "/api/v1/users/unknow/orgs/org25/permissions"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusNotFound) var apiError api.APIError @@ -142,7 +144,8 @@ func TestUnknowOrganization(t *testing.T) { session := loginUser(t, "user1") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser, auth_model.AccessTokenScopeReadOrganization) - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/user1/orgs/unknow/permissions?token=%s", token)) + req := NewRequest(t, "GET", "/api/v1/users/user1/orgs/unknow/permissions"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusNotFound) var apiError api.APIError DecodeJSON(t, resp, &apiError) diff --git a/tests/integration/api_user_orgs_test.go b/tests/integration/api_user_orgs_test.go index 51830961aca48..b6b4b6f2b2d2e 100644 --- a/tests/integration/api_user_orgs_test.go +++ b/tests/integration/api_user_orgs_test.go @@ -74,8 +74,8 @@ func getUserOrgs(t *testing.T, userDoer, userCheck string) (orgs []*api.Organiza if len(userDoer) != 0 { token = getUserToken(t, userDoer, auth_model.AccessTokenScopeReadOrganization, auth_model.AccessTokenScopeReadUser) } - urlStr := fmt.Sprintf("/api/v1/users/%s/orgs?token=%s", userCheck, token) - req := NewRequest(t, "GET", urlStr) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/orgs", userCheck)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &orgs) return orgs @@ -95,7 +95,8 @@ func TestMyOrgs(t *testing.T) { normalUsername := "user2" token := getUserToken(t, normalUsername, auth_model.AccessTokenScopeReadOrganization, auth_model.AccessTokenScopeReadUser) - req = NewRequest(t, "GET", "/api/v1/user/orgs?token="+token) + req = NewRequest(t, "GET", "/api/v1/user/orgs"). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var orgs []*api.Organization DecodeJSON(t, resp, &orgs) diff --git a/tests/integration/api_user_search_test.go b/tests/integration/api_user_search_test.go index ddfeb25234b4d..f776b35325768 100644 --- a/tests/integration/api_user_search_test.go +++ b/tests/integration/api_user_search_test.go @@ -27,7 +27,8 @@ func TestAPIUserSearchLoggedIn(t *testing.T) { session := loginUser(t, adminUsername) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) query := "user2" - req := NewRequestf(t, "GET", "/api/v1/users/search?token=%s&q=%s", token, query) + req := NewRequestf(t, "GET", "/api/v1/users/search?q=%s", query). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var results SearchResults @@ -84,8 +85,8 @@ func TestAPIUserSearchAdminLoggedInUserHidden(t *testing.T) { session := loginUser(t, adminUsername) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) query := "user31" - req := NewRequestf(t, "GET", "/api/v1/users/search?token=%s&q=%s", token, query) - req.SetBasicAuth(token, "x-oauth-basic") + req := NewRequestf(t, "GET", "/api/v1/users/search?q=%s", query). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var results SearchResults diff --git a/tests/integration/api_user_secrets_test.go b/tests/integration/api_user_secrets_test.go index 5909f4b831541..56bf30e804412 100644 --- a/tests/integration/api_user_secrets_test.go +++ b/tests/integration/api_user_secrets_test.go @@ -55,44 +55,47 @@ func TestAPIUserSecrets(t *testing.T) { } for _, c := range cases { - req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/user/actions/secrets/%s?token=%s", c.Name, token), api.CreateOrUpdateSecretOption{ + req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/user/actions/secrets/%s", c.Name), api.CreateOrUpdateSecretOption{ Data: "data", - }) + }).AddTokenAuth(token) MakeRequest(t, req, c.ExpectedStatus) } }) t.Run("Update", func(t *testing.T) { name := "update_secret" - url := fmt.Sprintf("/api/v1/user/actions/secrets/%s?token=%s", name, token) + url := fmt.Sprintf("/api/v1/user/actions/secrets/%s", name) req := NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{ Data: "initial", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) req = NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{ Data: "changed", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) }) t.Run("Delete", func(t *testing.T) { name := "delete_secret" - url := fmt.Sprintf("/api/v1/user/actions/secrets/%s?token=%s", name, token) + url := fmt.Sprintf("/api/v1/user/actions/secrets/%s", name) req := NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{ Data: "initial", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) - req = NewRequest(t, "DELETE", url) + req = NewRequest(t, "DELETE", url). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "DELETE", url) + req = NewRequest(t, "DELETE", url). + AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/actions/secrets/000?token=%s", token)) + req = NewRequest(t, "DELETE", "/api/v1/user/actions/secrets/000"). + AddTokenAuth(token) MakeRequest(t, req, http.StatusBadRequest) }) } diff --git a/tests/integration/api_user_star_test.go b/tests/integration/api_user_star_test.go index 15a555d17d550..50423c80e7a2b 100644 --- a/tests/integration/api_user_star_test.go +++ b/tests/integration/api_user_star_test.go @@ -28,14 +28,16 @@ func TestAPIStar(t *testing.T) { t.Run("Star", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo, tokenWithUserScope)) + req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + AddTokenAuth(tokenWithUserScope) MakeRequest(t, req, http.StatusNoContent) }) t.Run("GetStarredRepos", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/starred?token=%s", user, token)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/starred", user)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "1", resp.Header().Get("X-Total-Count")) @@ -49,7 +51,8 @@ func TestAPIStar(t *testing.T) { t.Run("GetMyStarredRepos", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred?token=%s", tokenWithUserScope)) + req := NewRequest(t, "GET", "/api/v1/user/starred"). + AddTokenAuth(tokenWithUserScope) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "1", resp.Header().Get("X-Total-Count")) @@ -63,17 +66,20 @@ func TestAPIStar(t *testing.T) { t.Run("IsStarring", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo, tokenWithUserScope)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + AddTokenAuth(tokenWithUserScope) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo+"notexisting", tokenWithUserScope)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s", repo+"notexisting")). + AddTokenAuth(tokenWithUserScope) MakeRequest(t, req, http.StatusNotFound) }) t.Run("Unstar", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/starred/%s?token=%s", repo, tokenWithUserScope)) + req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + AddTokenAuth(tokenWithUserScope) MakeRequest(t, req, http.StatusNoContent) }) } diff --git a/tests/integration/api_user_watch_test.go b/tests/integration/api_user_watch_test.go index c07fd288d109c..20528959e8c52 100644 --- a/tests/integration/api_user_watch_test.go +++ b/tests/integration/api_user_watch_test.go @@ -28,14 +28,16 @@ func TestAPIWatch(t *testing.T) { t.Run("Watch", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/subscription?token=%s", repo, tokenWithRepoScope)) + req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/subscription", repo)). + AddTokenAuth(tokenWithRepoScope) MakeRequest(t, req, http.StatusOK) }) t.Run("GetWatchedRepos", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/subscriptions?token=%s", user, token)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/subscriptions", user)). + AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "1", resp.Header().Get("X-Total-Count")) @@ -49,7 +51,8 @@ func TestAPIWatch(t *testing.T) { t.Run("GetMyWatchedRepos", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/subscriptions?token=%s", tokenWithRepoScope)) + req := NewRequest(t, "GET", "/api/v1/user/subscriptions"). + AddTokenAuth(tokenWithRepoScope) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "1", resp.Header().Get("X-Total-Count")) @@ -63,17 +66,20 @@ func TestAPIWatch(t *testing.T) { t.Run("IsWatching", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/subscription?token=%s", repo, tokenWithRepoScope)) + req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/subscription", repo)). + AddTokenAuth(tokenWithRepoScope) MakeRequest(t, req, http.StatusOK) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/subscription?token=%s", repo+"notexisting", tokenWithRepoScope)) + req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/subscription", repo+"notexisting")). + AddTokenAuth(tokenWithRepoScope) MakeRequest(t, req, http.StatusNotFound) }) t.Run("Unwatch", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/subscription?token=%s", repo, tokenWithRepoScope)) + req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/repos/%s/subscription", repo)). + AddTokenAuth(tokenWithRepoScope) MakeRequest(t, req, http.StatusNoContent) }) } diff --git a/tests/integration/api_wiki_test.go b/tests/integration/api_wiki_test.go index f598982555b3a..05d90fc4e371d 100644 --- a/tests/integration/api_wiki_test.go +++ b/tests/integration/api_wiki_test.go @@ -182,13 +182,13 @@ func TestAPINewWikiPage(t *testing.T) { session := loginUser(t, username) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/new?token=%s", username, "repo1", token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/new", username, "repo1") req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateWikiPageOptions{ Title: title, ContentBase64: base64.StdEncoding.EncodeToString([]byte("Wiki page content for API unit tests")), Message: "", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) } } @@ -199,13 +199,13 @@ func TestAPIEditWikiPage(t *testing.T) { session := loginUser(t, username) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/page/Page-With-Spaced-Name?token=%s", username, "repo1", token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/wiki/page/Page-With-Spaced-Name", username, "repo1") req := NewRequestWithJSON(t, "PATCH", urlStr, &api.CreateWikiPageOptions{ Title: "edited title", ContentBase64: base64.StdEncoding.EncodeToString([]byte("Edited wiki page content for API unit tests")), Message: "", - }) + }).AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) } diff --git a/tests/integration/cors_test.go b/tests/integration/cors_test.go index e4151d1c32e75..83d200402c86b 100644 --- a/tests/integration/cors_test.go +++ b/tests/integration/cors_test.go @@ -14,7 +14,7 @@ import ( func TestCORSNotSet(t *testing.T) { defer tests.PrepareTestEnv(t)() - req := NewRequestf(t, "GET", "/api/v1/version") + req := NewRequest(t, "GET", "/api/v1/version") session := loginUser(t, "user2") resp := session.MakeRequest(t, req, http.StatusOK) assert.Equal(t, resp.Code, http.StatusOK) diff --git a/tests/integration/empty_repo_test.go b/tests/integration/empty_repo_test.go index 78453f28a585b..8842de5f6f557 100644 --- a/tests/integration/empty_repo_test.go +++ b/tests/integration/empty_repo_test.go @@ -6,7 +6,6 @@ package integration import ( "bytes" "encoding/base64" - "fmt" "io" "mime/multipart" "net/http" @@ -119,14 +118,13 @@ func TestEmptyRepoAddFileByAPI(t *testing.T) { session := loginUser(t, "user30") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - url := fmt.Sprintf("/api/v1/repos/user30/empty/contents/new-file.txt?token=%s", token) - req := NewRequestWithJSON(t, "POST", url, &api.CreateFileOptions{ + req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user30/empty/contents/new-file.txt", &api.CreateFileOptions{ FileOptions: api.FileOptions{ NewBranchName: "new_branch", Message: "init", }, ContentBase64: base64.StdEncoding.EncodeToString([]byte("newly-added-api-file")), - }) + }).AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusCreated) var fileResponse api.FileResponse @@ -138,7 +136,8 @@ func TestEmptyRepoAddFileByAPI(t *testing.T) { resp = session.MakeRequest(t, req, http.StatusOK) assert.Contains(t, resp.Body.String(), "newly-added-api-file") - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/user30/empty?token=%s", token)) + req = NewRequest(t, "GET", "/api/v1/repos/user30/empty"). + AddTokenAuth(token) resp = session.MakeRequest(t, req, http.StatusOK) var apiRepo api.Repository DecodeJSON(t, resp, &apiRepo) diff --git a/tests/integration/eventsource_test.go b/tests/integration/eventsource_test.go index 734f4a6a0a347..2ef4218977509 100644 --- a/tests/integration/eventsource_test.go +++ b/tests/integration/eventsource_test.go @@ -65,17 +65,20 @@ func TestEventSourceManagerRun(t *testing.T) { var apiNL []api.NotificationThread // -- mark notifications as read -- - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?status-types=unread&token=%s", token)) + req := NewRequest(t, "GET", "/api/v1/notifications?status-types=unread"). + AddTokenAuth(token) resp := session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) assert.Len(t, apiNL, 2) lastReadAt := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801 <- only Notification 4 is in this filter ... - req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s&token=%s", user2.Name, repo1.Name, lastReadAt, token)) + req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/%s/notifications?last_read_at=%s", user2.Name, repo1.Name, lastReadAt)). + AddTokenAuth(token) session.MakeRequest(t, req, http.StatusResetContent) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?token=%s&status-types=unread", token)) + req = NewRequest(t, "GET", "/api/v1/notifications?status-types=unread"). + AddTokenAuth(token) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiNL) assert.Len(t, apiNL, 1) diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go index 8534b0393b9da..1127de1afcdd4 100644 --- a/tests/integration/integration_test.go +++ b/tests/integration/integration_test.go @@ -163,14 +163,15 @@ func (s *TestSession) GetCookie(name string) *http.Cookie { return nil } -func (s *TestSession) MakeRequest(t testing.TB, req *http.Request, expectedStatus int) *httptest.ResponseRecorder { +func (s *TestSession) MakeRequest(t testing.TB, rw *RequestWrapper, expectedStatus int) *httptest.ResponseRecorder { t.Helper() + req := rw.Request baseURL, err := url.Parse(setting.AppURL) assert.NoError(t, err) for _, c := range s.jar.Cookies(baseURL) { req.AddCookie(c) } - resp := MakeRequest(t, req, expectedStatus) + resp := MakeRequest(t, rw, expectedStatus) ch := http.Header{} ch.Add("Cookie", strings.Join(resp.Header()["Set-Cookie"], ";")) @@ -180,14 +181,15 @@ func (s *TestSession) MakeRequest(t testing.TB, req *http.Request, expectedStatu return resp } -func (s *TestSession) MakeRequestNilResponseRecorder(t testing.TB, req *http.Request, expectedStatus int) *NilResponseRecorder { +func (s *TestSession) MakeRequestNilResponseRecorder(t testing.TB, rw *RequestWrapper, expectedStatus int) *NilResponseRecorder { t.Helper() + req := rw.Request baseURL, err := url.Parse(setting.AppURL) assert.NoError(t, err) for _, c := range s.jar.Cookies(baseURL) { req.AddCookie(c) } - resp := MakeRequestNilResponseRecorder(t, req, expectedStatus) + resp := MakeRequestNilResponseRecorder(t, rw, expectedStatus) ch := http.Header{} ch.Add("Cookie", strings.Join(resp.Header()["Set-Cookie"], ";")) @@ -197,14 +199,15 @@ func (s *TestSession) MakeRequestNilResponseRecorder(t testing.TB, req *http.Req return resp } -func (s *TestSession) MakeRequestNilResponseHashSumRecorder(t testing.TB, req *http.Request, expectedStatus int) *NilResponseHashSumRecorder { +func (s *TestSession) MakeRequestNilResponseHashSumRecorder(t testing.TB, rw *RequestWrapper, expectedStatus int) *NilResponseHashSumRecorder { t.Helper() + req := rw.Request baseURL, err := url.Parse(setting.AppURL) assert.NoError(t, err) for _, c := range s.jar.Cookies(baseURL) { req.AddCookie(c) } - resp := MakeRequestNilResponseHashSumRecorder(t, req, expectedStatus) + resp := MakeRequestNilResponseHashSumRecorder(t, rw, expectedStatus) ch := http.Header{} ch.Add("Cookie", strings.Join(resp.Header()["Set-Cookie"], ";")) @@ -314,17 +317,42 @@ func getTokenForLoggedInUser(t testing.TB, session *TestSession, scopes ...auth. return token } -func NewRequest(t testing.TB, method, urlStr string) *http.Request { +type RequestWrapper struct { + *http.Request +} + +func (req *RequestWrapper) AddBasicAuth(username string) *RequestWrapper { + req.Request.SetBasicAuth(username, userPassword) + return req +} + +func (req *RequestWrapper) AddTokenAuth(token string) *RequestWrapper { + if token == "" { + return req + } + if !strings.HasPrefix(token, "Bearer ") { + token = "Bearer " + token + } + req.Request.Header.Set("Authorization", token) + return req +} + +func (req *RequestWrapper) SetHeader(name, value string) *RequestWrapper { + req.Request.Header.Set(name, value) + return req +} + +func NewRequest(t testing.TB, method, urlStr string) *RequestWrapper { t.Helper() return NewRequestWithBody(t, method, urlStr, nil) } -func NewRequestf(t testing.TB, method, urlFormat string, args ...any) *http.Request { +func NewRequestf(t testing.TB, method, urlFormat string, args ...any) *RequestWrapper { t.Helper() return NewRequest(t, method, fmt.Sprintf(urlFormat, args...)) } -func NewRequestWithValues(t testing.TB, method, urlStr string, values map[string]string) *http.Request { +func NewRequestWithValues(t testing.TB, method, urlStr string, values map[string]string) *RequestWrapper { t.Helper() urlValues := url.Values{} for key, value := range values { @@ -333,43 +361,38 @@ func NewRequestWithValues(t testing.TB, method, urlStr string, values map[string return NewRequestWithURLValues(t, method, urlStr, urlValues) } -func NewRequestWithURLValues(t testing.TB, method, urlStr string, urlValues url.Values) *http.Request { +func NewRequestWithURLValues(t testing.TB, method, urlStr string, urlValues url.Values) *RequestWrapper { t.Helper() - req := NewRequestWithBody(t, method, urlStr, bytes.NewBufferString(urlValues.Encode())) - req.Header.Add("Content-Type", "application/x-www-form-urlencoded") - return req + return NewRequestWithBody(t, method, urlStr, bytes.NewBufferString(urlValues.Encode())). + SetHeader("Content-Type", "application/x-www-form-urlencoded") } -func NewRequestWithJSON(t testing.TB, method, urlStr string, v any) *http.Request { +func NewRequestWithJSON(t testing.TB, method, urlStr string, v any) *RequestWrapper { t.Helper() jsonBytes, err := json.Marshal(v) assert.NoError(t, err) - req := NewRequestWithBody(t, method, urlStr, bytes.NewBuffer(jsonBytes)) - req.Header.Add("Content-Type", "application/json") - return req + return NewRequestWithBody(t, method, urlStr, bytes.NewBuffer(jsonBytes)). + SetHeader("Content-Type", "application/json") } -func NewRequestWithBody(t testing.TB, method, urlStr string, body io.Reader) *http.Request { +func NewRequestWithBody(t testing.TB, method, urlStr string, body io.Reader) *RequestWrapper { t.Helper() if !strings.HasPrefix(urlStr, "http") && !strings.HasPrefix(urlStr, "/") { urlStr = "/" + urlStr } - request, err := http.NewRequest(method, urlStr, body) + req, err := http.NewRequest(method, urlStr, body) assert.NoError(t, err) - request.RequestURI = urlStr - return request -} + req.RequestURI = urlStr -func AddBasicAuthHeader(request *http.Request, username string) *http.Request { - request.SetBasicAuth(username, userPassword) - return request + return &RequestWrapper{req} } const NoExpectedStatus = -1 -func MakeRequest(t testing.TB, req *http.Request, expectedStatus int) *httptest.ResponseRecorder { +func MakeRequest(t testing.TB, rw *RequestWrapper, expectedStatus int) *httptest.ResponseRecorder { t.Helper() + req := rw.Request recorder := httptest.NewRecorder() if req.RemoteAddr == "" { req.RemoteAddr = "test-mock:12345" @@ -383,8 +406,9 @@ func MakeRequest(t testing.TB, req *http.Request, expectedStatus int) *httptest. return recorder } -func MakeRequestNilResponseRecorder(t testing.TB, req *http.Request, expectedStatus int) *NilResponseRecorder { +func MakeRequestNilResponseRecorder(t testing.TB, rw *RequestWrapper, expectedStatus int) *NilResponseRecorder { t.Helper() + req := rw.Request recorder := NewNilResponseRecorder() testWebRoutes.ServeHTTP(recorder, req) if expectedStatus != NoExpectedStatus { @@ -396,8 +420,9 @@ func MakeRequestNilResponseRecorder(t testing.TB, req *http.Request, expectedSta return recorder } -func MakeRequestNilResponseHashSumRecorder(t testing.TB, req *http.Request, expectedStatus int) *NilResponseHashSumRecorder { +func MakeRequestNilResponseHashSumRecorder(t testing.TB, rw *RequestWrapper, expectedStatus int) *NilResponseHashSumRecorder { t.Helper() + req := rw.Request recorder := NewNilResponseHashSumRecorder() testWebRoutes.ServeHTTP(recorder, req) if expectedStatus != NoExpectedStatus { diff --git a/tests/integration/org_test.go b/tests/integration/org_test.go index aa01678ea9474..94c4e197271c5 100644 --- a/tests/integration/org_test.go +++ b/tests/integration/org_test.go @@ -169,8 +169,8 @@ func TestOrgRestrictedUser(t *testing.T) { Units: []string{"repo.code"}, } - req = NewRequestWithJSON(t, "POST", - fmt.Sprintf("/api/v1/orgs/%s/teams?token=%s", orgName, token), teamToCreate) + req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/orgs/%s/teams", orgName), teamToCreate). + AddTokenAuth(token) var apiTeam api.Team @@ -183,8 +183,8 @@ func TestOrgRestrictedUser(t *testing.T) { // teamID := apiTeam.ID // Now we need to add the restricted user to the team - req = NewRequest(t, "PUT", - fmt.Sprintf("/api/v1/teams/%d/members/%s?token=%s", apiTeam.ID, restrictedUser, token)) + req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/teams/%d/members/%s", apiTeam.ID, restrictedUser)). + AddTokenAuth(token) _ = adminSession.MakeRequest(t, req, http.StatusNoContent) // Now we need to check if the restrictedUser can access the repo diff --git a/tests/integration/privateactivity_test.go b/tests/integration/privateactivity_test.go index 2b9b814106c18..5362462f7df9f 100644 --- a/tests/integration/privateactivity_test.go +++ b/tests/integration/privateactivity_test.go @@ -35,11 +35,11 @@ func testPrivateActivityDoSomethingForActionEntries(t *testing.T) { session := loginUser(t, privateActivityTestUser) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteIssue) - urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues?state=all&token=%s", owner.Name, repoBefore.Name, token) + urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues?state=all", owner.Name, repoBefore.Name) req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateIssueOption{ Body: "test", Title: "test", - }) + }).AddTokenAuth(token) session.MakeRequest(t, req, http.StatusCreated) } @@ -127,7 +127,8 @@ func testPrivateActivityHelperHasHeatmapContentFromPublic(t *testing.T) bool { func testPrivateActivityHelperHasHeatmapContentFromSession(t *testing.T, session *TestSession) bool { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadUser) - req := NewRequestf(t, "GET", "/api/v1/users/%s/heatmap?token=%s", privateActivityTestUser, token) + req := NewRequestf(t, "GET", "/api/v1/users/%s/heatmap", privateActivityTestUser). + AddTokenAuth(token) resp := session.MakeRequest(t, req, http.StatusOK) var items []*activities_model.UserHeatmapData diff --git a/tests/integration/pull_merge_test.go b/tests/integration/pull_merge_test.go index a4cc3e76fe94a..d17bf4afda114 100644 --- a/tests/integration/pull_merge_test.go +++ b/tests/integration/pull_merge_test.go @@ -218,11 +218,11 @@ func TestCantMergeConflict(t *testing.T) { // Use API to create a conflicting pr token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", "user1", "repo1", token), &api.CreatePullRequestOption{ + req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", "user1", "repo1"), &api.CreatePullRequestOption{ Head: "conflict", Base: "base", Title: "create a conflicting pr", - }) + }).AddTokenAuth(token) session.MakeRequest(t, req, http.StatusCreated) // Now this PR will be marked conflict - or at least a race will do - so drop down to pure code at this point... @@ -326,11 +326,11 @@ func TestCantMergeUnrelated(t *testing.T) { // Use API to create a conflicting pr token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls?token=%s", "user1", "repo1", token), &api.CreatePullRequestOption{ + req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", "user1", "repo1"), &api.CreatePullRequestOption{ Head: "unrelated", Base: "base", Title: "create an unrelated pr", - }) + }).AddTokenAuth(token) session.MakeRequest(t, req, http.StatusCreated) // Now this PR could be marked conflict - or at least a race may occur - so drop down to pure code at this point... diff --git a/tests/integration/pull_status_test.go b/tests/integration/pull_status_test.go index 01cb40d2cf5cb..26c99e6445974 100644 --- a/tests/integration/pull_status_test.go +++ b/tests/integration/pull_status_test.go @@ -77,7 +77,7 @@ func TestPullCreate_CommitStatus(t *testing.T) { Context: "testci", })) - req = NewRequestf(t, "GET", "/user1/repo1/pulls/1/commits") + req = NewRequest(t, "GET", "/user1/repo1/pulls/1/commits") resp = session.MakeRequest(t, req, http.StatusOK) doc = NewHTMLParser(t, resp.Body) @@ -98,9 +98,9 @@ func doAPICreateCommitStatus(ctx APITestContext, commitID string, data api.Creat req := NewRequestWithJSON( t, http.MethodPost, - fmt.Sprintf("/api/v1/repos/%s/%s/statuses/%s?token=%s", ctx.Username, ctx.Reponame, commitID, ctx.Token), + fmt.Sprintf("/api/v1/repos/%s/%s/statuses/%s", ctx.Username, ctx.Reponame, commitID), data, - ) + ).AddTokenAuth(ctx.Token) if ctx.ExpectedCode != 0 { ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) return diff --git a/tests/integration/pull_update_test.go b/tests/integration/pull_update_test.go index e4b2ae65bd61f..078253ffb0cb8 100644 --- a/tests/integration/pull_update_test.go +++ b/tests/integration/pull_update_test.go @@ -40,7 +40,8 @@ func TestAPIPullUpdate(t *testing.T) { session := loginUser(t, "user2") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/pulls/%d/update?token="+token, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index) + req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/pulls/%d/update", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index). + AddTokenAuth(token) session.MakeRequest(t, req, http.StatusOK) // Test GetDiverging after update @@ -68,7 +69,8 @@ func TestAPIPullUpdateByRebase(t *testing.T) { session := loginUser(t, "user2") token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/pulls/%d/update?style=rebase&token="+token, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index) + req := NewRequestf(t, "POST", "/api/v1/repos/%s/%s/pulls/%d/update?style=rebase", pr.BaseRepo.OwnerName, pr.BaseRepo.Name, pr.Issue.Index). + AddTokenAuth(token) session.MakeRequest(t, req, http.StatusOK) // Test GetDiverging after update diff --git a/tests/integration/repo_search_test.go b/tests/integration/repo_search_test.go index d113d1e57d03a..cf199e98c2895 100644 --- a/tests/integration/repo_search_test.go +++ b/tests/integration/repo_search_test.go @@ -51,7 +51,7 @@ func TestSearchRepo(t *testing.T) { } func testSearch(t *testing.T, url string, expected []string) { - req := NewRequestf(t, "GET", url) + req := NewRequest(t, "GET", url) resp := MakeRequest(t, req, http.StatusOK) filenames := resultFilenames(t, NewHTMLParser(t, resp.Body)) diff --git a/tests/integration/user_test.go b/tests/integration/user_test.go index ddde415960747..d8e4c64e85443 100644 --- a/tests/integration/user_test.go +++ b/tests/integration/user_test.go @@ -262,7 +262,7 @@ func TestListStopWatches(t *testing.T) { owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) session := loginUser(t, owner.Name) - req := NewRequestf(t, "GET", "/user/stopwatches") + req := NewRequest(t, "GET", "/user/stopwatches") resp := session.MakeRequest(t, req, http.StatusOK) var apiWatches []*api.StopWatch DecodeJSON(t, resp, &apiWatches)