2020-01-22 06:00:39 +01:00
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package middlewares
import (
2020-07-20 18:41:00 +02:00
"net/http"
"regexp"
2022-11-24 11:07:42 +01:00
"github.com/beego/beego/v2/server/web"
2022-07-20 05:33:08 +02:00
2020-07-20 18:41:00 +02:00
"github.com/goharbor/harbor/src/pkg/distribution"
2020-01-22 06:00:39 +01:00
"github.com/goharbor/harbor/src/server/middleware"
2020-07-24 09:42:48 +02:00
"github.com/goharbor/harbor/src/server/middleware/artifactinfo"
2020-06-16 11:58:58 +02:00
"github.com/goharbor/harbor/src/server/middleware/csrf"
"github.com/goharbor/harbor/src/server/middleware/log"
2021-05-28 10:13:20 +02:00
"github.com/goharbor/harbor/src/server/middleware/mergeslash"
2020-10-18 18:16:02 +02:00
"github.com/goharbor/harbor/src/server/middleware/metric"
2020-03-17 12:29:59 +01:00
"github.com/goharbor/harbor/src/server/middleware/notification"
2020-01-22 06:00:39 +01:00
"github.com/goharbor/harbor/src/server/middleware/orm"
2020-03-17 12:29:59 +01:00
"github.com/goharbor/harbor/src/server/middleware/readonly"
2020-06-16 11:58:58 +02:00
"github.com/goharbor/harbor/src/server/middleware/requestid"
2020-03-19 07:28:16 +01:00
"github.com/goharbor/harbor/src/server/middleware/security"
"github.com/goharbor/harbor/src/server/middleware/session"
2021-08-27 18:24:14 +02:00
"github.com/goharbor/harbor/src/server/middleware/trace"
2020-01-22 06:00:39 +01:00
"github.com/goharbor/harbor/src/server/middleware/transaction"
2022-06-24 11:57:46 +02:00
"github.com/goharbor/harbor/src/server/middleware/url"
2020-01-22 06:00:39 +01:00
)
var (
2023-11-10 06:08:31 +01:00
match = regexp . MustCompile
numericRegexp = match ( ` [0-9]+ ` )
serviceTokenRegexp = match ( ` ^/service/token ` )
2020-02-24 20:41:16 +01:00
2020-11-03 02:58:59 +01:00
// The ping endpoint will be blocked when DB conns reach the max open conns of the sql.DB
// which will make ping request timeout, so skip the middlewares which will require DB conn.
pingSkipper = middleware . MethodAndPathSkipper ( http . MethodGet , match ( "^/api/v2.0/ping" ) )
2021-05-11 04:54:15 +02:00
// dbTxSkippers skip the transaction middleware for PATCH Blob Upload, PUT Blob Upload and `Read` APIs
2020-07-20 18:41:00 +02:00
// because the APIs may take a long time to run, enable the transaction middleware in them will hold the database connections
// until the API finished, this behavior may eat all the database connections.
2021-05-11 04:54:15 +02:00
// There are no database writing operations in the PATCH Blob APIs, so skip the transaction middleware is all ok.
2020-07-20 18:41:00 +02:00
// For the PUT Blob Upload API, we will make a transaction manually to write blob info to the database when put blob upload successfully.
dbTxSkippers = [ ] middleware . Skipper {
middleware . MethodAndPathSkipper ( http . MethodPatch , distribution . BlobUploadURLRegexp ) ,
middleware . MethodAndPathSkipper ( http . MethodPut , distribution . BlobUploadURLRegexp ) ,
2021-05-11 04:54:15 +02:00
func ( r * http . Request ) bool { // skip tx for GET, HEAD and Options requests
m := r . Method
return m == http . MethodGet || m == http . MethodHead || m == http . MethodOptions
} ,
2020-07-20 18:41:00 +02:00
}
2020-02-24 20:41:16 +01:00
// readonlySkippers skip the post request when harbor sets to readonly.
readonlySkippers = [ ] middleware . Skipper {
2020-03-05 17:34:23 +01:00
middleware . MethodAndPathSkipper ( http . MethodPut , match ( "^/api/v2.0/configurations" ) ) ,
middleware . MethodAndPathSkipper ( http . MethodPut , match ( "^/api/internal/configurations" ) ) ,
2020-02-24 20:41:16 +01:00
middleware . MethodAndPathSkipper ( http . MethodPost , match ( "^/c/login" ) ) ,
middleware . MethodAndPathSkipper ( http . MethodPost , match ( "^/c/userExists" ) ) ,
middleware . MethodAndPathSkipper ( http . MethodPost , match ( "^/c/oidc/onboard" ) ) ,
middleware . MethodAndPathSkipper ( http . MethodPost , match ( "^/service/notifications/jobs/adminjob/" + numericRegexp . String ( ) ) ) ,
middleware . MethodAndPathSkipper ( http . MethodPost , match ( "^/service/notifications/jobs/replication/" + numericRegexp . String ( ) ) ) ,
middleware . MethodAndPathSkipper ( http . MethodPost , match ( "^/service/notifications/jobs/replication/task/" + numericRegexp . String ( ) ) ) ,
middleware . MethodAndPathSkipper ( http . MethodPost , match ( "^/service/notifications/jobs/retention/task/" + numericRegexp . String ( ) ) ) ,
middleware . MethodAndPathSkipper ( http . MethodPost , match ( "^/service/notifications/jobs/schedules/" + numericRegexp . String ( ) ) ) ,
2023-11-10 06:08:31 +01:00
// Harbor doesn't handle the POST request to /service/token. beego framework return 405 for the POST request
// some client, such as containerd, may send the POST request to /service/token and depends on 405/404/401/400 return code to determine continue or not
// the read only middleware returns 403 before the beego framework, so skip this request to make the client continue
middleware . MethodAndPathSkipper ( http . MethodPost , serviceTokenRegexp ) ,
2020-11-03 02:58:59 +01:00
pingSkipper ,
2020-02-24 20:41:16 +01:00
}
2020-01-22 06:00:39 +01:00
)
// MiddleWares returns global middlewares
2022-11-24 11:07:42 +01:00
func MiddleWares ( ) [ ] web . MiddleWare {
return [ ] web . MiddleWare {
2022-06-24 11:57:46 +02:00
url . Middleware ( ) ,
2021-05-28 10:13:20 +02:00
mergeslash . Middleware ( ) ,
2021-08-23 09:13:06 +02:00
trace . Middleware ( ) ,
2020-10-18 18:16:02 +02:00
metric . Middleware ( ) ,
2020-01-22 06:00:39 +01:00
requestid . Middleware ( ) ,
2020-03-17 12:29:59 +01:00
log . Middleware ( ) ,
2020-03-19 07:28:16 +01:00
session . Middleware ( ) ,
csrf . Middleware ( ) ,
2020-11-03 02:58:59 +01:00
orm . Middleware ( pingSkipper ) ,
notification . Middleware ( pingSkipper ) , // notification must ahead of transaction ensure the DB transaction execution complete
2020-07-20 18:41:00 +02:00
transaction . Middleware ( dbTxSkippers ... ) ,
2020-07-24 09:42:48 +02:00
artifactinfo . Middleware ( ) ,
2020-11-03 02:58:59 +01:00
security . Middleware ( pingSkipper ) ,
security . UnauthorizedMiddleware ( ) ,
2020-02-24 20:41:16 +01:00
readonly . Middleware ( readonlySkippers ... ) ,
2020-01-22 06:00:39 +01:00
}
}