diff --git a/.travis.yml b/.travis.yml index b0dd4c556..80a1df4a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -101,7 +101,7 @@ script: - docker ps - ./tests/notarytest.sh - - go run tests/startuptest.go https://localhost/ + - ./tests/startuptest.sh - go run tests/userlogintest.go -name ${HARBOR_ADMIN} -passwd ${HARBOR_ADMIN_PASSWD} # - sudo ./tests/testprepare.sh diff --git a/Makefile b/Makefile index b126a2316..719c23d05 100644 --- a/Makefile +++ b/Makefile @@ -390,9 +390,9 @@ down: [ $$CONTINUE = "y" ] || [ $$CONTINUE = "Y" ] || (echo "Exiting."; exit 1;) @echo "stoping harbor instance..." @if [ "$(NOTARYFLAG)" = "true" ] ; then \ - $(DOCKERCOMPOSECMD) -f $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME) -f $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSENOTARYFILENAME) down ; \ + $(DOCKERCOMPOSECMD) -f $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME) -f $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSENOTARYFILENAME) down -v ; \ else \ - $(DOCKERCOMPOSECMD) -f $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME) down ; \ + $(DOCKERCOMPOSECMD) -f $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME) down -v ; \ fi @echo "Done." diff --git a/make/common/templates/notary/notary-signer.crt b/make/common/templates/notary/notary-signer.crt index 9e9478998..1189dfd7b 100644 --- a/make/common/templates/notary/notary-signer.crt +++ b/make/common/templates/notary/notary-signer.crt @@ -1,63 +1,32 @@ -----BEGIN CERTIFICATE----- -MIIFBDCCAuygAwIBAgIJAMbWdVJcKhXYMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNV -BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEPMA0G -A1UECgwGRG9ja2VyMScwJQYDVQQDDB5Ob3RhcnkgSW50ZXJtZWRpYXRlIFRlc3Rp -bmcgQ0EwHhcNMTcwMTIzMDYwMzM3WhcNMTkwMjEyMDYwMzM3WjBbMQswCQYDVQQG -EwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDzANBgNV -BAoMBkRvY2tlcjEWMBQGA1UEAwwNbm90YXJ5LXNpZ25lcjCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBANhO8+K9xT6M9dQC90Hxs6bmTXWQzE5oV2kLeVKq -OjwAvGt6wBE2XJCAbTS3FORIOyoOVQDVCv2Pk2lZXGWqSrH8SY2umjRJIhPDiqN9 -V5M/gcmMm2EUgwmp2l4bsDk1MQ6GSbud5kjYGZcp9uXxAVO8tfLVLQF7ohJYqiex -JN+fZkQyxTgSqrI7MKK1pUvGX/fa6EXzpKwxTQPJXiG/ZQW0Pn+gdrz+/Cf0PcVy -V/Ghc2RR+WjKzqqAiDUJoEtKm/xQVRcSPbagVLCe0KZr7VmtDWnHsUv9ZB9BRNlI -lRVDOhVDCCcMu/zEtcxuH8ja7fafi5xNt6vCBmHuCXQtTUsCAwEAAaOBuTCBtjAf -BgNVHSMEGDAWgBQjgpNYJjU9Ei7nadpOhHm59FPiKTAMBgNVHRMBAf8EAjAAMB0G -A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCBaAwNwYD -VR0RBDAwLoINbm90YXJ5LXNpZ25lcoIMbm90YXJ5c2lnbmVygglsb2NhbGhvc3SH -BAp1BI4wHQYDVR0OBBYEFLv4/22eN7pe8IzCbL+gKr2i/o6VMA0GCSqGSIb3DQEB -CwUAA4ICAQBzBcFgcwtr7oNP7WPyG64mRXHFs1qGCoDZO3D2dZPF/vUKnyPWI6+i -Ozu1Lmvd6QUQ5C0m91D6RidKKy3ENz2MgUo8NNj3QY3XzassiLnNOtpo1ed6U3BG -2w05gaLTTFywnpOgPy180U6f5uNSHGxY/fq9dN+8YR/MqGOht74q36x0swkPegG/ -+0SLloKOJw1wBzZ4nCLmED08DWNnuNTAj5IIVjApzqZbTh4+z6H1lmN3b7XwmiWw -+y7Jx8k74h5JmqKQnV+3lN0DlCc1BCbtH2fbKOmAKeu4gMniw5FBo75wYrPIet+Z -E3G2Zg+T6fjTXAnLGT3S0RVn/CW1lLR6RgkoFgURRZoJyTWrg+1yu4ZOgEz+bot2 -/hMAr/fjo+Dd6ReFrgGkpTyWYtPhYusori1W8KW138CVrJmSs6p2ss1Ixh8uIOaQ -iFmlX/ZXXbvkz3FGQS9LfBdESO3MGjiJTcnXE0DTnXf6RmdlUfNwxsZbIliFa0TQ -E/JjIJYQzWmtkJbUdC02GUMjUJAM7SxmP7tU9CmMmjUI28Nno0XtPN2WsAszaiLh -JYLJCi7rqaLo0oZuaXVIrgBpQ0qEC1XXS5sCQL+xvMSYvke/rhwIPItWt7Ww/9yj -QDIi1nzzX86lbKd095pNX4sUfFx6j4caR8iENgJDfWnqynAzj1Y21A== ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -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 -XJCKYD/1jYIB +MIIFdjCCA14CCQCeVwANSZmmiDANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UEBhMC +VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExEjAQBgNVBAcMCVBhbG8gQWx0bzEVMBMG +A1UECgwMVk13YXJlLCBJbmMuMQ8wDQYDVQQLDAZIYXJib3IxJDAiBgNVBAMMG1Nl +bGYtc2lnbmVkIGJ5IFZNd2FyZSwgSW5jLjAeFw0xNzAzMjQwNTMyMDBaFw0yNzAz +MjIwNTMyMDBaMHUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIw +EAYDVQQHDAlQYWxvIEFsdG8xFTATBgNVBAoMDFZNd2FyZSwgSW5jLjEPMA0GA1UE +CwwGSGFyYm9yMRUwEwYDVQQDDAxub3RhcnlzaWduZXIwggIiMA0GCSqGSIb3DQEB +AQUAA4ICDwAwggIKAoICAQC6TV2RCoH8d1g6xFvDo4FL9v+pGLe5+bu9ryjTaLbN +dH/Cmf5/8WrmgJ3vG2Ksk796J7qsVddwvQkZn6NwDm2Tm+ETMCG85yEA3jl4Kr9R +XfWHYWEavv0vsq6M+bUSSq7VJAhgk4wfx6qJBnFX2qKpODeYLHaHxU1EnIXrStNf +IqR4Eu0Xre8jAkzrDdaFy/KnX4HGgNdz413CXzBCKEuu3VJj07ZvonnTzOgoLvh8 ++PCoQ2M4OBPT9gHqUov1I8nWnrjc+HuM1BW3YIGCB5TV9x0Y7hjvkr4E38gbJURj +uDwg8jof4lMRmU/FHXFLt1ucGwNFUJdPwI7dyEKRA03Lr7htfP5sa9tmv3L93dKD +po1gW1LsfiM3Cur5jARM/hBA+eYJr12Laf9oL59r8JmweqF3zRSwGSY336XoR/Fv +/PAFs9vfKKWZp0uiRtuY9JZNRTF8trnfNf1957bND+DS2HWPmWkw4yK6CGa0s55X +adiDt4gDFvKjl68dBWZoHutY+cZy/hK1D5uqagcX1kzbr/Pzy1gsq9FBBwaTJqBu +YIAsSuzP+7NNZXoPd3rg13V93pbZr8eQN5VOQIBZK83xZEtHSJBEdUSuBOo3JS7j +/rjEnspRqOI4soFnx1vaK0TrRyzJ5KBOuGpW4u8/ZUdIq8KIE30Mj/XI/sgAPr5j +UQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQBjqYBm/FRqyMH2hnHA0TMXY/WPufJ8 +TX10daELCAYJCEETXmUt1i7dnFxdAZXTnHENHdNYiS4nGBfqMLmODtcAamcv6Dcl +JnyQPt3QlCDPKkcHgz3y4tvDDx6M5rFWYzN9QLiWAYrunIk1R4Jj7FODrM6/NODE +0Mz1czWfsmLfX/jF80SsxnY1DCLKGgo6/RID3xTp4eIMboxCfeH2/yDA+6YPyYbV +Si4ccwo9Foq0IYU8bimPNTyBQ0N+8ajcn328ql6aazmr894Ch5pWA3Qxaa98FcKS +zokBvmmCuvCJ9HOmxKWdFEhSRS9GWxn7wg78UIlLP/8RfUrsecBJHgyhWRA7Qs3K +keiG68Zrhn456IdMxjCZXgJ7gAAe77n4Cz8sFEHAvnAg9JLNEHuEBV5H1Hb7TzET +k0lPiEY78QjutOpqHsWiagqSjlGEMqKI9c8WxXHh9030T/6NnWkdXFo+4HaEZEpp +0JryASS53B5SwLIPrn0Y2/io/kRgbglGktPt6Ex0DwW3f96lcz3me34Nw+HOYYnz +b0cz7JqJZgFXfEnykic3IwZs7m7Xrl9B/vvaVub9Fb5LQ7rIzrO7VkoILov/G41B +Pd4/kagjXDTWd+UBMvZF6YGjr+TUZi5ooi7bvQ3X6N9WNYKW4a1DOokz9janStiL +MrTKyOEOBi0Aew== -----END CERTIFICATE----- diff --git a/make/common/templates/notary/notary-signer.key b/make/common/templates/notary/notary-signer.key index 2db6e2ce9..3973cec7b 100644 --- a/make/common/templates/notary/notary-signer.key +++ b/make/common/templates/notary/notary-signer.key @@ -1,28 +1,52 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEA2E7z4r3FPoz11AL3QfGzpuZNdZDMTmhXaQt5Uqo6PAC8a3rA -ETZckIBtNLcU5Eg7Kg5VANUK/Y+TaVlcZapKsfxJja6aNEkiE8OKo31Xkz+ByYyb -YRSDCanaXhuwOTUxDoZJu53mSNgZlyn25fEBU7y18tUtAXuiEliqJ7Ek359mRDLF -OBKqsjsworWlS8Zf99roRfOkrDFNA8leIb9lBbQ+f6B2vP78J/Q9xXJX8aFzZFH5 -aMrOqoCINQmgS0qb/FBVFxI9tqBUsJ7QpmvtWa0NacexS/1kH0FE2UiVFUM6FUMI -Jwy7/MS1zG4fyNrt9p+LnE23q8IGYe4JdC1NSwIDAQABAoIBAHykYhyRxYrZpv3Y -B6pUIHVX1+Ka4V98+IFrPynHNW9F7UzxmqNQc95AYq0xojQ4+v6s64ZjPMYHaaYW -/AsJKamN+sRNjEX8rko9LzIuE7yhp6QABbjXHPsAiPgZdF5CrFX2Q558yinHfFeC -sualDWK3JxEajaiBGU8BEGt2xAymuWACGblrM1aAEZa8B84TW3CzzcdyzAkn8P3e -piJCe+DWMc33441r0KlV5GruwF9ewXiWzZtXAOiP/0xEDICFdlFWbO39myMpxDdU -Y0uZ+zmn2G3gz2tz25thH0Wl7mDQ3AA0VlHurgPBBEekeZPQmjiKW+F4slCzXvuy -kW/urIECgYEA/LhY+OWlZVXzIEly7z1/cU9/WImqTs2uRKDeQHMwZrd7D9BXkJuQ -jPN+jZlMYBBrxoaCywbMrgB80Z3MgGHaSx9OIDEZmaxyuQv0zQJCMogysYkbCcaD -mHYnyAf7OXa708Z168WAisEhrwa/DXBn3/hPoBkrbMsuPF/J+tEP7lsCgYEA2x2g -86SitgPVeNV3iuZ6D/SV0QIbDWOYoST2GQn2LnfALIOrzpXRClOSQZ2pGtg9gYo1 -owUyyOSv2Fke93p3ufHv3Gqvjl55lzBVV0siHkEXwHcol36DDGQcskVnXJqaL3IF -tiOisuJS9A7PW7gEi0miyGzzB/kh/IEWHKqLL9ECgYEAoBOFB+MuqMmQftsHWlLx -7qwUVdidb90IjZ/4J4rPFcESyimFzas8HIv/lWGM5yx/l/iL0F42N+FHLt9tMcTJ -qNvjeLChLp307RGNtm2/0JJEyf+2iLKdmGz/Nc0YbIWw46vJ9dXcXgeHdn4ndjPF -GDEI/rfysa7hUoy6O41BMhECgYBPJsLPgHdufLAOeD44pM0PGnFMERCoo4OtImbr -4JdXbdazvdTASYo7yriYj1VY5yhAtSZu/x+7RjDnXDo9d7XsK6NT4g4Mxb/yh3ks -kW1/tE/aLLEzGHZKcZeUJlISN57e6Ld7dh/9spf4pajuHuk1T6JH+GNKTAqk5hSQ -wmKJIQKBgCGBWGvJrCeT5X9oHdrlHj2YoKvIIG1eibagcjcKemD7sWzi7Q4P7JIo -xeX8K1WVxdBpo4/RiQcGFmwSmSUKwwr1dO00xtjxIl7ip4DU+WAM7CdmcOIOMbr4 -rP9T/wy1ZBkERCIw2ElybTzB8yuOlNLuOMhUeU55xUMFNYYrWEp2 ------END RSA PRIVATE KEY----- - +-----BEGIN PRIVATE KEY----- +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 +tajKl+aoc+CDxUYbilzhhKetWWF/cJY= +-----END PRIVATE KEY----- diff --git a/make/docker-compose.tpl b/make/docker-compose.tpl index decf381ee..302c15dd1 100644 --- a/make/docker-compose.tpl +++ b/make/docker-compose.tpl @@ -118,6 +118,7 @@ services: ports: - 80:80 - 443:443 + - 4443:4443 depends_on: - mysql - registry diff --git a/make/harbor.cfg b/make/harbor.cfg index 844daa49e..8c9575585 100644 --- a/make/harbor.cfg +++ b/make/harbor.cfg @@ -20,19 +20,10 @@ max_job_workers = 3 #Determine whether or not to generate certificate for the registry's token. #If the value is on, the prepare script creates new root cert and private key -#for generating token to access the registry. If the value is off, a key/certificate must -#be supplied for token generation. +#for generating token to access the registry. If the value is off the default key/cert will be used. +#This flag also controls the creation of the notary signer's cert. customize_crt = on -#Information of your organization for certificate -crt_country = CN -crt_state = State -crt_location = CN -crt_organization = organization -crt_organizationalunit = organizational unit -crt_commonname = example.com -crt_email = example@example.com - #The path of cert and key files for nginx, they are applied only the protocol is set to https ssl_cert = /data/cert/server.crt ssl_cert_key = /data/cert/server.key diff --git a/make/install.sh b/make/install.sh index 54c2b10be..def0189f0 100755 --- a/make/install.sh +++ b/make/install.sh @@ -166,13 +166,13 @@ then if [ -n "$(docker-compose -f docker-compose.yml -f docker-compose.notary.yml ps -q)" ] then note "stopping existing Harbor instance ..." - docker-compose -f docker-compose.yml -f docker-compose.notary.yml down + docker-compose -f docker-compose.yml -f docker-compose.notary.yml down -v fi else if [ -n "$(docker-compose -f docker-compose.yml ps -q)" ] then note "stopping existing Harbor instance ..." - docker-compose -f docker-compose.yml down + docker-compose -f docker-compose.yml down -v fi fi echo "" diff --git a/make/prepare b/make/prepare index df52b6662..9d26ed54c 100755 --- a/make/prepare +++ b/make/prepare @@ -135,13 +135,6 @@ if protocol == "https": cert_path = rcp.get("configuration", "ssl_cert") cert_key_path = rcp.get("configuration", "ssl_cert_key") customize_crt = rcp.get("configuration", "customize_crt") -crt_country = rcp.get("configuration", "crt_country") -crt_state = rcp.get("configuration", "crt_state") -crt_location = rcp.get("configuration", "crt_location") -crt_organization = rcp.get("configuration", "crt_organization") -crt_organizationalunit = rcp.get("configuration", "crt_organizationalunit") -crt_commonname = rcp.get("configuration", "crt_commonname") -crt_email = rcp.get("configuration", "crt_email") max_job_workers = rcp.get("configuration", "max_job_workers") token_expiration = rcp.get("configuration", "token_expiration") verify_remote_cert = rcp.get("configuration", "verify_remote_cert") @@ -273,44 +266,43 @@ def stat_decorator(func): @stat_decorator def create_root_cert(subj, key_path="./k.key", cert_path="./cert.crt"): - rc = subprocess.call(["openssl", "genrsa", "-out", key_path, "4096"]) + rc = subprocess.call(["openssl", "genrsa", "-out", key_path, "4096"], stdout=FNULL, stderr=subprocess.STDOUT) if rc != 0: return rc return subprocess.call(["openssl", "req", "-new", "-x509", "-key", key_path,\ - "-out", cert_path, "-days", "3650", "-subj", subj]) + "-out", cert_path, "-days", "3650", "-subj", subj], stdout=FNULL, stderr=subprocess.STDOUT) @stat_decorator def create_cert(subj, ca_key, ca_cert, key_path="./k.key", cert_path="./cert.crt"): cert_dir = os.path.dirname(cert_path) csr_path = os.path.join(cert_dir, "tmp.csr") rc = subprocess.call(["openssl", "req", "-newkey", "rsa:4096", "-nodes","-sha256","-keyout", key_path,\ - "-out", csr_path, "-subj", subj]) + "-out", csr_path, "-subj", subj], stdout=FNULL, stderr=subprocess.STDOUT) if rc != 0: return rc return subprocess.call(["openssl", "x509", "-req", "-days", "3650", "-in", csr_path, "-CA", \ - ca_cert, "-CAkey", ca_key, "-CAcreateserial", "-out", cert_path]) + ca_cert, "-CAkey", ca_key, "-CAcreateserial", "-out", cert_path], stdout=FNULL, stderr=subprocess.STDOUT) -def openssl_is_installed(stat): - if stat == 0: - return True - else: +def openssl_installed(): + shell_stat = subprocess.check_call(["which", "openssl"], stdout=FNULL, stderr=subprocess.STDOUT) + if shell_stat != 0: print("Cannot find openssl installed in this computer\nUse default SSL certificate file") return False + return True + -if customize_crt == 'on': +if customize_crt == 'on' and openssl_installed(): shell_stat = subprocess.check_call(["which", "openssl"], stdout=FNULL, stderr=subprocess.STDOUT) - if openssl_is_installed(shell_stat): - empty_subj = "/C=/ST=/L=/O=/CN=/" - private_key_pem = os.path.join(config_dir, "ui", "private_key.pem") - root_crt = os.path.join(config_dir, "registry", "root.crt") - create_root_cert(empty_subj, key_path=private_key_pem, cert_path=root_crt) + empty_subj = "/C=/ST=/L=/O=/CN=/" + private_key_pem = os.path.join(config_dir, "ui", "private_key.pem") + root_crt = os.path.join(config_dir, "registry", "root.crt") + create_root_cert(empty_subj, key_path=private_key_pem, cert_path=root_crt) else: print("Copied configuration file: %s" % ui_config_dir + "private_key.pem") shutil.copyfile(os.path.join(templates_dir, "ui", "private_key.pem"), os.path.join(ui_config_dir, "private_key.pem")) print("Copied configuration file: %s" % registry_config_dir + "root.crt") shutil.copyfile(os.path.join(templates_dir, "registry", "root.crt"), os.path.join(registry_config_dir, "root.crt")) -FNULL.close() if args.notary_mode: notary_config_dir = prep_conf_dir(config_dir, "notary") notary_temp_dir = os.path.join(templates_dir, "notary") @@ -318,13 +310,12 @@ if args.notary_mode: if os.path.exists(os.path.join(notary_config_dir, "mysql-initdb.d")): shutil.rmtree(os.path.join(notary_config_dir, "mysql-initdb.d")) shutil.copytree(os.path.join(notary_temp_dir, "mysql-initdb.d"), os.path.join(notary_config_dir, "mysql-initdb.d")) - #TODO:generate certs? - if customize_crt == 'on': + if customize_crt == 'on' and openssl_installed(): temp_cert_dir = os.path.join(base_dir, "cert_tmp") if not os.path.exists(temp_cert_dir): os.makedirs(temp_cert_dir) - ca_subj = "/C=US/ST=California/L=Palo Alto/O=Vmware/CN=Self Signed CA/" - cert_subj = "/C=US/ST=California/L=Palo Alto/O=Vmware/CN=notarysigner/" + ca_subj = "/C=US/ST=California/L=Palo Alto/O=VMware, Inc./OU=Harbor/CN=Self-signed by VMware, Inc." + cert_subj = "/C=US/ST=California/L=Palo Alto/O=VMware, Inc./OU=Harbor/CN=notarysigner" signer_ca_cert = os.path.join(temp_cert_dir, "notary-signer-ca.crt") signer_ca_key = os.path.join(temp_cert_dir, "notary-signer-ca.key") signer_cert_path = os.path.join(temp_cert_dir, "notary-signer.crt") @@ -355,6 +346,6 @@ if args.notary_mode: default_alias = ''.join(random.choice(string.ascii_letters) for i in range(8)) render(os.path.join(notary_temp_dir, "signer_env"), os.path.join(notary_config_dir, "signer_env"), alias = default_alias) - +FNULL.close() print("The configuration files are ready, please use docker-compose to start the service.") diff --git a/src/ui/views/reset-password-mail.tpl b/src/ui/views/reset-password-mail.tpl new file mode 100644 index 000000000..31fb438ef --- /dev/null +++ b/src/ui/views/reset-password-mail.tpl @@ -0,0 +1,21 @@ + + + + +

Please click this link to reset your password:

+ {{.URL}}/reset_password?reset_uuid={{.UUID}} + + diff --git a/src/ui_ng/src/app/harbor-routing.module.ts b/src/ui_ng/src/app/harbor-routing.module.ts index 967a3c402..583071bfb 100644 --- a/src/ui_ng/src/app/harbor-routing.module.ts +++ b/src/ui_ng/src/app/harbor-routing.module.ts @@ -76,7 +76,10 @@ const harborRoutes: Routes = [ }, { path: 'tags/:id/:repo', - component: TagRepositoryComponent + component: TagRepositoryComponent, + resolve: { + projectResolver: ProjectRoutingResolver + } }, { path: 'projects/:id', diff --git a/src/ui_ng/src/app/log/audit-log.service.ts b/src/ui_ng/src/app/log/audit-log.service.ts index 320d589b5..28be16021 100644 --- a/src/ui_ng/src/app/log/audit-log.service.ts +++ b/src/ui_ng/src/app/log/audit-log.service.ts @@ -1,8 +1,6 @@ import { Injectable } from '@angular/core'; import { Http, Headers, RequestOptions } from '@angular/http'; -import { BaseService } from '../service/base.service'; - import { AuditLog } from './audit-log'; import { Observable } from 'rxjs/Observable'; @@ -13,7 +11,7 @@ import 'rxjs/add/observable/throw'; export const logEndpoint = "/api/logs"; @Injectable() -export class AuditLogService extends BaseService { +export class AuditLogService { private httpOptions = new RequestOptions({ headers: new Headers({ "Content-Type": 'application/json', @@ -21,9 +19,7 @@ export class AuditLogService extends BaseService { }) }); - constructor(private http: Http) { - super(); - } + constructor(private http: Http) {} listAuditLogs(queryParam: AuditLog): Observable { return this.http @@ -36,12 +32,12 @@ export class AuditLogService extends BaseService { username: queryParam.username }) .map(response => response) - .catch(error => this.handleError(error)); + .catch(error => Observable.throw(error)); } getRecentLogs(lines: number): Observable { return this.http.get(logEndpoint + "?lines=" + lines, this.httpOptions) .map(response => response.json() as AuditLog[]) - .catch(error => this.handleError(error)); + .catch(error => Observable.throw(error)); } } \ No newline at end of file diff --git a/src/ui_ng/src/app/project/create-project/create-project.component.html b/src/ui_ng/src/app/project/create-project/create-project.component.html index 725f538a6..785ba7fe9 100644 --- a/src/ui_ng/src/app/project/create-project/create-project.component.html +++ b/src/ui_ng/src/app/project/create-project/create-project.component.html @@ -31,6 +31,6 @@ diff --git a/src/ui_ng/src/app/project/list-project/list-project.component.html b/src/ui_ng/src/app/project/list-project/list-project.component.html index fa6074706..c04437c00 100644 --- a/src/ui_ng/src/app/project/list-project/list-project.component.html +++ b/src/ui_ng/src/app/project/list-project/list-project.component.html @@ -1,9 +1,9 @@ {{'PROJECT.NAME' | translate}} {{'PROJECT.PUBLIC_OR_PRIVATE' | translate}} + {{'PROJECT.ROLE' | translate}} {{'PROJECT.REPO_COUNT'| translate}} {{'PROJECT.CREATION_TIME' | translate}} - {{'PROJECT.DESCRIPTION' | translate}} @@ -12,9 +12,9 @@ {{p.name}} {{ (p.public === 1 ? 'PROJECT.PUBLIC' : 'PROJECT.PRIVATE') | translate}} + {{roleInfo[p.current_user_role_id] | translate}} {{p.repo_count}} {{p.creation_time}} - {{p.description}} {{totalRecordCount || (projects ? projects.length : 0)}} {{'PROJECT.ITEMS' | translate}} diff --git a/src/ui_ng/src/app/project/list-project/list-project.component.ts b/src/ui_ng/src/app/project/list-project/list-project.component.ts index c4a5895cb..1a4c8b5ea 100644 --- a/src/ui_ng/src/app/project/list-project/list-project.component.ts +++ b/src/ui_ng/src/app/project/list-project/list-project.component.ts @@ -5,7 +5,7 @@ import { ProjectService } from '../project.service'; import { SessionService } from '../../shared/session.service'; import { SearchTriggerService } from '../../base/global-search/search-trigger.service'; -import { ListMode } from '../../shared/shared.const'; +import { ListMode, ProjectTypes, RoleInfo } from '../../shared/shared.const'; import { State } from 'clarity-angular'; @@ -24,6 +24,8 @@ export class ListProjectComponent implements OnInit { @Input() totalRecordCount: number; pageOffset: number = 1; + @Input() filteredType: string; + @Output() paginate = new EventEmitter(); @Output() toggle = new EventEmitter(); @@ -31,6 +33,8 @@ export class ListProjectComponent implements OnInit { @Input() mode: string = ListMode.FULL; + roleInfo = RoleInfo; + constructor( private session: SessionService, private router: Router, @@ -43,6 +47,10 @@ export class ListProjectComponent implements OnInit { return this.mode === ListMode.FULL && this.session.getCurrentUser() != null; } + get showRoleInfo(): boolean { + return this.listFullMode && this.filteredType === ProjectTypes[0]; + } + public get isSystemAdmin(): boolean { let account = this.session.getCurrentUser(); return account != null && account.has_admin_role > 0; diff --git a/src/ui_ng/src/app/project/member/add-member/add-member.component.html b/src/ui_ng/src/app/project/member/add-member/add-member.component.html index 844ddd209..55764ae35 100644 --- a/src/ui_ng/src/app/project/member/add-member/add-member.component.html +++ b/src/ui_ng/src/app/project/member/add-member/add-member.component.html @@ -36,6 +36,6 @@ diff --git a/src/ui_ng/src/app/project/member/member.component.html b/src/ui_ng/src/app/project/member/member.component.html index a0563db81..ac4a5ea5f 100644 --- a/src/ui_ng/src/app/project/member/member.component.html +++ b/src/ui_ng/src/app/project/member/member.component.html @@ -17,15 +17,15 @@ {{'MEMBER.NAME' | translate}} {{'MEMBER.ROLE' | translate}} - - - - - - + + + + + + - {{u.username}} - {{roleInfo[u.role_id] | translate}} + {{m.username}} + {{roleInfo[m.role_id] | translate}} {{ (members ? members.length : 0) }} {{'MEMBER.ITEMS' | translate}} diff --git a/src/ui_ng/src/app/project/member/member.component.ts b/src/ui_ng/src/app/project/member/member.component.ts index b13b04c3b..765f67ee6 100644 --- a/src/ui_ng/src/app/project/member/member.component.ts +++ b/src/ui_ng/src/app/project/member/member.component.ts @@ -15,6 +15,8 @@ import { ConfirmationDialogService } from '../../shared/confirmation-dialog/conf import { ConfirmationMessage } from '../../shared/confirmation-dialog/confirmation-message'; import { SessionService } from '../../shared/session.service'; +import { RoleInfo } from '../../shared/shared.const'; + import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/switchMap'; import 'rxjs/add/operator/catch'; @@ -22,7 +24,7 @@ import 'rxjs/add/operator/map'; import 'rxjs/add/observable/throw'; import { Subscription } from 'rxjs/Subscription'; -export const roleInfo: {} = { 1: 'MEMBER.PROJECT_ADMIN', 2: 'MEMBER.DEVELOPER', 3: 'MEMBER.GUEST' }; +import { Project } from '../../project/project'; @Component({ moduleId: module.id, @@ -31,31 +33,22 @@ export const roleInfo: {} = { 1: 'MEMBER.PROJECT_ADMIN', 2: 'MEMBER.DEVELOPER', }) export class MemberComponent implements OnInit, OnDestroy { - currentUser: SessionUser; members: Member[]; projectId: number; - roleInfo = roleInfo; + roleInfo = RoleInfo; private delSub: Subscription; @ViewChild(AddMemberComponent) addMemberComponent: AddMemberComponent; + currentUser: SessionUser; hasProjectAdminRole: boolean; constructor(private route: ActivatedRoute, private router: Router, private memberService: MemberService, private messageService: MessageService, private deletionDialogService: ConfirmationDialogService, - session: SessionService) { - //Get current user from registered resolver. - this.currentUser = session.getCurrentUser(); - let projectMembers: Member[] = session.getProjectMembers(); - if(this.currentUser && projectMembers) { - let currentMember = projectMembers.find(m=>m.user_id === this.currentUser.user_id); - if(currentMember) { - this.hasProjectAdminRole = (currentMember.role_name === 'projectAdmin'); - } - } - + private session: SessionService) { + this.delSub = deletionDialogService.confirmationConfirm$.subscribe(message => { if (message && message.state === ConfirmationState.CONFIRMED && @@ -82,8 +75,7 @@ export class MemberComponent implements OnInit, OnDestroy { error => { this.router.navigate(['/harbor', 'projects']); this.messageService.announceMessage(error.status, 'Failed to get project member with project ID:' + projectId, AlertType.DANGER); - } - ); + }); } ngOnDestroy() { @@ -97,6 +89,15 @@ export class MemberComponent implements OnInit, OnDestroy { this.projectId = +this.route.snapshot.parent.params['id']; console.log('Get projectId from route params snapshot:' + this.projectId); + this.currentUser = this.session.getCurrentUser(); + //Get current user from registered resolver. + let resolverData = this.route.snapshot.parent.data; + if(resolverData) { + this.hasProjectAdminRole = (resolverData['projectResolver']).has_project_admin_role; + } + + + this.retrieve(this.projectId, ''); } @@ -108,25 +109,27 @@ export class MemberComponent implements OnInit, OnDestroy { this.retrieve(this.projectId, ''); } - changeRole(userId: number, roleId: number) { - this.memberService - .changeMemberRole(this.projectId, userId, roleId) - .subscribe( - response => { - this.messageService.announceMessage(response, 'MEMBER.SWITCHED_SUCCESS', AlertType.SUCCESS); - console.log('Successful change role with user ' + userId + ' to roleId ' + roleId); - this.retrieve(this.projectId, ''); - }, - error => this.messageService.announceMessage(error.status, 'Failed to change role with user ' + userId + ' to roleId ' + roleId, AlertType.DANGER) - ); + changeRole(m: Member, roleId: number) { + if(m) { + this.memberService + .changeMemberRole(this.projectId, m.user_id, roleId) + .subscribe( + response => { + this.messageService.announceMessage(response, 'MEMBER.SWITCHED_SUCCESS', AlertType.SUCCESS); + console.log('Successful change role with user ' + m.user_id + ' to roleId ' + roleId); + this.retrieve(this.projectId, ''); + }, + error => this.messageService.announceMessage(error.status, 'Failed to change role with user ' + m.user_id + ' to roleId ' + roleId, AlertType.DANGER) + ); + } } - deleteMember(userId: number) { + deleteMember(m: Member) { let deletionMessage: ConfirmationMessage = new ConfirmationMessage( 'MEMBER.DELETION_TITLE', 'MEMBER.DELETION_SUMMARY', - userId + "", - userId, + m.username, + m.user_id, ConfirmationTargets.PROJECT_MEMBER ); this.deletionDialogService.openComfirmDialog(deletionMessage); diff --git a/src/ui_ng/src/app/project/member/member.service.ts b/src/ui_ng/src/app/project/member/member.service.ts index 5578b1083..28cb0c895 100644 --- a/src/ui_ng/src/app/project/member/member.service.ts +++ b/src/ui_ng/src/app/project/member/member.service.ts @@ -6,22 +6,19 @@ import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/map'; import 'rxjs/add/observable/throw'; -import { BaseService } from '../../service/base.service'; import { Member } from './member'; @Injectable() -export class MemberService extends BaseService { +export class MemberService { - constructor(private http: Http) { - super(); - } + constructor(private http: Http) {} listMembers(projectId: number, username: string): Observable { console.log('Get member from project_id:' + projectId + ', username:' + username); return this.http .get(`/api/projects/${projectId}/members?username=${username}`) - .map(response=>response.json()) - .catch(error=>this.handleError(error)); + .map(response=>response.json() as Member[]) + .catch(error=>Observable.throw(error)); } addMember(projectId: number, username: string, roleId: number): Observable { diff --git a/src/ui_ng/src/app/project/project-detail/project-detail.component.html b/src/ui_ng/src/app/project/project-detail/project-detail.component.html index ccfd09356..b33359980 100644 --- a/src/ui_ng/src/app/project/project-detail/project-detail.component.html +++ b/src/ui_ng/src/app/project/project-detail/project-detail.component.html @@ -5,10 +5,10 @@ - -