From 8a308a63e2fbbe1d2d7bbe7fceb8b6bc0ac0b364 Mon Sep 17 00:00:00 2001 From: Qian Deng Date: Tue, 9 Apr 2019 17:19:05 +0800 Subject: [PATCH 1/7] Set default mode to https Default mode to https The cert file value is set to previous version style Signed-off-by: Qian Deng --- make/harbor.yml | 16 ++++++++++------ tests/hostcfg.sh | 4 ---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/make/harbor.yml b/make/harbor.yml index 7abb44217..32aee3774 100644 --- a/make/harbor.yml +++ b/make/harbor.yml @@ -3,15 +3,19 @@ #The IP address or hostname to access admin UI and registry service. #DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients. hostname: reg.mydomain.com -# core, harbor + +# http related comfig http: + # port for http, default is 80. If https enabled, this port will redirect to https port port: 80 -# https: -# port: 443 -# #The path of cert and key files for nginx -# certificate: /your/certificate/path -# private_key: /your/private/key/path +# https related comfig +https: + # https port for harbor, default is 443 + port: 443 + #The path of cert and key files for nginx + certificate: /data/cert/server.crt + private_key: /data/cert/server.key # Uncomment extearnal_url if you want to enable external proxy # And when it enabled the hostname will no longger used diff --git a/tests/hostcfg.sh b/tests/hostcfg.sh index 9aae9c3a0..7fc455fcb 100755 --- a/tests/hostcfg.sh +++ b/tests/hostcfg.sh @@ -3,7 +3,3 @@ IP=`ip addr s eth0 |grep "inet "|awk '{print $2}' |awk -F "/" '{print $1}'` #echo $IP sudo sed "s/reg.mydomain.com/$IP/" -i make/harbor.yml - -echo "https:" >> make/harbor.yml -echo " certificate: /data/cert/server.crt" >> make/harbor.yml -echo " private_key: /data/cert/server.key" >> make/harbor.yml \ No newline at end of file From f2316601d8feece41fb092b3aaab53b61c505ecd Mon Sep 17 00:00:00 2001 From: FangyuanCheng Date: Fri, 19 Apr 2019 15:42:33 +0800 Subject: [PATCH 2/7] Fix duration missed for failed jobs Signed-off-by: FangyuanCheng --- .../create-edit-endpoint.component.html | 14 +++++++------- .../create-edit-endpoint.component.scss | 6 +----- .../create-edit-endpoint.component.ts | 16 ++++++++++++++-- .../lib/src/replication/replication.component.ts | 4 +--- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.html b/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.html index 7c80db5a8..ef9dbd343 100644 --- a/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.html +++ b/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.html @@ -15,8 +15,8 @@
-
-
@@ -29,7 +29,7 @@
+ [(ngModel)]="target.credential.access_secret" size="28" name="access_secret" #access_secret="ngModel">
diff --git a/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.scss b/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.scss index 23bfc365d..bada17ade 100644 --- a/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.scss +++ b/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.scss @@ -12,10 +12,6 @@ height: 30px; } - .providerSelect { - width: 180px; - } - .inputWidth { - width: 182px; + width: 216px; } diff --git a/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts b/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts index 50f681780..5f7678cf9 100644 --- a/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts +++ b/src/portal/lib/src/create-edit-endpoint/create-edit-endpoint.component.ts @@ -32,7 +32,7 @@ import { Endpoint } from "../service/interface"; import { clone, compareValue, isEmptyObject } from "../utils"; const FAKE_PASSWORD = "rjGcfuRu"; - +const DOCKERHUB_URL = "https://registry-1.docker.io"; @Component({ selector: "hbr-create-edit-endpoint", templateUrl: "./create-edit-endpoint.component.html", @@ -41,6 +41,7 @@ const FAKE_PASSWORD = "rjGcfuRu"; export class CreateEditEndpointComponent implements AfterViewChecked, OnDestroy, OnInit { modalTitle: string; + editDisabled: boolean = false; controlEnabled: boolean = false; createEditDestinationOpened: boolean; staticBackdrop: boolean = true; @@ -178,7 +179,7 @@ export class CreateEditEndpointComponent // Open the modal now this.open(); - this.controlEnabled = true; + this.editDisabled = true; this.forceRefreshView(2000); }, error => this.errorHandler.error(error) @@ -190,6 +191,17 @@ export class CreateEditEndpointComponent .subscribe(res => (this.modalTitle = res)); // Directly open the modal this.open(); + this.editDisabled = false; + } + } + + adapterChange($event): void { + let selectValue = this.targetForm.controls.adapter.value; + if (selectValue === 'dockerHub') { + this.targetForm.controls.endpointUrl.setValue(DOCKERHUB_URL); + this.controlEnabled = true; + } else { + this.targetForm.controls.endpointUrl.setValue(""); this.controlEnabled = false; } } diff --git a/src/portal/lib/src/replication/replication.component.ts b/src/portal/lib/src/replication/replication.component.ts index 3c245a164..4ee6a6496 100644 --- a/src/portal/lib/src/replication/replication.component.ts +++ b/src/portal/lib/src/replication/replication.component.ts @@ -474,9 +474,7 @@ export class ReplicationComponent implements OnInit, OnDestroy { if (!j) { return; } - if (j.status === "Failed") { - return "-"; - } + let start_time = new Date(j.start_time).getTime(); let end_time = new Date(j.end_time).getTime(); let timesDiff = end_time - start_time; From 4e8d4fca85cf4777aaee87f9dcc180aeb78623d1 Mon Sep 17 00:00:00 2001 From: danfengliu Date: Mon, 22 Apr 2019 09:58:02 +0800 Subject: [PATCH 3/7] Due to replication NG feature already in master branch, old replication UI test cases have been moved out of Jenkins pipline, and here test case Pro-Replication-Rules-Add has been finished and ready for duty. (#7453) Signed-off-by: danfengliu --- tests/resources/Harbor-Pages/Replication.robot | 12 ++++++------ .../Harbor-Pages/Replication_Elements.robot | 2 +- tests/robot-cases/Group1-Nightly/Replication.robot | 9 ++++++++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/tests/resources/Harbor-Pages/Replication.robot b/tests/resources/Harbor-Pages/Replication.robot index 583edc1af..a705de13d 100644 --- a/tests/resources/Harbor-Pages/Replication.robot +++ b/tests/resources/Harbor-Pages/Replication.robot @@ -21,11 +21,11 @@ ${HARBOR_VERSION} v1.1.1 *** Keywords *** Check New Rule UI Without Endpoint - Click Element ${new_replication-rule_button} - Page Should Contain Please add an endpoint first - Mouse Down ${link_to_registries} - Mouse Up ${link_to_registries} - Page Should Contain Endpoint Name + Retry Element Click ${new_replication-rule_button} + Page Should Contain Please add an endpoint first + Retry Element Click ${link_to_registries} + Retry Wait Until Page Contains Endpoint URL + Retry Wait Element ${new_endpoint_button} Create A New Endpoint [Arguments] ${name} ${url} ${username} ${pwd} ${save}=Y @@ -42,7 +42,7 @@ Create A New Endpoint Run Keyword If '${save}' == 'N' No Operation Create A Rule With Existing Endpoint -# day 1=Monday..7=Sunday timeformat 12hour+am/pm +# day 1=Monday..7=Sunday timeformat 12hour+am/pm [Arguments] ${name} ${project_name} ${endpoint} ${mode} ${plan}=Daily ${weekday}=1 ${time}=0800a #click new Click Element ${new_name_xpath} diff --git a/tests/resources/Harbor-Pages/Replication_Elements.robot b/tests/resources/Harbor-Pages/Replication_Elements.robot index 44fd26d9f..3294d4606 100644 --- a/tests/resources/Harbor-Pages/Replication_Elements.robot +++ b/tests/resources/Harbor-Pages/Replication_Elements.robot @@ -31,7 +31,7 @@ ${destination_insecure_xpath} //label[@id='destination_insecure_checkbox'] ${new_replication-rule_button} //button[contains(.,'New Replication Rule')] ${link_to_registries} //clr-modal//span[contains(.,'Endpoint')] -${new_endpoint_button} //hbr-endpoint//button[contains(.,'New')] +${new_endpoint_button} //hbr-endpoint//button[contains(.,'New Endpoint')] ${rule_name} //input[@id='ruleName'] ${source_project} //input[@value='name'] ${source_image_filter_add} //hbr-create-edit-rule/clr-modal//clr-icon[@id='add-label-list'] diff --git a/tests/robot-cases/Group1-Nightly/Replication.robot b/tests/robot-cases/Group1-Nightly/Replication.robot index 62100842f..89eb28586 100644 --- a/tests/robot-cases/Group1-Nightly/Replication.robot +++ b/tests/robot-cases/Group1-Nightly/Replication.robot @@ -33,4 +33,11 @@ ${REMOTE_SERVER_API_ENDPOINT} ${REMOTE_SERVER_URL}/api *** Test Cases *** Test Case - Get Harbor Version #Just get harbor version and log it - Get Harbor Version \ No newline at end of file + Get Harbor Version + +Test Case - Pro Replication Rules Add + Init Chrome Driver + Sign In Harbor ${HARBOR_URL} ${HARBOR_ADMIN} ${HARBOR_PASSWORD} + Switch To Replication Manage + Check New Rule UI Without Endpoint + Close Browser From ca3561c8b82a550be70f91754c9616d85d82df85 Mon Sep 17 00:00:00 2001 From: Daniel Jiang Date: Thu, 28 Mar 2019 23:29:02 +0800 Subject: [PATCH 4/7] Bump up Clair to v2.0.8 (#7246) Signed-off-by: Daniel Jiang --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b257bce68..652558396 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,7 @@ PREPARE_VERSION_NAME=versions REGISTRYVERSION=v2.7.1-patch-2819 NGINXVERSION=$(VERSIONTAG) NOTARYVERSION=v0.6.1 -CLAIRVERSION=v2.0.7 +CLAIRVERSION=v2.0.8 CLAIRDBVERSION=$(VERSIONTAG) MIGRATORVERSION=$(VERSIONTAG) REDISVERSION=$(VERSIONTAG) From f742c415ada60b8dbc5470debedfa69690cf5079 Mon Sep 17 00:00:00 2001 From: Qian Deng Date: Mon, 22 Apr 2019 10:58:44 +0800 Subject: [PATCH 5/7] Upgrade the version of jinja2 Prevent verneribility issue Signed-off-by: Qian Deng --- make/photon/prepare/Pipfile | 2 +- make/photon/prepare/Pipfile.lock | 55 ++++++++++++++++---------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/make/photon/prepare/Pipfile b/make/photon/prepare/Pipfile index a6d7e0f45..91b2d3bc1 100644 --- a/make/photon/prepare/Pipfile +++ b/make/photon/prepare/Pipfile @@ -6,7 +6,7 @@ name = "pypi" [packages] pyyaml = "==4.2b1" click = "*" -"jinja2" = "*" +"jinja2" = ">=2.10.1" [dev-packages] pylint = "*" diff --git a/make/photon/prepare/Pipfile.lock b/make/photon/prepare/Pipfile.lock index 115f1f2ab..20bc8e549 100644 --- a/make/photon/prepare/Pipfile.lock +++ b/make/photon/prepare/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0fd59e52429cbbc5e345259707a98d7c071a0a59ca709882d8b106321fb2191e" + "sha256": "a3c7e13ece64f4447d0bd3648257ca4117192e5d52ff7cdd4b4c2d3109ae6500" }, "pipfile-spec": 6, "requires": { @@ -26,11 +26,11 @@ }, "jinja2": { "hashes": [ - "sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd", - "sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4" + "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", + "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" ], "index": "pypi", - "version": "==2.10" + "version": "==2.10.1" }, "markupsafe": { "hashes": [ @@ -83,10 +83,10 @@ }, "isort": { "hashes": [ - "sha256:18c796c2cd35eb1a1d3f012a214a542790a1aed95e29768bdcb9f2197eccbd0b", - "sha256:96151fca2c6e736503981896495d344781b60d18bfda78dc11b290c6125ebdb6" + "sha256:01cb7e1ca5e6c5b3f235f0385057f70558b70d2f00320208825fa62887292f43", + "sha256:268067462aed7eb2a1e237fcb287852f22077de3fb07964e87e00f829eea2d1a" ], - "version": "==4.3.15" + "version": "==4.3.17" }, "lazy-object-proxy": { "hashes": [ @@ -146,28 +146,29 @@ }, "typed-ast": { "hashes": [ - "sha256:035a54ede6ce1380599b2ce57844c6554666522e376bd111eb940fbc7c3dad23", - "sha256:037c35f2741ce3a9ac0d55abfcd119133cbd821fffa4461397718287092d9d15", - "sha256:049feae7e9f180b64efacbdc36b3af64a00393a47be22fa9cb6794e68d4e73d3", - "sha256:19228f7940beafc1ba21a6e8e070e0b0bfd1457902a3a81709762b8b9039b88d", - "sha256:2ea681e91e3550a30c2265d2916f40a5f5d89b59469a20f3bad7d07adee0f7a6", - "sha256:3a6b0a78af298d82323660df5497bcea0f0a4a25a0b003afd0ce5af049bd1f60", - "sha256:5385da8f3b801014504df0852bf83524599df890387a3c2b17b7caa3d78b1773", - "sha256:606d8afa07eef77280c2bf84335e24390055b478392e1975f96286d99d0cb424", - "sha256:69245b5b23bbf7fb242c9f8f08493e9ecd7711f063259aefffaeb90595d62287", - "sha256:6f6d839ab09830d59b7fa8fb6917023d8cb5498ee1f1dbd82d37db78eb76bc99", - "sha256:730888475f5ac0e37c1de4bd05eeb799fdb742697867f524dc8a4cd74bcecc23", - "sha256:9819b5162ffc121b9e334923c685b0d0826154e41dfe70b2ede2ce29034c71d8", - "sha256:9e60ef9426efab601dd9aa120e4ff560f4461cf8442e9c0a2b92548d52800699", - "sha256:af5fbdde0690c7da68e841d7fc2632345d570768ea7406a9434446d7b33b0ee1", - "sha256:b64efdbdf3bbb1377562c179f167f3bf301251411eb5ac77dec6b7d32bcda463", - "sha256:bac5f444c118aeb456fac1b0b5d14c6a71ea2a42069b09c176f75e9bd4c186f6", - "sha256:bda9068aafb73859491e13b99b682bd299c1b5fd50644d697533775828a28ee0", - "sha256:d659517ca116e6750101a1326107d3479028c5191f0ecee3c7203c50f5b915b0", - "sha256:eddd3fb1f3e0f82e5915a899285a39ee34ce18fd25d89582bc89fc9fb16cd2c6" + "sha256:04894d268ba6eab7e093d43107869ad49e7b5ef40d1a94243ea49b352061b200", + "sha256:16616ece19daddc586e499a3d2f560302c11f122b9c692bc216e821ae32aa0d0", + "sha256:252fdae740964b2d3cdfb3f84dcb4d6247a48a6abe2579e8029ab3be3cdc026c", + "sha256:2af80a373af123d0b9f44941a46df67ef0ff7a60f95872412a145f4500a7fc99", + "sha256:2c88d0a913229a06282b285f42a31e063c3bf9071ff65c5ea4c12acb6977c6a7", + "sha256:2ea99c029ebd4b5a308d915cc7fb95b8e1201d60b065450d5d26deb65d3f2bc1", + "sha256:3d2e3ab175fc097d2a51c7a0d3fda442f35ebcc93bb1d7bd9b95ad893e44c04d", + "sha256:4766dd695548a15ee766927bf883fb90c6ac8321be5a60c141f18628fb7f8da8", + "sha256:56b6978798502ef66625a2e0f80cf923da64e328da8bbe16c1ff928c70c873de", + "sha256:5cddb6f8bce14325b2863f9d5ac5c51e07b71b462361fd815d1d7706d3a9d682", + "sha256:644ee788222d81555af543b70a1098f2025db38eaa99226f3a75a6854924d4db", + "sha256:64cf762049fc4775efe6b27161467e76d0ba145862802a65eefc8879086fc6f8", + "sha256:68c362848d9fb71d3c3e5f43c09974a0ae319144634e7a47db62f0f2a54a7fa7", + "sha256:6c1f3c6f6635e611d58e467bf4371883568f0de9ccc4606f17048142dec14a1f", + "sha256:b213d4a02eec4ddf622f4d2fbc539f062af3788d1f332f028a2e19c42da53f15", + "sha256:bb27d4e7805a7de0e35bd0cb1411bc85f807968b2b0539597a49a23b00a622ae", + "sha256:c9d414512eaa417aadae7758bc118868cd2396b0e6138c1dd4fda96679c079d3", + "sha256:f0937165d1e25477b01081c4763d2d9cdc3b18af69cb259dd4f640c9b900fe5e", + "sha256:fb96a6e2c11059ecf84e6741a319f93f683e440e341d4489c9b161eca251cf2a", + "sha256:fc71d2d6ae56a091a8d94f33ec9d0f2001d1cb1db423d8b4355debfe9ce689b7" ], "markers": "implementation_name == 'cpython'", - "version": "==1.3.1" + "version": "==1.3.4" }, "wrapt": { "hashes": [ From 1fdc2e6ba9dabcc2b6a934b848a2799b9b0cd519 Mon Sep 17 00:00:00 2001 From: Daniel Jiang Date: Fri, 19 Apr 2019 18:44:24 +0800 Subject: [PATCH 6/7] Provide API to generate CLI secret This commit provide an API to allow a user that is onboarded via OIDC authn update his CLI secret. Signed-off-by: Daniel Jiang --- docs/swagger.yaml | 282 ++++++++++-------- .../postgresql/0004_1.8.0_schema.up.sql | 2 +- src/common/dao/oidc_user.go | 13 +- src/common/dao/oidc_user_test.go | 8 +- src/core/api/user.go | 60 +++- src/core/router.go | 1 + 6 files changed, 230 insertions(+), 136 deletions(-) diff --git a/docs/swagger.yaml b/docs/swagger.yaml index bf0c950bf..23ce6dfa0 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -903,7 +903,7 @@ paths: '401': description: Don't have authority to change password. Please check login status. '403': - description: The caller does not have permission to update the password of the user with given ID, or the old password in request body is not correct. + description: The caller does not have permission to update the password of the user with given ID, or the old password in request body is not correct. '500': description: Unexpected internal errors. '/users/{user_id}/sysadmin': @@ -940,6 +940,44 @@ paths: description: User ID does not exist. '500': description: Unexpected internal errors. + '/users/{user_id}/gen_cli_secret': + post: + summary: Generate new CLI secret for a user. + description: | + This endpoint let user generate a new CLI secret for himself. This API only works when auth mode is set to 'OIDC'. + Once this API returns with successful status, the old secret will be invalid, as there will be only one CLI secret + for a user. The new secret will be returned in the response. + parameters: + - name: user_id + in: path + type: integer + format: int + required: true + description: User ID + tags: + - Products + responses: + '200': + description: The secret is successfully generated. + schema: + type: object + properties: + secret: + type: string + description: The new secret + '400': + description: Invalid user ID. Or user is not onboarded via OIDC authentication. + '401': + description: User need to log in first. + '403': + description: Non-admin user can only generate the cli secret of himself. + '404': + description: User ID does not exist. + '412': + description: The auth mode of the system is not "oidc_auth", or the user is not onboarded via OIDC AuthN. + '500': + description: Unexpected internal errors. + /repositories: get: summary: Get repositories accompany with relevant project and repo name. @@ -1492,7 +1530,7 @@ paths: get: summary: Get recent logs of the projects which the user is a member of description: | - This endpoint let user see the recent operation logs of the projects which he is member of + This endpoint let user see the recent operation logs of the projects which he is member of parameters: - name: username in: query @@ -1624,7 +1662,7 @@ paths: '500': description: Unexpected internal errors. /replication/executions/{id}: - get: + get: summary: Get the execution of the replication. description: | This endpoint is for user to get one execution of the replication. @@ -1654,7 +1692,7 @@ paths: $ref: '#/responses/UnsupportedMediaType' '500': description: Unexpected internal errors. - put: + put: summary: Stop the execution of the replication. description: | This endpoint is for user to stop one execution of the replication. @@ -1683,7 +1721,7 @@ paths: '500': description: Unexpected internal errors. /replication/executions/{id}/tasks: - get: + get: summary: Get the task list of one execution. description: | This endpoint is for user to get the task list of one execution. @@ -1714,7 +1752,7 @@ paths: '500': description: Unexpected internal errors. /replication/executions/{id}/tasks/{task_id}/log: - get: + get: summary: Get the log of one task. description: | This endpoint is for user to get the log of one task. @@ -1884,14 +1922,14 @@ paths: description: | Delete the replication policy specified by ID. parameters: - - name: id - in: path - type: integer - format: int64 - required: true - description: Replication policy ID + - name: id + in: path + type: integer + format: int64 + required: true + description: Replication policy ID tags: - - Products + - Products responses: '200': $ref: '#/responses/OK' @@ -2297,18 +2335,18 @@ paths: description: | This endpoint let user list namespaces of registry according to query. parameters: - - name: id - in: path - type: integer - required: true - description: The registry ID. - - name: name - in: query - type: string - required: false - description: The name of namespace. + - name: id + in: path + type: integer + required: true + description: The registry ID. + - name: name + in: query + type: string + required: false + description: The name of namespace. tags: - - Products + - Products responses: '200': description: Success @@ -2328,7 +2366,7 @@ paths: post: summary: Sync repositories from registry to DB. description: | - This endpoint is for syncing all repositories of registry with database. + This endpoint is for syncing all repositories of registry with database. tags: - Products responses: @@ -2392,7 +2430,7 @@ paths: post: summary: Ping available ldap service. description: | - This endpoint ping the available ldap service for test related configuration parameters. + This endpoint ping the available ldap service for test related configuration parameters. parameters: - name: ldapconf in: body @@ -2476,7 +2514,7 @@ paths: post: summary: Import selected available ldap users. description: | - This endpoint adds the selected available ldap users to harbor based on related configuration parameters from the system. System will try to guess the user email address and realname, add to harbor user information. + This endpoint adds the selected available ldap users to harbor based on related configuration parameters from the system. System will try to guess the user email address and realname, add to harbor user information. If have errors when import user, will return the list of importing failed uid and the failed reason. parameters: - name: uid_list @@ -2661,7 +2699,7 @@ paths: '200': description: Get gc results successfully. schema: - $ref: '#/definitions/GCResult' + $ref: '#/definitions/GCResult' '401': description: User need to log in first. '403': @@ -2685,7 +2723,7 @@ paths: '200': description: Get successfully. schema: - type: string + type: string '400': description: Illegal format of provided ID value. '401': @@ -2706,7 +2744,7 @@ paths: '200': description: Get gc's schedule. schema: - $ref: '#/definitions/AdminJobSchedule' + $ref: '#/definitions/AdminJobSchedule' '401': description: User need to log in first. '403': @@ -2768,12 +2806,12 @@ paths: summary: Get scan_all's schedule. description: This endpoint is for getting a schedule for the scan all job, which scans all of images in Harbor. tags: - - Products + - Products responses: '200': description: Get a schedule for the scan all job, which scans all of images in Harbor. schema: - $ref: '#/definitions/AdminJobSchedule' + $ref: '#/definitions/AdminJobSchedule' '401': description: User need to log in first. '403': @@ -2785,14 +2823,14 @@ paths: description: | This endpoint is for updating the schedule of scan all job, which scans all of images in Harbor. parameters: - - name: schedule - in: body - required: true - schema: - $ref: '#/definitions/AdminJobSchedule' - description: Updates the schedule of scan all job, which scans all of images in Harbor. + - name: schedule + in: body + required: true + schema: + $ref: '#/definitions/AdminJobSchedule' + description: Updates the schedule of scan all job, which scans all of images in Harbor. tags: - - Products + - Products responses: '200': description: Updated scan_all's schedule successfully. @@ -2809,14 +2847,14 @@ paths: description: | This endpoint is for creating a schedule or a manual trigger for the scan all job, which scans all of images in Harbor. parameters: - - name: schedule - in: body - required: true - schema: - $ref: '#/definitions/AdminJobSchedule' - description: Create a schedule or a manual trigger for the scan all job. + - name: schedule + in: body + required: true + schema: + $ref: '#/definitions/AdminJobSchedule' + description: Create a schedule or a manual trigger for the scan all job. tags: - - Products + - Products responses: '200': description: Updated scan_all's schedule successfully. @@ -2876,7 +2914,7 @@ paths: post: summary: Test connection and authentication with email server. description: | - Test connection and authentication with email server. + Test connection and authentication with email server. parameters: - name: settings in: body @@ -2937,7 +2975,7 @@ paths: schema: type: array items: - $ref: '#/definitions/ChartInfoEntry' + $ref: '#/definitions/ChartInfoEntry' '401': $ref: '#/definitions/UnauthorizedChartAPIError' '403': @@ -3289,15 +3327,15 @@ paths: summary: Get all robot accounts of specified project description: Get all robot accounts of specified project parameters: - - name: project_id - in: path - type: integer - format: int64 - required: true - description: Relevant project ID. + - name: project_id + in: path + type: integer + format: int64 + required: true + description: Relevant project ID. tags: - - Products - - Robot Account + - Products + - Robot Account responses: '200': description: Get project robot accounts successfully. @@ -3319,21 +3357,21 @@ paths: summary: Create a robot account for project description: Create a robot account for project tags: - - Products - - Robot Account + - Products + - Robot Account parameters: - - name: project_id - in: path - type: integer - format: int64 - required: true - description: Relevant project ID. - - name: robot - in: body - description: Request body of creating a robot account. - required: true - schema: - $ref: '#/definitions/RobotAccountCreate' + - name: project_id + in: path + type: integer + format: int64 + required: true + description: Relevant project ID. + - name: robot + in: body + description: Request body of creating a robot account. + required: true + schema: + $ref: '#/definitions/RobotAccountCreate' responses: '201': description: Project member created successfully. @@ -3354,21 +3392,21 @@ paths: summary: Return the infor of the specified robot account. description: Return the infor of the specified robot account. tags: - - Products - - Robot Account + - Products + - Robot Account parameters: - - name: project_id - in: path - type: integer - format: int64 - required: true - description: Relevant project ID. - - name: robot_id - in: path - type: integer - format: int64 - required: true - description: The ID of robot account. + - name: project_id + in: path + type: integer + format: int64 + required: true + description: Relevant project ID. + - name: robot_id + in: path + type: integer + format: int64 + required: true + description: The ID of robot account. responses: '200': description: Robot account information. @@ -3386,27 +3424,27 @@ paths: summary: Update status of robot account. description: Used to disable/enable a specified robot account. tags: - - Products - - Robot Account + - Products + - Robot Account parameters: - - name: project_id - in: path - type: integer - format: int64 - required: true - description: Relevant project ID. - - name: robot_id - in: path - type: integer - format: int64 - required: true - description: The ID of robot account. - - name: robot - in: body - description: Request body of enable/disable a robot account. - required: true - schema: - $ref: '#/definitions/RobotAccountUpdate' + - name: project_id + in: path + type: integer + format: int64 + required: true + description: Relevant project ID. + - name: robot_id + in: path + type: integer + format: int64 + required: true + description: The ID of robot account. + - name: robot + in: body + description: Request body of enable/disable a robot account. + required: true + schema: + $ref: '#/definitions/RobotAccountUpdate' responses: '200': description: Robot account has been modified success. @@ -3416,21 +3454,21 @@ paths: summary: Delete the specified robot account description: Delete the specified robot account tags: - - Products - - Robot Account + - Products + - Robot Account parameters: - - name: project_id - in: path - type: integer - format: int64 - required: true - description: Relevant project ID. - - name: robot_id - in: path - type: integer - format: int64 - required: true - description: The ID of robot account. + - name: project_id + in: path + type: integer + format: int64 + required: true + description: Relevant project ID. + - name: robot_id + in: path + type: integer + format: int64 + required: true + description: The ID of robot account. responses: '200': description: The specified robot account is successfully deleted. @@ -4603,13 +4641,13 @@ definitions: description: Total count of chart versions latest_version: type: string - description: latest version of chart + description: latest version of chart created: type: string description: The created time of chart updated: type: string - description: The created time of chart + description: The created time of chart icon: type: string description: The icon path of chart @@ -4818,7 +4856,7 @@ definitions: properties: status: type: string - description: The overall health status. It is "healthy" only when all the components' status are "healthy" + description: The overall health status. It is "healthy" only when all the components' status are "healthy" components: type: array items: @@ -4829,7 +4867,7 @@ definitions: properties: name: type: string - description: The component name + description: The component name status: type: string description: The health status of component diff --git a/make/migrations/postgresql/0004_1.8.0_schema.up.sql b/make/migrations/postgresql/0004_1.8.0_schema.up.sql index 37cd217b6..98fd25561 100644 --- a/make/migrations/postgresql/0004_1.8.0_schema.up.sql +++ b/make/migrations/postgresql/0004_1.8.0_schema.up.sql @@ -38,7 +38,7 @@ CREATE TABLE oidc_user ( UNIQUE (subiss) ); -CREATE TRIGGER odic_user_update_time_at_modtime BEFORE UPDATE ON oidc_user FOR EACH ROW EXECUTE PROCEDURE update_update_time_at_column(); +CREATE TRIGGER oidc_user_update_time_at_modtime BEFORE UPDATE ON oidc_user FOR EACH ROW EXECUTE PROCEDURE update_update_time_at_column(); /*add master role*/ INSERT INTO role (role_code, name) VALUES ('DRWS', 'master'); diff --git a/src/common/dao/oidc_user.go b/src/common/dao/oidc_user.go index 6045cff36..7367f1b37 100644 --- a/src/common/dao/oidc_user.go +++ b/src/common/dao/oidc_user.go @@ -92,10 +92,17 @@ func GetOIDCUserByUserID(userID int) (*models.OIDCUser, error) { return &oidcUsers[0], nil } -// UpdateOIDCUser ... +// UpdateOIDCUser updates the OIDCUser based on the input parm, only the column "secret" and "token" can be updated func UpdateOIDCUser(oidcUser *models.OIDCUser) error { - oidcUser.UpdateTime = time.Now() - _, err := GetOrmer().Update(oidcUser) + cols := []string{"secret", "token"} + _, err := GetOrmer().Update(oidcUser, cols...) + return err +} + +// UpdateOIDCUserSecret updates the secret of the OIDC User. The secret in the input parm should be encrypted before +// calling this func +func UpdateOIDCUserSecret(oidcUser *models.OIDCUser) error { + _, err := GetOrmer().Update(oidcUser, "secret") return err } diff --git a/src/common/dao/oidc_user_test.go b/src/common/dao/oidc_user_test.go index 7ec303c9c..1b3c76bec 100644 --- a/src/common/dao/oidc_user_test.go +++ b/src/common/dao/oidc_user_test.go @@ -80,15 +80,13 @@ func TestOIDCUserMetaDaoMethods(t *testing.T) { ID: ou111.ID, UserID: ou111.UserID, SubIss: "newSub", + Secret: "newSecret", } require.Nil(t, UpdateOIDCUser(meta3)) oidcUser1Update, err := GetOIDCUserByID(ou111.ID) require.Nil(t, err) - assert.Equal(t, "newSub", oidcUser1Update.SubIss) - - user, err := GetUserBySubIss("new", "Sub") - require.Nil(t, err) - assert.Equal(t, "user111", user.Username) + assert.Equal(t, "QWE123123RT1", oidcUser1Update.SubIss) + assert.Equal(t, "newSecret", oidcUser1Update.Secret) // clear data defer func() { diff --git a/src/core/api/user.go b/src/core/api/user.go index 6c37a6d93..de5abc501 100644 --- a/src/core/api/user.go +++ b/src/core/api/user.go @@ -38,6 +38,7 @@ type UserAPI struct { SelfRegistration bool IsAdmin bool AuthMode string + secretKey string } type passwordReq struct { @@ -50,6 +51,10 @@ type userSearch struct { Username string `json:"username"` } +type secretResp struct { + Secret string `json:"secret"` +} + // Prepare validates the URL and parms func (ua *UserAPI) Prepare() { ua.BaseController.Prepare() @@ -61,6 +66,15 @@ func (ua *UserAPI) Prepare() { } ua.AuthMode = mode + if mode == common.OIDCAuth { + key, err := config.SecretKey() + if err != nil { + log.Errorf("failed to get secret key: %v", err) + ua.SendInternalServerError(fmt.Errorf("failed to get secret key: %v", err)) + return + } + ua.secretKey = key + } self, err := config.SelfRegistration() if err != nil { @@ -475,17 +489,53 @@ func (ua *UserAPI) ListUserPermissions() { return } -func (ua *UserAPI) getOIDCUserInfo() (*models.OIDCUser, error) { - key, err := config.SecretKey() - if err != nil { - return nil, err +// GenCLISecret generates a new CLI secret and replace the old one +func (ua *UserAPI) GenCLISecret() { + if ua.AuthMode != common.OIDCAuth { + ua.SendPreconditionFailedError(errors.New("the auth mode has to be oidc auth")) + return } + if ua.userID != ua.currentUserID && !ua.IsAdmin { + ua.SendForbiddenError(errors.New("")) + return + } + oidcData, err := dao.GetOIDCUserByUserID(ua.userID) + if err != nil { + log.Errorf("Failed to get OIDC User meta for user, id: %d, error: %v", ua.userID, err) + ua.SendInternalServerError(errors.New("failed to get OIDC meta data for user")) + return + } + if oidcData == nil { + log.Errorf("User is not onboarded via OIDC AuthN, user id: %d", ua.userID) + ua.SendPreconditionFailedError(errors.New("user is not onboarded via OIDC AuthN")) + return + } + + sec := utils.GenerateRandomString() + encSec, err := utils.ReversibleEncrypt(sec, ua.secretKey) + if err != nil { + log.Errorf("Failed to encrypt secret, error: %v", err) + ua.SendInternalServerError(errors.New("failed to encrypt secret")) + return + } + oidcData.Secret = encSec + err = dao.UpdateOIDCUserSecret(oidcData) + if err != nil { + log.Errorf("Failed to update secret in DB, error: %v", err) + ua.SendInternalServerError(errors.New("failed to update secret in DB")) + return + } + ua.Data["json"] = secretResp{sec} + ua.ServeJSON() +} + +func (ua *UserAPI) getOIDCUserInfo() (*models.OIDCUser, error) { o, err := dao.GetOIDCUserByUserID(ua.userID) if err != nil || o == nil { return nil, err } if len(o.Secret) > 0 { - p, err := utils.ReversibleDecrypt(o.Secret, key) + p, err := utils.ReversibleDecrypt(o.Secret, ua.secretKey) if err != nil { return nil, err } diff --git a/src/core/router.go b/src/core/router.go index ed3630200..d1beb12f6 100644 --- a/src/core/router.go +++ b/src/core/router.go @@ -53,6 +53,7 @@ func initRouters() { beego.Router("/api/users/:id([0-9]+)/password", &api.UserAPI{}, "put:ChangePassword") beego.Router("/api/users/:id/permissions", &api.UserAPI{}, "get:ListUserPermissions") beego.Router("/api/users/:id/sysadmin", &api.UserAPI{}, "put:ToggleUserAdminRole") + beego.Router("/api/users/:id/gen_cli_secret", &api.UserAPI{}, "post:GenCLISecret") beego.Router("/api/usergroups/?:ugid([0-9]+)", &api.UserGroupAPI{}) beego.Router("/api/ldap/ping", &api.LdapAPI{}, "post:Ping") beego.Router("/api/ldap/users/search", &api.LdapAPI{}, "get:Search") From 6b9584a71f21c59299d102d7c744f602b7a095ab Mon Sep 17 00:00:00 2001 From: danfengliu Date: Mon, 22 Apr 2019 15:47:43 +0800 Subject: [PATCH 7/7] Add retry and wait for keyword , Jenkins chart CI failed at 1 test case in rare occasion, the reason is lacking of wait and retry to wait. (#7466) Signed-off-by: danfengliu --- .../Harbor-Pages/Project-Repository.robot | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/tests/resources/Harbor-Pages/Project-Repository.robot b/tests/resources/Harbor-Pages/Project-Repository.robot index 5e7bb6cf9..23d4ad569 100644 --- a/tests/resources/Harbor-Pages/Project-Repository.robot +++ b/tests/resources/Harbor-Pages/Project-Repository.robot @@ -18,22 +18,18 @@ Resource ../../resources/Util.robot *** Keywords *** View Repo Scan Details - Click Element xpath=${first_repo_xpath} - Sleep 2 + Retry Element Click xpath=${first_repo_xpath} Capture Page Screenshot viewcve1.png - Wait Until Page Contains unknown - Wait Until Page Contains high - Wait Until Page Contains medium - Page Should Contain CVE - Sleep 2 - Click Element xpath=${build_history_btn} - Sleep 1 - Page Should Contain Element xpath=${build_history_data} + Retry Wait Until Page Contains unknown + Retry Wait Until Page Contains high + Retry Wait Until Page Contains medium + Retry Wait Until Page Contains CVE + Retry Element Click xpath=${build_history_btn} + Retry Wait Until Page Contains Element xpath=${build_history_data} View Scan Error Log - Page Should Contain View Log - Click Element xpath=${view_log_xpath} - Sleep 1 + Retry Wait Until Page Contains View Log + Retry Element Click xpath=${view_log_xpath} Capture Page Screenshot viewlog.png