You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

webhook.go 21KB

Move macaron to chi (#14293) Use [chi](https://github.com/go-chi/chi) instead of the forked [macaron](https://gitea.com/macaron/macaron). Since macaron and chi have conflicts with session share, this big PR becomes a have-to thing. According my previous idea, we can replace macaron step by step but I'm wrong. :( Below is a list of big changes on this PR. - [x] Define `context.ResponseWriter` interface with an implementation `context.Response`. - [x] Use chi instead of macaron, and also a customize `Route` to wrap chi so that the router usage is similar as before. - [x] Create different routers for `web`, `api`, `internal` and `install` so that the codes will be more clear and no magic . - [x] Use https://github.com/unrolled/render instead of macaron's internal render - [x] Use https://github.com/NYTimes/gziphandler instead of https://gitea.com/macaron/gzip - [x] Use https://gitea.com/go-chi/session which is a modified version of https://gitea.com/macaron/session and removed `nodb` support since it will not be maintained. **BREAK** - [x] Use https://gitea.com/go-chi/captcha which is a modified version of https://gitea.com/macaron/captcha - [x] Use https://gitea.com/go-chi/cache which is a modified version of https://gitea.com/macaron/cache - [x] Use https://gitea.com/go-chi/binding which is a modified version of https://gitea.com/macaron/binding - [x] Use https://github.com/go-chi/cors instead of https://gitea.com/macaron/cors - [x] Dropped https://gitea.com/macaron/i18n and make a new one in `code.gitea.io/gitea/modules/translation` - [x] Move validation form structs from `code.gitea.io/gitea/modules/auth` to `code.gitea.io/gitea/modules/forms` to avoid dependency cycle. - [x] Removed macaron log service because it's not need any more. **BREAK** - [x] All form structs have to be get by `web.GetForm(ctx)` in the route function but not as a function parameter on routes definition. - [x] Move Git HTTP protocol implementation to use routers directly. - [x] Fix the problem that chi routes don't support trailing slash but macaron did. - [x] `/api/v1/swagger` now will be redirect to `/api/swagger` but not render directly so that `APIContext` will not create a html render. Notices: - Chi router don't support request with trailing slash - Integration test `TestUserHeatmap` maybe mysql version related. It's failed on my macOS(mysql 5.7.29 installed via brew) but succeed on CI. Co-authored-by: 6543 <6543@obermui.de>
3 years ago
Move secrets and runners settings to actions settings (#24200) This PR moves the secrets and runners settings to actions settings on all settings(repo,org,user,admin) levels. After this PR, if [ENABLED](https://github.com/go-gitea/gitea/blob/5e7543fcf441afb30aba6188edac754ef32b9ac3/custom/conf/app.example.ini#L2604) inside `app.ini` under `[actions]` is set to `false`, the "Actions" tab (including runners management and secrets management) will not be shown. After, the settings under actions settings for each level: 1. Admin Level "Runners Management" <img width="1437" alt="Screen Shot 2023-04-26 at 14 34 20" src="https://user-images.githubusercontent.com/17645053/234489731-15822d21-38e1-4560-8bbe-69f122376abc.png"> 2. User Level "Secrets Management" <img width="1427" alt="Screen Shot 2023-04-26 at 14 34 30" src="https://user-images.githubusercontent.com/17645053/234489795-68c9c0cb-24f8-4f09-95c6-458ab914c313.png"> 3. Repo and Organization Levels "Runners Management" and "Secrets Management" Org: <img width="1437" alt="Screen Shot 2023-04-26 at 14 35 07" src="https://user-images.githubusercontent.com/17645053/234489996-f3af5ebb-d354-46ca-9087-a0b586845281.png"> <img width="1433" alt="Screen Shot 2023-04-26 at 14 35 14" src="https://user-images.githubusercontent.com/17645053/234490004-3abf8fed-81fd-4ce2-837a-935dade1793d.png"> Repo: <img width="1419" alt="Screen Shot 2023-04-26 at 14 34 50" src="https://user-images.githubusercontent.com/17645053/234489904-80c11038-4b58-462c-9d0b-8b7cf70bc2b3.png"> <img width="1430" alt="Screen Shot 2023-04-26 at 14 34 57" src="https://user-images.githubusercontent.com/17645053/234489918-4e8d1fe2-9bcd-4d8a-96c1-238a8088d92e.png"> It also finished these tasks : - [x] rename routers function "runners" to "actions", and refactor related file names - [x] check and modify part of the runners related functions to match their name - [x] Fix backend check caused by fmt check --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
1 year ago
Move secrets and runners settings to actions settings (#24200) This PR moves the secrets and runners settings to actions settings on all settings(repo,org,user,admin) levels. After this PR, if [ENABLED](https://github.com/go-gitea/gitea/blob/5e7543fcf441afb30aba6188edac754ef32b9ac3/custom/conf/app.example.ini#L2604) inside `app.ini` under `[actions]` is set to `false`, the "Actions" tab (including runners management and secrets management) will not be shown. After, the settings under actions settings for each level: 1. Admin Level "Runners Management" <img width="1437" alt="Screen Shot 2023-04-26 at 14 34 20" src="https://user-images.githubusercontent.com/17645053/234489731-15822d21-38e1-4560-8bbe-69f122376abc.png"> 2. User Level "Secrets Management" <img width="1427" alt="Screen Shot 2023-04-26 at 14 34 30" src="https://user-images.githubusercontent.com/17645053/234489795-68c9c0cb-24f8-4f09-95c6-458ab914c313.png"> 3. Repo and Organization Levels "Runners Management" and "Secrets Management" Org: <img width="1437" alt="Screen Shot 2023-04-26 at 14 35 07" src="https://user-images.githubusercontent.com/17645053/234489996-f3af5ebb-d354-46ca-9087-a0b586845281.png"> <img width="1433" alt="Screen Shot 2023-04-26 at 14 35 14" src="https://user-images.githubusercontent.com/17645053/234490004-3abf8fed-81fd-4ce2-837a-935dade1793d.png"> Repo: <img width="1419" alt="Screen Shot 2023-04-26 at 14 34 50" src="https://user-images.githubusercontent.com/17645053/234489904-80c11038-4b58-462c-9d0b-8b7cf70bc2b3.png"> <img width="1430" alt="Screen Shot 2023-04-26 at 14 34 57" src="https://user-images.githubusercontent.com/17645053/234489918-4e8d1fe2-9bcd-4d8a-96c1-238a8088d92e.png"> It also finished these tasks : - [x] rename routers function "runners" to "actions", and refactor related file names - [x] check and modify part of the runners related functions to match their name - [x] Fix backend check caused by fmt check --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
1 year ago
Move secrets and runners settings to actions settings (#24200) This PR moves the secrets and runners settings to actions settings on all settings(repo,org,user,admin) levels. After this PR, if [ENABLED](https://github.com/go-gitea/gitea/blob/5e7543fcf441afb30aba6188edac754ef32b9ac3/custom/conf/app.example.ini#L2604) inside `app.ini` under `[actions]` is set to `false`, the "Actions" tab (including runners management and secrets management) will not be shown. After, the settings under actions settings for each level: 1. Admin Level "Runners Management" <img width="1437" alt="Screen Shot 2023-04-26 at 14 34 20" src="https://user-images.githubusercontent.com/17645053/234489731-15822d21-38e1-4560-8bbe-69f122376abc.png"> 2. User Level "Secrets Management" <img width="1427" alt="Screen Shot 2023-04-26 at 14 34 30" src="https://user-images.githubusercontent.com/17645053/234489795-68c9c0cb-24f8-4f09-95c6-458ab914c313.png"> 3. Repo and Organization Levels "Runners Management" and "Secrets Management" Org: <img width="1437" alt="Screen Shot 2023-04-26 at 14 35 07" src="https://user-images.githubusercontent.com/17645053/234489996-f3af5ebb-d354-46ca-9087-a0b586845281.png"> <img width="1433" alt="Screen Shot 2023-04-26 at 14 35 14" src="https://user-images.githubusercontent.com/17645053/234490004-3abf8fed-81fd-4ce2-837a-935dade1793d.png"> Repo: <img width="1419" alt="Screen Shot 2023-04-26 at 14 34 50" src="https://user-images.githubusercontent.com/17645053/234489904-80c11038-4b58-462c-9d0b-8b7cf70bc2b3.png"> <img width="1430" alt="Screen Shot 2023-04-26 at 14 34 57" src="https://user-images.githubusercontent.com/17645053/234489918-4e8d1fe2-9bcd-4d8a-96c1-238a8088d92e.png"> It also finished these tasks : - [x] rename routers function "runners" to "actions", and refactor related file names - [x] check and modify part of the runners related functions to match their name - [x] Fix backend check caused by fmt check --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
1 year ago
Move secrets and runners settings to actions settings (#24200) This PR moves the secrets and runners settings to actions settings on all settings(repo,org,user,admin) levels. After this PR, if [ENABLED](https://github.com/go-gitea/gitea/blob/5e7543fcf441afb30aba6188edac754ef32b9ac3/custom/conf/app.example.ini#L2604) inside `app.ini` under `[actions]` is set to `false`, the "Actions" tab (including runners management and secrets management) will not be shown. After, the settings under actions settings for each level: 1. Admin Level "Runners Management" <img width="1437" alt="Screen Shot 2023-04-26 at 14 34 20" src="https://user-images.githubusercontent.com/17645053/234489731-15822d21-38e1-4560-8bbe-69f122376abc.png"> 2. User Level "Secrets Management" <img width="1427" alt="Screen Shot 2023-04-26 at 14 34 30" src="https://user-images.githubusercontent.com/17645053/234489795-68c9c0cb-24f8-4f09-95c6-458ab914c313.png"> 3. Repo and Organization Levels "Runners Management" and "Secrets Management" Org: <img width="1437" alt="Screen Shot 2023-04-26 at 14 35 07" src="https://user-images.githubusercontent.com/17645053/234489996-f3af5ebb-d354-46ca-9087-a0b586845281.png"> <img width="1433" alt="Screen Shot 2023-04-26 at 14 35 14" src="https://user-images.githubusercontent.com/17645053/234490004-3abf8fed-81fd-4ce2-837a-935dade1793d.png"> Repo: <img width="1419" alt="Screen Shot 2023-04-26 at 14 34 50" src="https://user-images.githubusercontent.com/17645053/234489904-80c11038-4b58-462c-9d0b-8b7cf70bc2b3.png"> <img width="1430" alt="Screen Shot 2023-04-26 at 14 34 57" src="https://user-images.githubusercontent.com/17645053/234489918-4e8d1fe2-9bcd-4d8a-96c1-238a8088d92e.png"> It also finished these tasks : - [x] rename routers function "runners" to "actions", and refactor related file names - [x] check and modify part of the runners related functions to match their name - [x] Fix backend check caused by fmt check --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
1 year ago
Add Webhook authorization header (#20926) _This is a different approach to #20267, I took the liberty of adapting some parts, see below_ ## Context In some cases, a weebhook endpoint requires some kind of authentication. The usual way is by sending a static `Authorization` header, with a given token. For instance: - Matrix expects a `Bearer <token>` (already implemented, by storing the header cleartext in the metadata - which is buggy on retry #19872) - TeamCity #18667 - Gitea instances #20267 - SourceHut https://man.sr.ht/graphql.md#authentication-strategies (this is my actual personal need :) ## Proposed solution Add a dedicated encrypt column to the webhook table (instead of storing it as meta as proposed in #20267), so that it gets available for all present and future hook types (especially the custom ones #19307). This would also solve the buggy matrix retry #19872. As a first step, I would recommend focusing on the backend logic and improve the frontend at a later stage. For now the UI is a simple `Authorization` field (which could be later customized with `Bearer` and `Basic` switches): ![2022-08-23-142911](https://user-images.githubusercontent.com/3864879/186162483-5b721504-eef5-4932-812e-eb96a68494cc.png) The header name is hard-coded, since I couldn't fine any usecase justifying otherwise. ## Questions - What do you think of this approach? @justusbunsi @Gusted @silverwind - ~~How are the migrations generated? Do I have to manually create a new file, or is there a command for that?~~ - ~~I started adding it to the API: should I complete it or should I drop it? (I don't know how much the API is actually used)~~ ## Done as well: - add a migration for the existing matrix webhooks and remove the `Authorization` logic there _Closes #19872_ Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: Gusted <williamzijl7@hotmail.com> Co-authored-by: delvh <dev.lh@web.de>
1 year ago
Add Webhook authorization header (#20926) _This is a different approach to #20267, I took the liberty of adapting some parts, see below_ ## Context In some cases, a weebhook endpoint requires some kind of authentication. The usual way is by sending a static `Authorization` header, with a given token. For instance: - Matrix expects a `Bearer <token>` (already implemented, by storing the header cleartext in the metadata - which is buggy on retry #19872) - TeamCity #18667 - Gitea instances #20267 - SourceHut https://man.sr.ht/graphql.md#authentication-strategies (this is my actual personal need :) ## Proposed solution Add a dedicated encrypt column to the webhook table (instead of storing it as meta as proposed in #20267), so that it gets available for all present and future hook types (especially the custom ones #19307). This would also solve the buggy matrix retry #19872. As a first step, I would recommend focusing on the backend logic and improve the frontend at a later stage. For now the UI is a simple `Authorization` field (which could be later customized with `Bearer` and `Basic` switches): ![2022-08-23-142911](https://user-images.githubusercontent.com/3864879/186162483-5b721504-eef5-4932-812e-eb96a68494cc.png) The header name is hard-coded, since I couldn't fine any usecase justifying otherwise. ## Questions - What do you think of this approach? @justusbunsi @Gusted @silverwind - ~~How are the migrations generated? Do I have to manually create a new file, or is there a command for that?~~ - ~~I started adding it to the API: should I complete it or should I drop it? (I don't know how much the API is actually used)~~ ## Done as well: - add a migration for the existing matrix webhooks and remove the `Authorization` logic there _Closes #19872_ Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: Gusted <williamzijl7@hotmail.com> Co-authored-by: delvh <dev.lh@web.de>
1 year ago
Move macaron to chi (#14293) Use [chi](https://github.com/go-chi/chi) instead of the forked [macaron](https://gitea.com/macaron/macaron). Since macaron and chi have conflicts with session share, this big PR becomes a have-to thing. According my previous idea, we can replace macaron step by step but I'm wrong. :( Below is a list of big changes on this PR. - [x] Define `context.ResponseWriter` interface with an implementation `context.Response`. - [x] Use chi instead of macaron, and also a customize `Route` to wrap chi so that the router usage is similar as before. - [x] Create different routers for `web`, `api`, `internal` and `install` so that the codes will be more clear and no magic . - [x] Use https://github.com/unrolled/render instead of macaron's internal render - [x] Use https://github.com/NYTimes/gziphandler instead of https://gitea.com/macaron/gzip - [x] Use https://gitea.com/go-chi/session which is a modified version of https://gitea.com/macaron/session and removed `nodb` support since it will not be maintained. **BREAK** - [x] Use https://gitea.com/go-chi/captcha which is a modified version of https://gitea.com/macaron/captcha - [x] Use https://gitea.com/go-chi/cache which is a modified version of https://gitea.com/macaron/cache - [x] Use https://gitea.com/go-chi/binding which is a modified version of https://gitea.com/macaron/binding - [x] Use https://github.com/go-chi/cors instead of https://gitea.com/macaron/cors - [x] Dropped https://gitea.com/macaron/i18n and make a new one in `code.gitea.io/gitea/modules/translation` - [x] Move validation form structs from `code.gitea.io/gitea/modules/auth` to `code.gitea.io/gitea/modules/forms` to avoid dependency cycle. - [x] Removed macaron log service because it's not need any more. **BREAK** - [x] All form structs have to be get by `web.GetForm(ctx)` in the route function but not as a function parameter on routes definition. - [x] Move Git HTTP protocol implementation to use routers directly. - [x] Fix the problem that chi routes don't support trailing slash but macaron did. - [x] `/api/v1/swagger` now will be redirect to `/api/swagger` but not render directly so that `APIContext` will not create a html render. Notices: - Chi router don't support request with trailing slash - Integration test `TestUserHeatmap` maybe mysql version related. It's failed on my macOS(mysql 5.7.29 installed via brew) but succeed on CI. Co-authored-by: 6543 <6543@obermui.de>
3 years ago
Move macaron to chi (#14293) Use [chi](https://github.com/go-chi/chi) instead of the forked [macaron](https://gitea.com/macaron/macaron). Since macaron and chi have conflicts with session share, this big PR becomes a have-to thing. According my previous idea, we can replace macaron step by step but I'm wrong. :( Below is a list of big changes on this PR. - [x] Define `context.ResponseWriter` interface with an implementation `context.Response`. - [x] Use chi instead of macaron, and also a customize `Route` to wrap chi so that the router usage is similar as before. - [x] Create different routers for `web`, `api`, `internal` and `install` so that the codes will be more clear and no magic . - [x] Use https://github.com/unrolled/render instead of macaron's internal render - [x] Use https://github.com/NYTimes/gziphandler instead of https://gitea.com/macaron/gzip - [x] Use https://gitea.com/go-chi/session which is a modified version of https://gitea.com/macaron/session and removed `nodb` support since it will not be maintained. **BREAK** - [x] Use https://gitea.com/go-chi/captcha which is a modified version of https://gitea.com/macaron/captcha - [x] Use https://gitea.com/go-chi/cache which is a modified version of https://gitea.com/macaron/cache - [x] Use https://gitea.com/go-chi/binding which is a modified version of https://gitea.com/macaron/binding - [x] Use https://github.com/go-chi/cors instead of https://gitea.com/macaron/cors - [x] Dropped https://gitea.com/macaron/i18n and make a new one in `code.gitea.io/gitea/modules/translation` - [x] Move validation form structs from `code.gitea.io/gitea/modules/auth` to `code.gitea.io/gitea/modules/forms` to avoid dependency cycle. - [x] Removed macaron log service because it's not need any more. **BREAK** - [x] All form structs have to be get by `web.GetForm(ctx)` in the route function but not as a function parameter on routes definition. - [x] Move Git HTTP protocol implementation to use routers directly. - [x] Fix the problem that chi routes don't support trailing slash but macaron did. - [x] `/api/v1/swagger` now will be redirect to `/api/swagger` but not render directly so that `APIContext` will not create a html render. Notices: - Chi router don't support request with trailing slash - Integration test `TestUserHeatmap` maybe mysql version related. It's failed on my macOS(mysql 5.7.29 installed via brew) but succeed on CI. Co-authored-by: 6543 <6543@obermui.de>
3 years ago
Move macaron to chi (#14293) Use [chi](https://github.com/go-chi/chi) instead of the forked [macaron](https://gitea.com/macaron/macaron). Since macaron and chi have conflicts with session share, this big PR becomes a have-to thing. According my previous idea, we can replace macaron step by step but I'm wrong. :( Below is a list of big changes on this PR. - [x] Define `context.ResponseWriter` interface with an implementation `context.Response`. - [x] Use chi instead of macaron, and also a customize `Route` to wrap chi so that the router usage is similar as before. - [x] Create different routers for `web`, `api`, `internal` and `install` so that the codes will be more clear and no magic . - [x] Use https://github.com/unrolled/render instead of macaron's internal render - [x] Use https://github.com/NYTimes/gziphandler instead of https://gitea.com/macaron/gzip - [x] Use https://gitea.com/go-chi/session which is a modified version of https://gitea.com/macaron/session and removed `nodb` support since it will not be maintained. **BREAK** - [x] Use https://gitea.com/go-chi/captcha which is a modified version of https://gitea.com/macaron/captcha - [x] Use https://gitea.com/go-chi/cache which is a modified version of https://gitea.com/macaron/cache - [x] Use https://gitea.com/go-chi/binding which is a modified version of https://gitea.com/macaron/binding - [x] Use https://github.com/go-chi/cors instead of https://gitea.com/macaron/cors - [x] Dropped https://gitea.com/macaron/i18n and make a new one in `code.gitea.io/gitea/modules/translation` - [x] Move validation form structs from `code.gitea.io/gitea/modules/auth` to `code.gitea.io/gitea/modules/forms` to avoid dependency cycle. - [x] Removed macaron log service because it's not need any more. **BREAK** - [x] All form structs have to be get by `web.GetForm(ctx)` in the route function but not as a function parameter on routes definition. - [x] Move Git HTTP protocol implementation to use routers directly. - [x] Fix the problem that chi routes don't support trailing slash but macaron did. - [x] `/api/v1/swagger` now will be redirect to `/api/swagger` but not render directly so that `APIContext` will not create a html render. Notices: - Chi router don't support request with trailing slash - Integration test `TestUserHeatmap` maybe mysql version related. It's failed on my macOS(mysql 5.7.29 installed via brew) but succeed on CI. Co-authored-by: 6543 <6543@obermui.de>
3 years ago
Move macaron to chi (#14293) Use [chi](https://github.com/go-chi/chi) instead of the forked [macaron](https://gitea.com/macaron/macaron). Since macaron and chi have conflicts with session share, this big PR becomes a have-to thing. According my previous idea, we can replace macaron step by step but I'm wrong. :( Below is a list of big changes on this PR. - [x] Define `context.ResponseWriter` interface with an implementation `context.Response`. - [x] Use chi instead of macaron, and also a customize `Route` to wrap chi so that the router usage is similar as before. - [x] Create different routers for `web`, `api`, `internal` and `install` so that the codes will be more clear and no magic . - [x] Use https://github.com/unrolled/render instead of macaron's internal render - [x] Use https://github.com/NYTimes/gziphandler instead of https://gitea.com/macaron/gzip - [x] Use https://gitea.com/go-chi/session which is a modified version of https://gitea.com/macaron/session and removed `nodb` support since it will not be maintained. **BREAK** - [x] Use https://gitea.com/go-chi/captcha which is a modified version of https://gitea.com/macaron/captcha - [x] Use https://gitea.com/go-chi/cache which is a modified version of https://gitea.com/macaron/cache - [x] Use https://gitea.com/go-chi/binding which is a modified version of https://gitea.com/macaron/binding - [x] Use https://github.com/go-chi/cors instead of https://gitea.com/macaron/cors - [x] Dropped https://gitea.com/macaron/i18n and make a new one in `code.gitea.io/gitea/modules/translation` - [x] Move validation form structs from `code.gitea.io/gitea/modules/auth` to `code.gitea.io/gitea/modules/forms` to avoid dependency cycle. - [x] Removed macaron log service because it's not need any more. **BREAK** - [x] All form structs have to be get by `web.GetForm(ctx)` in the route function but not as a function parameter on routes definition. - [x] Move Git HTTP protocol implementation to use routers directly. - [x] Fix the problem that chi routes don't support trailing slash but macaron did. - [x] `/api/v1/swagger` now will be redirect to `/api/swagger` but not render directly so that `APIContext` will not create a html render. Notices: - Chi router don't support request with trailing slash - Integration test `TestUserHeatmap` maybe mysql version related. It's failed on my macOS(mysql 5.7.29 installed via brew) but succeed on CI. Co-authored-by: 6543 <6543@obermui.de>
3 years ago
Move macaron to chi (#14293) Use [chi](https://github.com/go-chi/chi) instead of the forked [macaron](https://gitea.com/macaron/macaron). Since macaron and chi have conflicts with session share, this big PR becomes a have-to thing. According my previous idea, we can replace macaron step by step but I'm wrong. :( Below is a list of big changes on this PR. - [x] Define `context.ResponseWriter` interface with an implementation `context.Response`. - [x] Use chi instead of macaron, and also a customize `Route` to wrap chi so that the router usage is similar as before. - [x] Create different routers for `web`, `api`, `internal` and `install` so that the codes will be more clear and no magic . - [x] Use https://github.com/unrolled/render instead of macaron's internal render - [x] Use https://github.com/NYTimes/gziphandler instead of https://gitea.com/macaron/gzip - [x] Use https://gitea.com/go-chi/session which is a modified version of https://gitea.com/macaron/session and removed `nodb` support since it will not be maintained. **BREAK** - [x] Use https://gitea.com/go-chi/captcha which is a modified version of https://gitea.com/macaron/captcha - [x] Use https://gitea.com/go-chi/cache which is a modified version of https://gitea.com/macaron/cache - [x] Use https://gitea.com/go-chi/binding which is a modified version of https://gitea.com/macaron/binding - [x] Use https://github.com/go-chi/cors instead of https://gitea.com/macaron/cors - [x] Dropped https://gitea.com/macaron/i18n and make a new one in `code.gitea.io/gitea/modules/translation` - [x] Move validation form structs from `code.gitea.io/gitea/modules/auth` to `code.gitea.io/gitea/modules/forms` to avoid dependency cycle. - [x] Removed macaron log service because it's not need any more. **BREAK** - [x] All form structs have to be get by `web.GetForm(ctx)` in the route function but not as a function parameter on routes definition. - [x] Move Git HTTP protocol implementation to use routers directly. - [x] Fix the problem that chi routes don't support trailing slash but macaron did. - [x] `/api/v1/swagger` now will be redirect to `/api/swagger` but not render directly so that `APIContext` will not create a html render. Notices: - Chi router don't support request with trailing slash - Integration test `TestUserHeatmap` maybe mysql version related. It's failed on my macOS(mysql 5.7.29 installed via brew) but succeed on CI. Co-authored-by: 6543 <6543@obermui.de>
3 years ago
Move macaron to chi (#14293) Use [chi](https://github.com/go-chi/chi) instead of the forked [macaron](https://gitea.com/macaron/macaron). Since macaron and chi have conflicts with session share, this big PR becomes a have-to thing. According my previous idea, we can replace macaron step by step but I'm wrong. :( Below is a list of big changes on this PR. - [x] Define `context.ResponseWriter` interface with an implementation `context.Response`. - [x] Use chi instead of macaron, and also a customize `Route` to wrap chi so that the router usage is similar as before. - [x] Create different routers for `web`, `api`, `internal` and `install` so that the codes will be more clear and no magic . - [x] Use https://github.com/unrolled/render instead of macaron's internal render - [x] Use https://github.com/NYTimes/gziphandler instead of https://gitea.com/macaron/gzip - [x] Use https://gitea.com/go-chi/session which is a modified version of https://gitea.com/macaron/session and removed `nodb` support since it will not be maintained. **BREAK** - [x] Use https://gitea.com/go-chi/captcha which is a modified version of https://gitea.com/macaron/captcha - [x] Use https://gitea.com/go-chi/cache which is a modified version of https://gitea.com/macaron/cache - [x] Use https://gitea.com/go-chi/binding which is a modified version of https://gitea.com/macaron/binding - [x] Use https://github.com/go-chi/cors instead of https://gitea.com/macaron/cors - [x] Dropped https://gitea.com/macaron/i18n and make a new one in `code.gitea.io/gitea/modules/translation` - [x] Move validation form structs from `code.gitea.io/gitea/modules/auth` to `code.gitea.io/gitea/modules/forms` to avoid dependency cycle. - [x] Removed macaron log service because it's not need any more. **BREAK** - [x] All form structs have to be get by `web.GetForm(ctx)` in the route function but not as a function parameter on routes definition. - [x] Move Git HTTP protocol implementation to use routers directly. - [x] Fix the problem that chi routes don't support trailing slash but macaron did. - [x] `/api/v1/swagger` now will be redirect to `/api/swagger` but not render directly so that `APIContext` will not create a html render. Notices: - Chi router don't support request with trailing slash - Integration test `TestUserHeatmap` maybe mysql version related. It's failed on my macOS(mysql 5.7.29 installed via brew) but succeed on CI. Co-authored-by: 6543 <6543@obermui.de>
3 years ago
Move macaron to chi (#14293) Use [chi](https://github.com/go-chi/chi) instead of the forked [macaron](https://gitea.com/macaron/macaron). Since macaron and chi have conflicts with session share, this big PR becomes a have-to thing. According my previous idea, we can replace macaron step by step but I'm wrong. :( Below is a list of big changes on this PR. - [x] Define `context.ResponseWriter` interface with an implementation `context.Response`. - [x] Use chi instead of macaron, and also a customize `Route` to wrap chi so that the router usage is similar as before. - [x] Create different routers for `web`, `api`, `internal` and `install` so that the codes will be more clear and no magic . - [x] Use https://github.com/unrolled/render instead of macaron's internal render - [x] Use https://github.com/NYTimes/gziphandler instead of https://gitea.com/macaron/gzip - [x] Use https://gitea.com/go-chi/session which is a modified version of https://gitea.com/macaron/session and removed `nodb` support since it will not be maintained. **BREAK** - [x] Use https://gitea.com/go-chi/captcha which is a modified version of https://gitea.com/macaron/captcha - [x] Use https://gitea.com/go-chi/cache which is a modified version of https://gitea.com/macaron/cache - [x] Use https://gitea.com/go-chi/binding which is a modified version of https://gitea.com/macaron/binding - [x] Use https://github.com/go-chi/cors instead of https://gitea.com/macaron/cors - [x] Dropped https://gitea.com/macaron/i18n and make a new one in `code.gitea.io/gitea/modules/translation` - [x] Move validation form structs from `code.gitea.io/gitea/modules/auth` to `code.gitea.io/gitea/modules/forms` to avoid dependency cycle. - [x] Removed macaron log service because it's not need any more. **BREAK** - [x] All form structs have to be get by `web.GetForm(ctx)` in the route function but not as a function parameter on routes definition. - [x] Move Git HTTP protocol implementation to use routers directly. - [x] Fix the problem that chi routes don't support trailing slash but macaron did. - [x] `/api/v1/swagger` now will be redirect to `/api/swagger` but not render directly so that `APIContext` will not create a html render. Notices: - Chi router don't support request with trailing slash - Integration test `TestUserHeatmap` maybe mysql version related. It's failed on my macOS(mysql 5.7.29 installed via brew) but succeed on CI. Co-authored-by: 6543 <6543@obermui.de>
3 years ago
Add support for corporate WeChat webhooks (#15910) * 企业微信webhook * 企业微信webhook * 企业微信webhook * Update templates/admin/hook_new.tmpl Co-authored-by: a1012112796 <1012112796@qq.com> * Update services/webhook/wechatwork.go Co-authored-by: a1012112796 <1012112796@qq.com> * 修善wechatwork * 修善wechatwork * fix * Update locale_cs-CZ.ini fix * fix build * fix * fix build * make webhooks.zh-cn.md * delet unnecessary blank line * delet unnecessary blank line * 企业微信webhook * 企业微信webhook * 企业微信webhook * Update templates/admin/hook_new.tmpl Co-authored-by: a1012112796 <1012112796@qq.com> * Update services/webhook/wechatwork.go Co-authored-by: a1012112796 <1012112796@qq.com> * 修善wechatwork * 修善wechatwork * fix * fix build * fix * fix build * make webhooks.zh-cn.md * delet unnecessary blank line * delet unnecessary blank line * 企业微信webhook * 企业微信webhook * 企业微信webhook * 企业微信webhook * 企业微信webhook * fix * fix * 企业微信webhook * 企业微信webhook * 企业微信webhook * fix wechat * fix wechat * fix wechat * fix wechat * Fix invalid params and typo of email templates (#16394) Signed-off-by: Meano <meanocat@gmail.com> * Add LRU mem cache implementation (#16226) The current default memory cache implementation is unbounded in size and number of objects cached. This is hardly ideal. This PR proposes creating a TwoQueue LRU cache as the underlying cache for Gitea. The cache is limited by the number of objects stored in the cache (rather than size) for simplicity. The default number of objects is 50000 - which is perhaps too small as most of our objects cached are going to be much less than 1kB. It may be worth considering using a different LRU implementation that actively limits sizes or avoids GC - however, this is just a beginning implementation. Signed-off-by: Andrew Thornton <art27@cantab.net> * [skip ci] Updated translations via Crowdin * Replace `plugins/docker` with `techknowlogick/drone-docker`in ci (#16407) * plugins/docker -> techknowlogick/drone-docker * It is multi-arch * docs: rewrite email setup (#16404) * Add intro for both the docs page and mailer methods * Fix numbering level in SMTP section * Recommends implicit TLS Signed-off-by: Bagas Sanjaya <bagasdotme@gmail.com> * Validate Issue Index before querying DB (#16406) * Fix external renderer (#16401) * fix external renderer * use GBackground context as fallback * no fallback, return error Co-authored-by: Lauris BH <lauris@nix.lv> * Add checkbox to delete pull branch after successful merge (#16049) * Add checkbox to delete pull branch after successful merge * Omit DeleteBranchAfterMerge field in json * Log a warning instead of error when PR head branch deleted * Add DefaultDeleteBranchAfterMerge to PullRequestConfig * Add support for delete_branch_after_merge via API * Fix for API: the branch should be deleted from the HEAD repo If head and base repo are the same, reuse the already opened ctx.Repo.GitRepo * Don't delegate to CleanupBranch, only reuse branch deletion code CleanupBranch contains too much logic that has already been performed by the Merge * Reuse gitrepo in MergePullRequest Co-authored-by: Andrew Thornton <art27@cantab.net> * [skip ci] Updated translations via Crowdin * Detect encoding changes while parsing diff (#16330) * Detect encoding changes while parsing diff * Let branch/tag name be a valid ref to get CI status (#16400) * fix #16384# * refactor: move shared helper func to utils package * extend Tests * use ctx.Repo.GitRepo if not nil * fix * fix * 企业微信webhook * 企业微信webhook * 企业微信webhook * fix build * fix build * Apply suggestions from code review Co-authored-by: a1012112796 <1012112796@qq.com> Co-authored-by: myheavily <myheavily> Co-authored-by: zhaoxin <gitea@fake.local> Co-authored-by: Meano <Meano@foxmail.com> Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: GiteaBot <teabot@gitea.io> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Bagas Sanjaya <bagasdotme@gmail.com> Co-authored-by: Norwin <noerw@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: Jimmy Praet <jimmy.praet@telenet.be> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2 years ago
Add support for corporate WeChat webhooks (#15910) * 企业微信webhook * 企业微信webhook * 企业微信webhook * Update templates/admin/hook_new.tmpl Co-authored-by: a1012112796 <1012112796@qq.com> * Update services/webhook/wechatwork.go Co-authored-by: a1012112796 <1012112796@qq.com> * 修善wechatwork * 修善wechatwork * fix * Update locale_cs-CZ.ini fix * fix build * fix * fix build * make webhooks.zh-cn.md * delet unnecessary blank line * delet unnecessary blank line * 企业微信webhook * 企业微信webhook * 企业微信webhook * Update templates/admin/hook_new.tmpl Co-authored-by: a1012112796 <1012112796@qq.com> * Update services/webhook/wechatwork.go Co-authored-by: a1012112796 <1012112796@qq.com> * 修善wechatwork * 修善wechatwork * fix * fix build * fix * fix build * make webhooks.zh-cn.md * delet unnecessary blank line * delet unnecessary blank line * 企业微信webhook * 企业微信webhook * 企业微信webhook * 企业微信webhook * 企业微信webhook * fix * fix * 企业微信webhook * 企业微信webhook * 企业微信webhook * fix wechat * fix wechat * fix wechat * fix wechat * Fix invalid params and typo of email templates (#16394) Signed-off-by: Meano <meanocat@gmail.com> * Add LRU mem cache implementation (#16226) The current default memory cache implementation is unbounded in size and number of objects cached. This is hardly ideal. This PR proposes creating a TwoQueue LRU cache as the underlying cache for Gitea. The cache is limited by the number of objects stored in the cache (rather than size) for simplicity. The default number of objects is 50000 - which is perhaps too small as most of our objects cached are going to be much less than 1kB. It may be worth considering using a different LRU implementation that actively limits sizes or avoids GC - however, this is just a beginning implementation. Signed-off-by: Andrew Thornton <art27@cantab.net> * [skip ci] Updated translations via Crowdin * Replace `plugins/docker` with `techknowlogick/drone-docker`in ci (#16407) * plugins/docker -> techknowlogick/drone-docker * It is multi-arch * docs: rewrite email setup (#16404) * Add intro for both the docs page and mailer methods * Fix numbering level in SMTP section * Recommends implicit TLS Signed-off-by: Bagas Sanjaya <bagasdotme@gmail.com> * Validate Issue Index before querying DB (#16406) * Fix external renderer (#16401) * fix external renderer * use GBackground context as fallback * no fallback, return error Co-authored-by: Lauris BH <lauris@nix.lv> * Add checkbox to delete pull branch after successful merge (#16049) * Add checkbox to delete pull branch after successful merge * Omit DeleteBranchAfterMerge field in json * Log a warning instead of error when PR head branch deleted * Add DefaultDeleteBranchAfterMerge to PullRequestConfig * Add support for delete_branch_after_merge via API * Fix for API: the branch should be deleted from the HEAD repo If head and base repo are the same, reuse the already opened ctx.Repo.GitRepo * Don't delegate to CleanupBranch, only reuse branch deletion code CleanupBranch contains too much logic that has already been performed by the Merge * Reuse gitrepo in MergePullRequest Co-authored-by: Andrew Thornton <art27@cantab.net> * [skip ci] Updated translations via Crowdin * Detect encoding changes while parsing diff (#16330) * Detect encoding changes while parsing diff * Let branch/tag name be a valid ref to get CI status (#16400) * fix #16384# * refactor: move shared helper func to utils package * extend Tests * use ctx.Repo.GitRepo if not nil * fix * fix * 企业微信webhook * 企业微信webhook * 企业微信webhook * fix build * fix build * Apply suggestions from code review Co-authored-by: a1012112796 <1012112796@qq.com> Co-authored-by: myheavily <myheavily> Co-authored-by: zhaoxin <gitea@fake.local> Co-authored-by: Meano <Meano@foxmail.com> Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: GiteaBot <teabot@gitea.io> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Bagas Sanjaya <bagasdotme@gmail.com> Co-authored-by: Norwin <noerw@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: Jimmy Praet <jimmy.praet@telenet.be> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2 years ago
Add support for corporate WeChat webhooks (#15910) * 企业微信webhook * 企业微信webhook * 企业微信webhook * Update templates/admin/hook_new.tmpl Co-authored-by: a1012112796 <1012112796@qq.com> * Update services/webhook/wechatwork.go Co-authored-by: a1012112796 <1012112796@qq.com> * 修善wechatwork * 修善wechatwork * fix * Update locale_cs-CZ.ini fix * fix build * fix * fix build * make webhooks.zh-cn.md * delet unnecessary blank line * delet unnecessary blank line * 企业微信webhook * 企业微信webhook * 企业微信webhook * Update templates/admin/hook_new.tmpl Co-authored-by: a1012112796 <1012112796@qq.com> * Update services/webhook/wechatwork.go Co-authored-by: a1012112796 <1012112796@qq.com> * 修善wechatwork * 修善wechatwork * fix * fix build * fix * fix build * make webhooks.zh-cn.md * delet unnecessary blank line * delet unnecessary blank line * 企业微信webhook * 企业微信webhook * 企业微信webhook * 企业微信webhook * 企业微信webhook * fix * fix * 企业微信webhook * 企业微信webhook * 企业微信webhook * fix wechat * fix wechat * fix wechat * fix wechat * Fix invalid params and typo of email templates (#16394) Signed-off-by: Meano <meanocat@gmail.com> * Add LRU mem cache implementation (#16226) The current default memory cache implementation is unbounded in size and number of objects cached. This is hardly ideal. This PR proposes creating a TwoQueue LRU cache as the underlying cache for Gitea. The cache is limited by the number of objects stored in the cache (rather than size) for simplicity. The default number of objects is 50000 - which is perhaps too small as most of our objects cached are going to be much less than 1kB. It may be worth considering using a different LRU implementation that actively limits sizes or avoids GC - however, this is just a beginning implementation. Signed-off-by: Andrew Thornton <art27@cantab.net> * [skip ci] Updated translations via Crowdin * Replace `plugins/docker` with `techknowlogick/drone-docker`in ci (#16407) * plugins/docker -> techknowlogick/drone-docker * It is multi-arch * docs: rewrite email setup (#16404) * Add intro for both the docs page and mailer methods * Fix numbering level in SMTP section * Recommends implicit TLS Signed-off-by: Bagas Sanjaya <bagasdotme@gmail.com> * Validate Issue Index before querying DB (#16406) * Fix external renderer (#16401) * fix external renderer * use GBackground context as fallback * no fallback, return error Co-authored-by: Lauris BH <lauris@nix.lv> * Add checkbox to delete pull branch after successful merge (#16049) * Add checkbox to delete pull branch after successful merge * Omit DeleteBranchAfterMerge field in json * Log a warning instead of error when PR head branch deleted * Add DefaultDeleteBranchAfterMerge to PullRequestConfig * Add support for delete_branch_after_merge via API * Fix for API: the branch should be deleted from the HEAD repo If head and base repo are the same, reuse the already opened ctx.Repo.GitRepo * Don't delegate to CleanupBranch, only reuse branch deletion code CleanupBranch contains too much logic that has already been performed by the Merge * Reuse gitrepo in MergePullRequest Co-authored-by: Andrew Thornton <art27@cantab.net> * [skip ci] Updated translations via Crowdin * Detect encoding changes while parsing diff (#16330) * Detect encoding changes while parsing diff * Let branch/tag name be a valid ref to get CI status (#16400) * fix #16384# * refactor: move shared helper func to utils package * extend Tests * use ctx.Repo.GitRepo if not nil * fix * fix * 企业微信webhook * 企业微信webhook * 企业微信webhook * fix build * fix build * Apply suggestions from code review Co-authored-by: a1012112796 <1012112796@qq.com> Co-authored-by: myheavily <myheavily> Co-authored-by: zhaoxin <gitea@fake.local> Co-authored-by: Meano <Meano@foxmail.com> Co-authored-by: zeripath <art27@cantab.net> Co-authored-by: GiteaBot <teabot@gitea.io> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Bagas Sanjaya <bagasdotme@gmail.com> Co-authored-by: Norwin <noerw@users.noreply.github.com> Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: Jimmy Praet <jimmy.praet@telenet.be> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2 years ago
Add context cache as a request level cache (#22294) To avoid duplicated load of the same data in an HTTP request, we can set a context cache to do that. i.e. Some pages may load a user from a database with the same id in different areas on the same page. But the code is hidden in two different deep logic. How should we share the user? As a result of this PR, now if both entry functions accept `context.Context` as the first parameter and we just need to refactor `GetUserByID` to reuse the user from the context cache. Then it will not be loaded twice on an HTTP request. But of course, sometimes we would like to reload an object from the database, that's why `RemoveContextData` is also exposed. The core context cache is here. It defines a new context ```go type cacheContext struct { ctx context.Context data map[any]map[any]any lock sync.RWMutex } var cacheContextKey = struct{}{} func WithCacheContext(ctx context.Context) context.Context { return context.WithValue(ctx, cacheContextKey, &cacheContext{ ctx: ctx, data: make(map[any]map[any]any), }) } ``` Then you can use the below 4 methods to read/write/del the data within the same context. ```go func GetContextData(ctx context.Context, tp, key any) any func SetContextData(ctx context.Context, tp, key, value any) func RemoveContextData(ctx context.Context, tp, key any) func GetWithContextCache[T any](ctx context.Context, cacheGroupKey string, cacheTargetID any, f func() (T, error)) (T, error) ``` Then let's take a look at how `system.GetString` implement it. ```go func GetSetting(ctx context.Context, key string) (string, error) { return cache.GetWithContextCache(ctx, contextCacheKey, key, func() (string, error) { return cache.GetString(genSettingCacheKey(key), func() (string, error) { res, err := GetSettingNoCache(ctx, key) if err != nil { return "", err } return res.SettingValue, nil }) }) } ``` First, it will check if context data include the setting object with the key. If not, it will query from the global cache which may be memory or a Redis cache. If not, it will get the object from the database. In the end, if the object gets from the global cache or database, it will be set into the context cache. An object stored in the context cache will only be destroyed after the context disappeared.
1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2017 The Gitea Authors. All rights reserved.
  3. // SPDX-License-Identifier: MIT
  4. package setting
  5. import (
  6. "errors"
  7. "fmt"
  8. "net/http"
  9. "net/url"
  10. "path"
  11. "strings"
  12. "code.gitea.io/gitea/models/perm"
  13. access_model "code.gitea.io/gitea/models/perm/access"
  14. user_model "code.gitea.io/gitea/models/user"
  15. "code.gitea.io/gitea/models/webhook"
  16. "code.gitea.io/gitea/modules/base"
  17. "code.gitea.io/gitea/modules/context"
  18. "code.gitea.io/gitea/modules/git"
  19. "code.gitea.io/gitea/modules/json"
  20. "code.gitea.io/gitea/modules/setting"
  21. api "code.gitea.io/gitea/modules/structs"
  22. "code.gitea.io/gitea/modules/util"
  23. "code.gitea.io/gitea/modules/web"
  24. webhook_module "code.gitea.io/gitea/modules/webhook"
  25. "code.gitea.io/gitea/services/convert"
  26. "code.gitea.io/gitea/services/forms"
  27. webhook_service "code.gitea.io/gitea/services/webhook"
  28. )
  29. const (
  30. tplHooks base.TplName = "repo/settings/webhook/base"
  31. tplHookNew base.TplName = "repo/settings/webhook/new"
  32. tplOrgHookNew base.TplName = "org/settings/hook_new"
  33. tplUserHookNew base.TplName = "user/settings/hook_new"
  34. tplAdminHookNew base.TplName = "admin/hook_new"
  35. )
  36. // Webhooks render web hooks list page
  37. func Webhooks(ctx *context.Context) {
  38. ctx.Data["Title"] = ctx.Tr("repo.settings.hooks")
  39. ctx.Data["PageIsSettingsHooks"] = true
  40. ctx.Data["BaseLink"] = ctx.Repo.RepoLink + "/settings/hooks"
  41. ctx.Data["BaseLinkNew"] = ctx.Repo.RepoLink + "/settings/hooks"
  42. ctx.Data["Description"] = ctx.Tr("repo.settings.hooks_desc", "https://docs.gitea.com/usage/webhooks")
  43. ws, err := webhook.ListWebhooksByOpts(ctx, &webhook.ListWebhookOptions{RepoID: ctx.Repo.Repository.ID})
  44. if err != nil {
  45. ctx.ServerError("GetWebhooksByRepoID", err)
  46. return
  47. }
  48. ctx.Data["Webhooks"] = ws
  49. ctx.HTML(http.StatusOK, tplHooks)
  50. }
  51. type ownerRepoCtx struct {
  52. OwnerID int64
  53. RepoID int64
  54. IsAdmin bool
  55. IsSystemWebhook bool
  56. Link string
  57. LinkNew string
  58. NewTemplate base.TplName
  59. }
  60. // getOwnerRepoCtx determines whether this is a repo, owner, or admin (both default and system) context.
  61. func getOwnerRepoCtx(ctx *context.Context) (*ownerRepoCtx, error) {
  62. if ctx.Data["PageIsRepoSettings"] == true {
  63. return &ownerRepoCtx{
  64. RepoID: ctx.Repo.Repository.ID,
  65. Link: path.Join(ctx.Repo.RepoLink, "settings/hooks"),
  66. LinkNew: path.Join(ctx.Repo.RepoLink, "settings/hooks"),
  67. NewTemplate: tplHookNew,
  68. }, nil
  69. }
  70. if ctx.Data["PageIsOrgSettings"] == true {
  71. return &ownerRepoCtx{
  72. OwnerID: ctx.ContextUser.ID,
  73. Link: path.Join(ctx.Org.OrgLink, "settings/hooks"),
  74. LinkNew: path.Join(ctx.Org.OrgLink, "settings/hooks"),
  75. NewTemplate: tplOrgHookNew,
  76. }, nil
  77. }
  78. if ctx.Data["PageIsUserSettings"] == true {
  79. return &ownerRepoCtx{
  80. OwnerID: ctx.Doer.ID,
  81. Link: path.Join(setting.AppSubURL, "/user/settings/hooks"),
  82. LinkNew: path.Join(setting.AppSubURL, "/user/settings/hooks"),
  83. NewTemplate: tplUserHookNew,
  84. }, nil
  85. }
  86. if ctx.Data["PageIsAdmin"] == true {
  87. return &ownerRepoCtx{
  88. IsAdmin: true,
  89. IsSystemWebhook: ctx.Params(":configType") == "system-hooks",
  90. Link: path.Join(setting.AppSubURL, "/admin/hooks"),
  91. LinkNew: path.Join(setting.AppSubURL, "/admin/", ctx.Params(":configType")),
  92. NewTemplate: tplAdminHookNew,
  93. }, nil
  94. }
  95. return nil, errors.New("unable to set OwnerRepo context")
  96. }
  97. func checkHookType(ctx *context.Context) string {
  98. hookType := strings.ToLower(ctx.Params(":type"))
  99. if !util.SliceContainsString(setting.Webhook.Types, hookType, true) {
  100. ctx.NotFound("checkHookType", nil)
  101. return ""
  102. }
  103. return hookType
  104. }
  105. // WebhooksNew render creating webhook page
  106. func WebhooksNew(ctx *context.Context) {
  107. ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook")
  108. ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook_module.HookEvent{}}
  109. orCtx, err := getOwnerRepoCtx(ctx)
  110. if err != nil {
  111. ctx.ServerError("getOwnerRepoCtx", err)
  112. return
  113. }
  114. if orCtx.IsAdmin && orCtx.IsSystemWebhook {
  115. ctx.Data["PageIsAdminSystemHooks"] = true
  116. ctx.Data["PageIsAdminSystemHooksNew"] = true
  117. } else if orCtx.IsAdmin {
  118. ctx.Data["PageIsAdminDefaultHooks"] = true
  119. ctx.Data["PageIsAdminDefaultHooksNew"] = true
  120. } else {
  121. ctx.Data["PageIsSettingsHooks"] = true
  122. ctx.Data["PageIsSettingsHooksNew"] = true
  123. }
  124. hookType := checkHookType(ctx)
  125. ctx.Data["HookType"] = hookType
  126. if ctx.Written() {
  127. return
  128. }
  129. if hookType == "discord" {
  130. ctx.Data["DiscordHook"] = map[string]any{
  131. "Username": "Gitea",
  132. }
  133. }
  134. ctx.Data["BaseLink"] = orCtx.LinkNew
  135. ctx.HTML(http.StatusOK, orCtx.NewTemplate)
  136. }
  137. // ParseHookEvent convert web form content to webhook.HookEvent
  138. func ParseHookEvent(form forms.WebhookForm) *webhook_module.HookEvent {
  139. return &webhook_module.HookEvent{
  140. PushOnly: form.PushOnly(),
  141. SendEverything: form.SendEverything(),
  142. ChooseEvents: form.ChooseEvents(),
  143. HookEvents: webhook_module.HookEvents{
  144. Create: form.Create,
  145. Delete: form.Delete,
  146. Fork: form.Fork,
  147. Issues: form.Issues,
  148. IssueAssign: form.IssueAssign,
  149. IssueLabel: form.IssueLabel,
  150. IssueMilestone: form.IssueMilestone,
  151. IssueComment: form.IssueComment,
  152. Release: form.Release,
  153. Push: form.Push,
  154. PullRequest: form.PullRequest,
  155. PullRequestAssign: form.PullRequestAssign,
  156. PullRequestLabel: form.PullRequestLabel,
  157. PullRequestMilestone: form.PullRequestMilestone,
  158. PullRequestComment: form.PullRequestComment,
  159. PullRequestReview: form.PullRequestReview,
  160. PullRequestSync: form.PullRequestSync,
  161. PullRequestReviewRequest: form.PullRequestReviewRequest,
  162. Wiki: form.Wiki,
  163. Repository: form.Repository,
  164. Package: form.Package,
  165. },
  166. BranchFilter: form.BranchFilter,
  167. }
  168. }
  169. type webhookParams struct {
  170. // Type should be imported from webhook package (webhook.XXX)
  171. Type string
  172. URL string
  173. ContentType webhook.HookContentType
  174. Secret string
  175. HTTPMethod string
  176. WebhookForm forms.WebhookForm
  177. Meta any
  178. }
  179. func createWebhook(ctx *context.Context, params webhookParams) {
  180. ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook")
  181. ctx.Data["PageIsSettingsHooks"] = true
  182. ctx.Data["PageIsSettingsHooksNew"] = true
  183. ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook_module.HookEvent{}}
  184. ctx.Data["HookType"] = params.Type
  185. orCtx, err := getOwnerRepoCtx(ctx)
  186. if err != nil {
  187. ctx.ServerError("getOwnerRepoCtx", err)
  188. return
  189. }
  190. ctx.Data["BaseLink"] = orCtx.LinkNew
  191. if ctx.HasError() {
  192. ctx.HTML(http.StatusOK, orCtx.NewTemplate)
  193. return
  194. }
  195. var meta []byte
  196. if params.Meta != nil {
  197. meta, err = json.Marshal(params.Meta)
  198. if err != nil {
  199. ctx.ServerError("Marshal", err)
  200. return
  201. }
  202. }
  203. w := &webhook.Webhook{
  204. RepoID: orCtx.RepoID,
  205. URL: params.URL,
  206. HTTPMethod: params.HTTPMethod,
  207. ContentType: params.ContentType,
  208. Secret: params.Secret,
  209. HookEvent: ParseHookEvent(params.WebhookForm),
  210. IsActive: params.WebhookForm.Active,
  211. Type: params.Type,
  212. Meta: string(meta),
  213. OwnerID: orCtx.OwnerID,
  214. IsSystemWebhook: orCtx.IsSystemWebhook,
  215. }
  216. err = w.SetHeaderAuthorization(params.WebhookForm.AuthorizationHeader)
  217. if err != nil {
  218. ctx.ServerError("SetHeaderAuthorization", err)
  219. return
  220. }
  221. if err := w.UpdateEvent(); err != nil {
  222. ctx.ServerError("UpdateEvent", err)
  223. return
  224. } else if err := webhook.CreateWebhook(ctx, w); err != nil {
  225. ctx.ServerError("CreateWebhook", err)
  226. return
  227. }
  228. ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
  229. ctx.Redirect(orCtx.Link)
  230. }
  231. func editWebhook(ctx *context.Context, params webhookParams) {
  232. ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook")
  233. ctx.Data["PageIsSettingsHooks"] = true
  234. ctx.Data["PageIsSettingsHooksEdit"] = true
  235. orCtx, w := checkWebhook(ctx)
  236. if ctx.Written() {
  237. return
  238. }
  239. ctx.Data["Webhook"] = w
  240. if ctx.HasError() {
  241. ctx.HTML(http.StatusOK, orCtx.NewTemplate)
  242. return
  243. }
  244. var meta []byte
  245. var err error
  246. if params.Meta != nil {
  247. meta, err = json.Marshal(params.Meta)
  248. if err != nil {
  249. ctx.ServerError("Marshal", err)
  250. return
  251. }
  252. }
  253. w.URL = params.URL
  254. w.ContentType = params.ContentType
  255. w.Secret = params.Secret
  256. w.HookEvent = ParseHookEvent(params.WebhookForm)
  257. w.IsActive = params.WebhookForm.Active
  258. w.HTTPMethod = params.HTTPMethod
  259. w.Meta = string(meta)
  260. err = w.SetHeaderAuthorization(params.WebhookForm.AuthorizationHeader)
  261. if err != nil {
  262. ctx.ServerError("SetHeaderAuthorization", err)
  263. return
  264. }
  265. if err := w.UpdateEvent(); err != nil {
  266. ctx.ServerError("UpdateEvent", err)
  267. return
  268. } else if err := webhook.UpdateWebhook(w); err != nil {
  269. ctx.ServerError("UpdateWebhook", err)
  270. return
  271. }
  272. ctx.Flash.Success(ctx.Tr("repo.settings.update_hook_success"))
  273. ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID))
  274. }
  275. // GiteaHooksNewPost response for creating Gitea webhook
  276. func GiteaHooksNewPost(ctx *context.Context) {
  277. createWebhook(ctx, giteaHookParams(ctx))
  278. }
  279. // GiteaHooksEditPost response for editing Gitea webhook
  280. func GiteaHooksEditPost(ctx *context.Context) {
  281. editWebhook(ctx, giteaHookParams(ctx))
  282. }
  283. func giteaHookParams(ctx *context.Context) webhookParams {
  284. form := web.GetForm(ctx).(*forms.NewWebhookForm)
  285. contentType := webhook.ContentTypeJSON
  286. if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm {
  287. contentType = webhook.ContentTypeForm
  288. }
  289. return webhookParams{
  290. Type: webhook_module.GITEA,
  291. URL: form.PayloadURL,
  292. ContentType: contentType,
  293. Secret: form.Secret,
  294. HTTPMethod: form.HTTPMethod,
  295. WebhookForm: form.WebhookForm,
  296. }
  297. }
  298. // GogsHooksNewPost response for creating Gogs webhook
  299. func GogsHooksNewPost(ctx *context.Context) {
  300. createWebhook(ctx, gogsHookParams(ctx))
  301. }
  302. // GogsHooksEditPost response for editing Gogs webhook
  303. func GogsHooksEditPost(ctx *context.Context) {
  304. editWebhook(ctx, gogsHookParams(ctx))
  305. }
  306. func gogsHookParams(ctx *context.Context) webhookParams {
  307. form := web.GetForm(ctx).(*forms.NewGogshookForm)
  308. contentType := webhook.ContentTypeJSON
  309. if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm {
  310. contentType = webhook.ContentTypeForm
  311. }
  312. return webhookParams{
  313. Type: webhook_module.GOGS,
  314. URL: form.PayloadURL,
  315. ContentType: contentType,
  316. Secret: form.Secret,
  317. WebhookForm: form.WebhookForm,
  318. }
  319. }
  320. // DiscordHooksNewPost response for creating Discord webhook
  321. func DiscordHooksNewPost(ctx *context.Context) {
  322. createWebhook(ctx, discordHookParams(ctx))
  323. }
  324. // DiscordHooksEditPost response for editing Discord webhook
  325. func DiscordHooksEditPost(ctx *context.Context) {
  326. editWebhook(ctx, discordHookParams(ctx))
  327. }
  328. func discordHookParams(ctx *context.Context) webhookParams {
  329. form := web.GetForm(ctx).(*forms.NewDiscordHookForm)
  330. return webhookParams{
  331. Type: webhook_module.DISCORD,
  332. URL: form.PayloadURL,
  333. ContentType: webhook.ContentTypeJSON,
  334. WebhookForm: form.WebhookForm,
  335. Meta: &webhook_service.DiscordMeta{
  336. Username: form.Username,
  337. IconURL: form.IconURL,
  338. },
  339. }
  340. }
  341. // DingtalkHooksNewPost response for creating Dingtalk webhook
  342. func DingtalkHooksNewPost(ctx *context.Context) {
  343. createWebhook(ctx, dingtalkHookParams(ctx))
  344. }
  345. // DingtalkHooksEditPost response for editing Dingtalk webhook
  346. func DingtalkHooksEditPost(ctx *context.Context) {
  347. editWebhook(ctx, dingtalkHookParams(ctx))
  348. }
  349. func dingtalkHookParams(ctx *context.Context) webhookParams {
  350. form := web.GetForm(ctx).(*forms.NewDingtalkHookForm)
  351. return webhookParams{
  352. Type: webhook_module.DINGTALK,
  353. URL: form.PayloadURL,
  354. ContentType: webhook.ContentTypeJSON,
  355. WebhookForm: form.WebhookForm,
  356. }
  357. }
  358. // TelegramHooksNewPost response for creating Telegram webhook
  359. func TelegramHooksNewPost(ctx *context.Context) {
  360. createWebhook(ctx, telegramHookParams(ctx))
  361. }
  362. // TelegramHooksEditPost response for editing Telegram webhook
  363. func TelegramHooksEditPost(ctx *context.Context) {
  364. editWebhook(ctx, telegramHookParams(ctx))
  365. }
  366. func telegramHookParams(ctx *context.Context) webhookParams {
  367. form := web.GetForm(ctx).(*forms.NewTelegramHookForm)
  368. return webhookParams{
  369. Type: webhook_module.TELEGRAM,
  370. URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s&message_thread_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID), url.QueryEscape(form.ThreadID)),
  371. ContentType: webhook.ContentTypeJSON,
  372. WebhookForm: form.WebhookForm,
  373. Meta: &webhook_service.TelegramMeta{
  374. BotToken: form.BotToken,
  375. ChatID: form.ChatID,
  376. ThreadID: form.ThreadID,
  377. },
  378. }
  379. }
  380. // MatrixHooksNewPost response for creating Matrix webhook
  381. func MatrixHooksNewPost(ctx *context.Context) {
  382. createWebhook(ctx, matrixHookParams(ctx))
  383. }
  384. // MatrixHooksEditPost response for editing Matrix webhook
  385. func MatrixHooksEditPost(ctx *context.Context) {
  386. editWebhook(ctx, matrixHookParams(ctx))
  387. }
  388. func matrixHookParams(ctx *context.Context) webhookParams {
  389. form := web.GetForm(ctx).(*forms.NewMatrixHookForm)
  390. return webhookParams{
  391. Type: webhook_module.MATRIX,
  392. URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID)),
  393. ContentType: webhook.ContentTypeJSON,
  394. HTTPMethod: http.MethodPut,
  395. WebhookForm: form.WebhookForm,
  396. Meta: &webhook_service.MatrixMeta{
  397. HomeserverURL: form.HomeserverURL,
  398. Room: form.RoomID,
  399. MessageType: form.MessageType,
  400. },
  401. }
  402. }
  403. // MSTeamsHooksNewPost response for creating MSTeams webhook
  404. func MSTeamsHooksNewPost(ctx *context.Context) {
  405. createWebhook(ctx, mSTeamsHookParams(ctx))
  406. }
  407. // MSTeamsHooksEditPost response for editing MSTeams webhook
  408. func MSTeamsHooksEditPost(ctx *context.Context) {
  409. editWebhook(ctx, mSTeamsHookParams(ctx))
  410. }
  411. func mSTeamsHookParams(ctx *context.Context) webhookParams {
  412. form := web.GetForm(ctx).(*forms.NewMSTeamsHookForm)
  413. return webhookParams{
  414. Type: webhook_module.MSTEAMS,
  415. URL: form.PayloadURL,
  416. ContentType: webhook.ContentTypeJSON,
  417. WebhookForm: form.WebhookForm,
  418. }
  419. }
  420. // SlackHooksNewPost response for creating Slack webhook
  421. func SlackHooksNewPost(ctx *context.Context) {
  422. createWebhook(ctx, slackHookParams(ctx))
  423. }
  424. // SlackHooksEditPost response for editing Slack webhook
  425. func SlackHooksEditPost(ctx *context.Context) {
  426. editWebhook(ctx, slackHookParams(ctx))
  427. }
  428. func slackHookParams(ctx *context.Context) webhookParams {
  429. form := web.GetForm(ctx).(*forms.NewSlackHookForm)
  430. return webhookParams{
  431. Type: webhook_module.SLACK,
  432. URL: form.PayloadURL,
  433. ContentType: webhook.ContentTypeJSON,
  434. WebhookForm: form.WebhookForm,
  435. Meta: &webhook_service.SlackMeta{
  436. Channel: strings.TrimSpace(form.Channel),
  437. Username: form.Username,
  438. IconURL: form.IconURL,
  439. Color: form.Color,
  440. },
  441. }
  442. }
  443. // FeishuHooksNewPost response for creating Feishu webhook
  444. func FeishuHooksNewPost(ctx *context.Context) {
  445. createWebhook(ctx, feishuHookParams(ctx))
  446. }
  447. // FeishuHooksEditPost response for editing Feishu webhook
  448. func FeishuHooksEditPost(ctx *context.Context) {
  449. editWebhook(ctx, feishuHookParams(ctx))
  450. }
  451. func feishuHookParams(ctx *context.Context) webhookParams {
  452. form := web.GetForm(ctx).(*forms.NewFeishuHookForm)
  453. return webhookParams{
  454. Type: webhook_module.FEISHU,
  455. URL: form.PayloadURL,
  456. ContentType: webhook.ContentTypeJSON,
  457. WebhookForm: form.WebhookForm,
  458. }
  459. }
  460. // WechatworkHooksNewPost response for creating Wechatwork webhook
  461. func WechatworkHooksNewPost(ctx *context.Context) {
  462. createWebhook(ctx, wechatworkHookParams(ctx))
  463. }
  464. // WechatworkHooksEditPost response for editing Wechatwork webhook
  465. func WechatworkHooksEditPost(ctx *context.Context) {
  466. editWebhook(ctx, wechatworkHookParams(ctx))
  467. }
  468. func wechatworkHookParams(ctx *context.Context) webhookParams {
  469. form := web.GetForm(ctx).(*forms.NewWechatWorkHookForm)
  470. return webhookParams{
  471. Type: webhook_module.WECHATWORK,
  472. URL: form.PayloadURL,
  473. ContentType: webhook.ContentTypeJSON,
  474. WebhookForm: form.WebhookForm,
  475. }
  476. }
  477. // PackagistHooksNewPost response for creating Packagist webhook
  478. func PackagistHooksNewPost(ctx *context.Context) {
  479. createWebhook(ctx, packagistHookParams(ctx))
  480. }
  481. // PackagistHooksEditPost response for editing Packagist webhook
  482. func PackagistHooksEditPost(ctx *context.Context) {
  483. editWebhook(ctx, packagistHookParams(ctx))
  484. }
  485. func packagistHookParams(ctx *context.Context) webhookParams {
  486. form := web.GetForm(ctx).(*forms.NewPackagistHookForm)
  487. return webhookParams{
  488. Type: webhook_module.PACKAGIST,
  489. URL: fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken)),
  490. ContentType: webhook.ContentTypeJSON,
  491. WebhookForm: form.WebhookForm,
  492. Meta: &webhook_service.PackagistMeta{
  493. Username: form.Username,
  494. APIToken: form.APIToken,
  495. PackageURL: form.PackageURL,
  496. },
  497. }
  498. }
  499. func checkWebhook(ctx *context.Context) (*ownerRepoCtx, *webhook.Webhook) {
  500. orCtx, err := getOwnerRepoCtx(ctx)
  501. if err != nil {
  502. ctx.ServerError("getOwnerRepoCtx", err)
  503. return nil, nil
  504. }
  505. ctx.Data["BaseLink"] = orCtx.Link
  506. var w *webhook.Webhook
  507. if orCtx.RepoID > 0 {
  508. w, err = webhook.GetWebhookByRepoID(orCtx.RepoID, ctx.ParamsInt64(":id"))
  509. } else if orCtx.OwnerID > 0 {
  510. w, err = webhook.GetWebhookByOwnerID(orCtx.OwnerID, ctx.ParamsInt64(":id"))
  511. } else if orCtx.IsAdmin {
  512. w, err = webhook.GetSystemOrDefaultWebhook(ctx, ctx.ParamsInt64(":id"))
  513. }
  514. if err != nil || w == nil {
  515. if webhook.IsErrWebhookNotExist(err) {
  516. ctx.NotFound("GetWebhookByID", nil)
  517. } else {
  518. ctx.ServerError("GetWebhookByID", err)
  519. }
  520. return nil, nil
  521. }
  522. ctx.Data["HookType"] = w.Type
  523. switch w.Type {
  524. case webhook_module.SLACK:
  525. ctx.Data["SlackHook"] = webhook_service.GetSlackHook(w)
  526. case webhook_module.DISCORD:
  527. ctx.Data["DiscordHook"] = webhook_service.GetDiscordHook(w)
  528. case webhook_module.TELEGRAM:
  529. ctx.Data["TelegramHook"] = webhook_service.GetTelegramHook(w)
  530. case webhook_module.MATRIX:
  531. ctx.Data["MatrixHook"] = webhook_service.GetMatrixHook(w)
  532. case webhook_module.PACKAGIST:
  533. ctx.Data["PackagistHook"] = webhook_service.GetPackagistHook(w)
  534. }
  535. ctx.Data["History"], err = w.History(1)
  536. if err != nil {
  537. ctx.ServerError("History", err)
  538. }
  539. return orCtx, w
  540. }
  541. // WebHooksEdit render editing web hook page
  542. func WebHooksEdit(ctx *context.Context) {
  543. ctx.Data["Title"] = ctx.Tr("repo.settings.update_webhook")
  544. ctx.Data["PageIsSettingsHooks"] = true
  545. ctx.Data["PageIsSettingsHooksEdit"] = true
  546. orCtx, w := checkWebhook(ctx)
  547. if ctx.Written() {
  548. return
  549. }
  550. ctx.Data["Webhook"] = w
  551. ctx.HTML(http.StatusOK, orCtx.NewTemplate)
  552. }
  553. // TestWebhook test if web hook is work fine
  554. func TestWebhook(ctx *context.Context) {
  555. hookID := ctx.ParamsInt64(":id")
  556. w, err := webhook.GetWebhookByRepoID(ctx.Repo.Repository.ID, hookID)
  557. if err != nil {
  558. ctx.Flash.Error("GetWebhookByRepoID: " + err.Error())
  559. ctx.Status(http.StatusInternalServerError)
  560. return
  561. }
  562. // Grab latest commit or fake one if it's empty repository.
  563. commit := ctx.Repo.Commit
  564. if commit == nil {
  565. ghost := user_model.NewGhostUser()
  566. commit = &git.Commit{
  567. ID: git.MustIDFromString(git.EmptySHA),
  568. Author: ghost.NewGitSig(),
  569. Committer: ghost.NewGitSig(),
  570. CommitMessage: "This is a fake commit",
  571. }
  572. }
  573. apiUser := convert.ToUserWithAccessMode(ctx, ctx.Doer, perm.AccessModeNone)
  574. apiCommit := &api.PayloadCommit{
  575. ID: commit.ID.String(),
  576. Message: commit.Message(),
  577. URL: ctx.Repo.Repository.HTMLURL() + "/commit/" + url.PathEscape(commit.ID.String()),
  578. Author: &api.PayloadUser{
  579. Name: commit.Author.Name,
  580. Email: commit.Author.Email,
  581. },
  582. Committer: &api.PayloadUser{
  583. Name: commit.Committer.Name,
  584. Email: commit.Committer.Email,
  585. },
  586. }
  587. commitID := commit.ID.String()
  588. p := &api.PushPayload{
  589. Ref: git.BranchPrefix + ctx.Repo.Repository.DefaultBranch,
  590. Before: commitID,
  591. After: commitID,
  592. CompareURL: setting.AppURL + ctx.Repo.Repository.ComposeCompareURL(commitID, commitID),
  593. Commits: []*api.PayloadCommit{apiCommit},
  594. TotalCommits: 1,
  595. HeadCommit: apiCommit,
  596. Repo: convert.ToRepo(ctx, ctx.Repo.Repository, access_model.Permission{AccessMode: perm.AccessModeNone}),
  597. Pusher: apiUser,
  598. Sender: apiUser,
  599. }
  600. if err := webhook_service.PrepareWebhook(ctx, w, webhook_module.HookEventPush, p); err != nil {
  601. ctx.Flash.Error("PrepareWebhook: " + err.Error())
  602. ctx.Status(http.StatusInternalServerError)
  603. } else {
  604. ctx.Flash.Info(ctx.Tr("repo.settings.webhook.delivery.success"))
  605. ctx.Status(http.StatusOK)
  606. }
  607. }
  608. // ReplayWebhook replays a webhook
  609. func ReplayWebhook(ctx *context.Context) {
  610. hookTaskUUID := ctx.Params(":uuid")
  611. orCtx, w := checkWebhook(ctx)
  612. if ctx.Written() {
  613. return
  614. }
  615. if err := webhook_service.ReplayHookTask(ctx, w, hookTaskUUID); err != nil {
  616. if webhook.IsErrHookTaskNotExist(err) {
  617. ctx.NotFound("ReplayHookTask", nil)
  618. } else {
  619. ctx.ServerError("ReplayHookTask", err)
  620. }
  621. return
  622. }
  623. ctx.Flash.Success(ctx.Tr("repo.settings.webhook.delivery.success"))
  624. ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID))
  625. }
  626. // DeleteWebhook delete a webhook
  627. func DeleteWebhook(ctx *context.Context) {
  628. if err := webhook.DeleteWebhookByRepoID(ctx.Repo.Repository.ID, ctx.FormInt64("id")); err != nil {
  629. ctx.Flash.Error("DeleteWebhookByRepoID: " + err.Error())
  630. } else {
  631. ctx.Flash.Success(ctx.Tr("repo.settings.webhook_deletion_success"))
  632. }
  633. ctx.JSONRedirect(ctx.Repo.RepoLink + "/settings/hooks")
  634. }